2 e68cdf30 2002-12-30 alex * ngIRCd -- The Next Generation IRC Daemon
3 e68cdf30 2002-12-30 alex * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
5 e68cdf30 2002-12-30 alex * This program is free software; you can redistribute it and/or modify
6 e68cdf30 2002-12-30 alex * it under the terms of the GNU General Public License as published by
7 e68cdf30 2002-12-30 alex * the Free Software Foundation; either version 2 of the License, or
8 e68cdf30 2002-12-30 alex * (at your option) any later version.
9 e68cdf30 2002-12-30 alex * Please read the file COPYING, README and AUTHORS for more information.
11 e68cdf30 2002-12-30 alex * Connection compression using ZLIB
15 e68cdf30 2002-12-30 alex #include "portab.h"
17 b77dae34 2002-12-30 alex #define CONN_MODULE
22 7daa7fb2 2005-04-25 fw static char UNUSED id[] = "$Id: conn-zip.c,v 1.7 2005/04/25 18:37:16 fw Exp $";
24 e68cdf30 2002-12-30 alex #include "imp.h"
25 e68cdf30 2002-12-30 alex #include <assert.h>
26 e68cdf30 2002-12-30 alex #include <string.h>
27 e68cdf30 2002-12-30 alex #include <zlib.h>
29 e68cdf30 2002-12-30 alex #include "conn.h"
30 b77dae34 2002-12-30 alex #include "conn-func.h"
31 e68cdf30 2002-12-30 alex #include "log.h"
33 e68cdf30 2002-12-30 alex #include "exp.h"
34 e68cdf30 2002-12-30 alex #include "conn-zip.h"
38 e68cdf30 2002-12-30 alex Zip_InitConn( CONN_ID Idx )
40 e68cdf30 2002-12-30 alex /* Kompression fuer Link initialisieren */
42 e68cdf30 2002-12-30 alex assert( Idx > NONE );
44 e68cdf30 2002-12-30 alex My_Connections[Idx].zip.in.avail_in = 0;
45 e68cdf30 2002-12-30 alex My_Connections[Idx].zip.in.total_in = 0;
46 e68cdf30 2002-12-30 alex My_Connections[Idx].zip.in.total_out = 0;
47 e68cdf30 2002-12-30 alex My_Connections[Idx].zip.in.zalloc = NULL;
48 e68cdf30 2002-12-30 alex My_Connections[Idx].zip.in.zfree = NULL;
49 e68cdf30 2002-12-30 alex My_Connections[Idx].zip.in.data_type = Z_ASCII;
51 e68cdf30 2002-12-30 alex if( inflateInit( &My_Connections[Idx].zip.in ) != Z_OK )
53 e68cdf30 2002-12-30 alex /* Fehler! */
54 e68cdf30 2002-12-30 alex Log( LOG_ALERT, "Can't initialize compression on connection %d (zlib inflate)!", Idx );
58 e68cdf30 2002-12-30 alex My_Connections[Idx].zip.out.total_in = 0;
59 e68cdf30 2002-12-30 alex My_Connections[Idx].zip.out.total_in = 0;
60 e68cdf30 2002-12-30 alex My_Connections[Idx].zip.out.zalloc = NULL;
61 e68cdf30 2002-12-30 alex My_Connections[Idx].zip.out.zfree = NULL;
62 e68cdf30 2002-12-30 alex My_Connections[Idx].zip.out.data_type = Z_ASCII;
64 e68cdf30 2002-12-30 alex if( deflateInit( &My_Connections[Idx].zip.out, Z_DEFAULT_COMPRESSION ) != Z_OK )
66 e68cdf30 2002-12-30 alex /* Fehler! */
67 e68cdf30 2002-12-30 alex Log( LOG_ALERT, "Can't initialize compression on connection %d (zlib deflate)!", Idx );
71 e68cdf30 2002-12-30 alex My_Connections[Idx].zip.bytes_in = My_Connections[Idx].bytes_in;
72 e68cdf30 2002-12-30 alex My_Connections[Idx].zip.bytes_out = My_Connections[Idx].bytes_out;
74 e68cdf30 2002-12-30 alex Log( LOG_INFO, "Enabled link compression (zlib) on connection %d.", Idx );
75 7daa7fb2 2005-04-25 fw Conn_OPTION_ADD( &My_Connections[Idx], CONN_ZIP );
78 e68cdf30 2002-12-30 alex } /* Zip_InitConn */
82 8adff592 2005-03-19 fw Zip_Buffer( CONN_ID Idx, char *Data, int Len )
84 e68cdf30 2002-12-30 alex /* Daten zum Komprimieren im "Kompressions-Puffer" sammeln.
85 8adff592 2005-03-19 fw * Es wird true bei Erfolg, sonst false geliefert. */
87 e68cdf30 2002-12-30 alex assert( Idx > NONE );
88 e68cdf30 2002-12-30 alex assert( Data != NULL );
89 e68cdf30 2002-12-30 alex assert( Len > 0 );
91 e68cdf30 2002-12-30 alex /* Ist noch Platz im Kompressions-Puffer? */
92 e68cdf30 2002-12-30 alex if( ZWRITEBUFFER_LEN - My_Connections[Idx].zip.wdatalen < Len + 50 )
94 e68cdf30 2002-12-30 alex /* Nein! Puffer zunaechst leeren ...*/
95 8adff592 2005-03-19 fw if( ! Zip_Flush( Idx )) return false;
98 e68cdf30 2002-12-30 alex /* Daten kopieren */
99 e68cdf30 2002-12-30 alex memmove( My_Connections[Idx].zip.wbuf + My_Connections[Idx].zip.wdatalen, Data, Len );
100 e68cdf30 2002-12-30 alex My_Connections[Idx].zip.wdatalen += Len;
103 e68cdf30 2002-12-30 alex } /* Zip_Buffer */
107 e68cdf30 2002-12-30 alex Zip_Flush( CONN_ID Idx )
109 e68cdf30 2002-12-30 alex /* Daten komprimieren und in Schreibpuffer kopieren.
110 8adff592 2005-03-19 fw * Es wird true bei Erfolg, sonst false geliefert. */
112 8adff592 2005-03-19 fw int result, out_len;
113 e68cdf30 2002-12-30 alex z_stream *out;
115 e68cdf30 2002-12-30 alex out = &My_Connections[Idx].zip.out;
117 8adff592 2005-03-19 fw out->next_in = (void *)My_Connections[Idx].zip.wbuf;
118 e68cdf30 2002-12-30 alex out->avail_in = My_Connections[Idx].zip.wdatalen;
119 8adff592 2005-03-19 fw out->next_out = (void *)(My_Connections[Idx].wbuf + My_Connections[Idx].wdatalen);
120 e68cdf30 2002-12-30 alex out->avail_out = WRITEBUFFER_LEN - My_Connections[Idx].wdatalen;
122 e68cdf30 2002-12-30 alex result = deflate( out, Z_SYNC_FLUSH );
123 e68cdf30 2002-12-30 alex if(( result != Z_OK ) || ( out->avail_in > 0 ))
125 e68cdf30 2002-12-30 alex Log( LOG_ALERT, "Compression error: code %d!?", result );
126 8adff592 2005-03-19 fw Conn_Close( Idx, "Compression error!", NULL, false );
127 8adff592 2005-03-19 fw return false;
130 e68cdf30 2002-12-30 alex out_len = WRITEBUFFER_LEN - My_Connections[Idx].wdatalen - out->avail_out;
131 e68cdf30 2002-12-30 alex My_Connections[Idx].wdatalen += out_len;
132 e68cdf30 2002-12-30 alex My_Connections[Idx].bytes_out += out_len;
133 e68cdf30 2002-12-30 alex My_Connections[Idx].zip.bytes_out += My_Connections[Idx].zip.wdatalen;
134 e68cdf30 2002-12-30 alex My_Connections[Idx].zip.wdatalen = 0;
137 e68cdf30 2002-12-30 alex } /* Zip_Flush */
141 e68cdf30 2002-12-30 alex Unzip_Buffer( CONN_ID Idx )
143 e68cdf30 2002-12-30 alex /* Daten entpacken und in Lesepuffer kopieren. Bei Fehlern
144 8adff592 2005-03-19 fw * wird false geliefert, ansonsten true. Der Fall, dass keine
145 e68cdf30 2002-12-30 alex * Daten mehr zu entpacken sind, ist _kein_ Fehler! */
147 8adff592 2005-03-19 fw int result, in_len, out_len;
148 e68cdf30 2002-12-30 alex z_stream *in;
150 e68cdf30 2002-12-30 alex assert( Idx > NONE );
152 8adff592 2005-03-19 fw if( My_Connections[Idx].zip.rdatalen <= 0 ) return true;
154 e68cdf30 2002-12-30 alex in = &My_Connections[Idx].zip.in;
156 8adff592 2005-03-19 fw in->next_in = (void *)My_Connections[Idx].zip.rbuf;
157 e68cdf30 2002-12-30 alex in->avail_in = My_Connections[Idx].zip.rdatalen;
158 8adff592 2005-03-19 fw in->next_out = (void *)(My_Connections[Idx].rbuf + My_Connections[Idx].rdatalen);
159 e68cdf30 2002-12-30 alex in->avail_out = READBUFFER_LEN - My_Connections[Idx].rdatalen - 1;
161 e68cdf30 2002-12-30 alex result = inflate( in, Z_SYNC_FLUSH );
162 e68cdf30 2002-12-30 alex if( result != Z_OK )
164 292c7bd4 2004-04-25 alex Log( LOG_ALERT, "Decompression error: %s (code=%d, ni=%d, ai=%d, no=%d, ao=%d)!?", in->msg, result, in->next_in, in->avail_in, in->next_out, in->avail_out );
165 8adff592 2005-03-19 fw Conn_Close( Idx, "Decompression error!", NULL, false );
166 8adff592 2005-03-19 fw return false;
169 e68cdf30 2002-12-30 alex in_len = My_Connections[Idx].zip.rdatalen - in->avail_in;
170 e68cdf30 2002-12-30 alex out_len = READBUFFER_LEN - My_Connections[Idx].rdatalen - 1 - in->avail_out;
171 e68cdf30 2002-12-30 alex My_Connections[Idx].rdatalen += out_len;
173 e68cdf30 2002-12-30 alex if( in->avail_in > 0 )
175 e68cdf30 2002-12-30 alex /* es konnten nicht alle Daten entpackt werden, vermutlich war
176 e68cdf30 2002-12-30 alex * im Ziel-Puffer kein Platz mehr. Umkopieren ... */
177 e68cdf30 2002-12-30 alex My_Connections[Idx].zip.rdatalen -= in_len;
178 e68cdf30 2002-12-30 alex memmove( My_Connections[Idx].zip.rbuf, My_Connections[Idx].zip.rbuf + in_len, My_Connections[Idx].zip.rdatalen );
180 e68cdf30 2002-12-30 alex else My_Connections[Idx].zip.rdatalen = 0;
181 e68cdf30 2002-12-30 alex My_Connections[Idx].zip.bytes_in += out_len;
184 e68cdf30 2002-12-30 alex } /* Unzip_Buffer */
188 e68cdf30 2002-12-30 alex Zip_SendBytes( CONN_ID Idx )
190 e68cdf30 2002-12-30 alex /* Anzahl gesendeter Bytes (komprimiert!) liefern */
192 e68cdf30 2002-12-30 alex assert( Idx > NONE );
193 e68cdf30 2002-12-30 alex return My_Connections[Idx].zip.bytes_out;
194 e68cdf30 2002-12-30 alex } /* Zip_SendBytes */
198 e68cdf30 2002-12-30 alex Zip_RecvBytes( CONN_ID Idx )
200 e68cdf30 2002-12-30 alex /* Anzahl gesendeter Bytes (komprimiert!) liefern */
202 e68cdf30 2002-12-30 alex assert( Idx > NONE );
203 e68cdf30 2002-12-30 alex return My_Connections[Idx].zip.bytes_in;
204 e68cdf30 2002-12-30 alex } /* Zip_RecvBytes */
210 e68cdf30 2002-12-30 alex /* -eof- */