Blame


1 e68cdf30 2002-12-30 alex /*
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)
4 e68cdf30 2002-12-30 alex *
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.
10 e68cdf30 2002-12-30 alex *
11 e68cdf30 2002-12-30 alex * Connection compression using ZLIB
12 e68cdf30 2002-12-30 alex */
13 e68cdf30 2002-12-30 alex
14 e68cdf30 2002-12-30 alex
15 e68cdf30 2002-12-30 alex #include "portab.h"
16 e68cdf30 2002-12-30 alex
17 b77dae34 2002-12-30 alex #define CONN_MODULE
18 e68cdf30 2002-12-30 alex
19 e68cdf30 2002-12-30 alex
20 e68cdf30 2002-12-30 alex #ifdef USE_ZLIB
21 e68cdf30 2002-12-30 alex
22 b77dae34 2002-12-30 alex static char UNUSED id[] = "$Id: conn-zip.c,v 1.2 2002/12/30 17:15:06 alex Exp $";
23 e68cdf30 2002-12-30 alex
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>
28 e68cdf30 2002-12-30 alex
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"
32 e68cdf30 2002-12-30 alex
33 e68cdf30 2002-12-30 alex #include "exp.h"
34 e68cdf30 2002-12-30 alex #include "conn-zip.h"
35 e68cdf30 2002-12-30 alex
36 e68cdf30 2002-12-30 alex
37 e68cdf30 2002-12-30 alex GLOBAL BOOLEAN
38 e68cdf30 2002-12-30 alex Zip_InitConn( CONN_ID Idx )
39 e68cdf30 2002-12-30 alex {
40 e68cdf30 2002-12-30 alex /* Kompression fuer Link initialisieren */
41 e68cdf30 2002-12-30 alex
42 e68cdf30 2002-12-30 alex assert( Idx > NONE );
43 e68cdf30 2002-12-30 alex
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;
50 e68cdf30 2002-12-30 alex
51 e68cdf30 2002-12-30 alex if( inflateInit( &My_Connections[Idx].zip.in ) != Z_OK )
52 e68cdf30 2002-12-30 alex {
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 );
55 e68cdf30 2002-12-30 alex return FALSE;
56 e68cdf30 2002-12-30 alex }
57 e68cdf30 2002-12-30 alex
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;
63 e68cdf30 2002-12-30 alex
64 e68cdf30 2002-12-30 alex if( deflateInit( &My_Connections[Idx].zip.out, Z_DEFAULT_COMPRESSION ) != Z_OK )
65 e68cdf30 2002-12-30 alex {
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 );
68 e68cdf30 2002-12-30 alex return FALSE;
69 e68cdf30 2002-12-30 alex }
70 e68cdf30 2002-12-30 alex
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;
73 e68cdf30 2002-12-30 alex
74 e68cdf30 2002-12-30 alex Log( LOG_INFO, "Enabled link compression (zlib) on connection %d.", Idx );
75 e68cdf30 2002-12-30 alex Conn_SetOption( Idx, CONN_ZIP );
76 e68cdf30 2002-12-30 alex
77 e68cdf30 2002-12-30 alex return TRUE;
78 e68cdf30 2002-12-30 alex } /* Zip_InitConn */
79 e68cdf30 2002-12-30 alex
80 e68cdf30 2002-12-30 alex
81 e68cdf30 2002-12-30 alex GLOBAL BOOLEAN
82 e68cdf30 2002-12-30 alex Zip_Buffer( CONN_ID Idx, CHAR *Data, INT Len )
83 e68cdf30 2002-12-30 alex {
84 e68cdf30 2002-12-30 alex /* Daten zum Komprimieren im "Kompressions-Puffer" sammeln.
85 e68cdf30 2002-12-30 alex * Es wird TRUE bei Erfolg, sonst FALSE geliefert. */
86 e68cdf30 2002-12-30 alex
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 );
90 e68cdf30 2002-12-30 alex
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 )
93 e68cdf30 2002-12-30 alex {
94 e68cdf30 2002-12-30 alex /* Nein! Puffer zunaechst leeren ...*/
95 e68cdf30 2002-12-30 alex if( ! Zip_Flush( Idx )) return FALSE;
96 e68cdf30 2002-12-30 alex }
97 e68cdf30 2002-12-30 alex
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;
101 e68cdf30 2002-12-30 alex
102 e68cdf30 2002-12-30 alex return TRUE;
103 e68cdf30 2002-12-30 alex } /* Zip_Buffer */
104 e68cdf30 2002-12-30 alex
105 e68cdf30 2002-12-30 alex
106 e68cdf30 2002-12-30 alex GLOBAL BOOLEAN
107 e68cdf30 2002-12-30 alex Zip_Flush( CONN_ID Idx )
108 e68cdf30 2002-12-30 alex {
109 e68cdf30 2002-12-30 alex /* Daten komprimieren und in Schreibpuffer kopieren.
110 e68cdf30 2002-12-30 alex * Es wird TRUE bei Erfolg, sonst FALSE geliefert. */
111 e68cdf30 2002-12-30 alex
112 e68cdf30 2002-12-30 alex INT result, out_len;
113 e68cdf30 2002-12-30 alex z_stream *out;
114 e68cdf30 2002-12-30 alex
115 e68cdf30 2002-12-30 alex out = &My_Connections[Idx].zip.out;
116 e68cdf30 2002-12-30 alex
117 e68cdf30 2002-12-30 alex out->next_in = My_Connections[Idx].zip.wbuf;
118 e68cdf30 2002-12-30 alex out->avail_in = My_Connections[Idx].zip.wdatalen;
119 e68cdf30 2002-12-30 alex out->next_out = My_Connections[Idx].wbuf + My_Connections[Idx].wdatalen;
120 e68cdf30 2002-12-30 alex out->avail_out = WRITEBUFFER_LEN - My_Connections[Idx].wdatalen;
121 e68cdf30 2002-12-30 alex
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 ))
124 e68cdf30 2002-12-30 alex {
125 e68cdf30 2002-12-30 alex Log( LOG_ALERT, "Compression error: code %d!?", result );
126 e68cdf30 2002-12-30 alex Conn_Close( Idx, "Compression error!", NULL, FALSE );
127 e68cdf30 2002-12-30 alex return FALSE;
128 e68cdf30 2002-12-30 alex }
129 e68cdf30 2002-12-30 alex
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;
135 e68cdf30 2002-12-30 alex
136 e68cdf30 2002-12-30 alex return TRUE;
137 e68cdf30 2002-12-30 alex } /* Zip_Flush */
138 e68cdf30 2002-12-30 alex
139 e68cdf30 2002-12-30 alex
140 e68cdf30 2002-12-30 alex GLOBAL BOOLEAN
141 e68cdf30 2002-12-30 alex Unzip_Buffer( CONN_ID Idx )
142 e68cdf30 2002-12-30 alex {
143 e68cdf30 2002-12-30 alex /* Daten entpacken und in Lesepuffer kopieren. Bei Fehlern
144 e68cdf30 2002-12-30 alex * wird FALSE geliefert, ansonsten TRUE. Der Fall, dass keine
145 e68cdf30 2002-12-30 alex * Daten mehr zu entpacken sind, ist _kein_ Fehler! */
146 e68cdf30 2002-12-30 alex
147 e68cdf30 2002-12-30 alex INT result, in_len, out_len;
148 e68cdf30 2002-12-30 alex z_stream *in;
149 e68cdf30 2002-12-30 alex
150 e68cdf30 2002-12-30 alex assert( Idx > NONE );
151 e68cdf30 2002-12-30 alex
152 e68cdf30 2002-12-30 alex if( My_Connections[Idx].zip.rdatalen <= 0 ) return TRUE;
153 e68cdf30 2002-12-30 alex
154 e68cdf30 2002-12-30 alex in = &My_Connections[Idx].zip.in;
155 e68cdf30 2002-12-30 alex
156 e68cdf30 2002-12-30 alex in->next_in = My_Connections[Idx].zip.rbuf;
157 e68cdf30 2002-12-30 alex in->avail_in = My_Connections[Idx].zip.rdatalen;
158 e68cdf30 2002-12-30 alex in->next_out = My_Connections[Idx].rbuf + My_Connections[Idx].rdatalen;
159 e68cdf30 2002-12-30 alex in->avail_out = READBUFFER_LEN - My_Connections[Idx].rdatalen - 1;
160 e68cdf30 2002-12-30 alex
161 e68cdf30 2002-12-30 alex result = inflate( in, Z_SYNC_FLUSH );
162 e68cdf30 2002-12-30 alex if( result != Z_OK )
163 e68cdf30 2002-12-30 alex {
164 e68cdf30 2002-12-30 alex Log( LOG_ALERT, "Decompression error: code %d (ni=%d, ai=%d, no=%d, ao=%d)!?", result, in->next_in, in->avail_in, in->next_out, in->avail_out );
165 e68cdf30 2002-12-30 alex Conn_Close( Idx, "Decompression error!", NULL, FALSE );
166 e68cdf30 2002-12-30 alex return FALSE;
167 e68cdf30 2002-12-30 alex }
168 e68cdf30 2002-12-30 alex
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;
172 e68cdf30 2002-12-30 alex
173 e68cdf30 2002-12-30 alex if( in->avail_in > 0 )
174 e68cdf30 2002-12-30 alex {
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 );
179 e68cdf30 2002-12-30 alex }
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;
182 e68cdf30 2002-12-30 alex
183 e68cdf30 2002-12-30 alex return TRUE;
184 e68cdf30 2002-12-30 alex } /* Unzip_Buffer */
185 e68cdf30 2002-12-30 alex
186 e68cdf30 2002-12-30 alex
187 e68cdf30 2002-12-30 alex GLOBAL LONG
188 e68cdf30 2002-12-30 alex Zip_SendBytes( CONN_ID Idx )
189 e68cdf30 2002-12-30 alex {
190 e68cdf30 2002-12-30 alex /* Anzahl gesendeter Bytes (komprimiert!) liefern */
191 e68cdf30 2002-12-30 alex
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 */
195 e68cdf30 2002-12-30 alex
196 e68cdf30 2002-12-30 alex
197 e68cdf30 2002-12-30 alex GLOBAL LONG
198 e68cdf30 2002-12-30 alex Zip_RecvBytes( CONN_ID Idx )
199 e68cdf30 2002-12-30 alex {
200 e68cdf30 2002-12-30 alex /* Anzahl gesendeter Bytes (komprimiert!) liefern */
201 e68cdf30 2002-12-30 alex
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 */
205 e68cdf30 2002-12-30 alex
206 e68cdf30 2002-12-30 alex
207 e68cdf30 2002-12-30 alex #endif
208 e68cdf30 2002-12-30 alex
209 e68cdf30 2002-12-30 alex
210 e68cdf30 2002-12-30 alex /* -eof- */