123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- /*
- * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * Please read the file COPYING, README and AUTHORS for more information.
- *
- * Connection compression using ZLIB
- */
- #include "portab.h"
- #define CONN_MODULE
- #ifdef ZLIB
- static char UNUSED id[] = "$Id: conn-zip.c,v 1.7 2005/04/25 18:37:16 fw Exp $";
- #include "imp.h"
- #include <assert.h>
- #include <string.h>
- #include <zlib.h>
- #include "conn.h"
- #include "conn-func.h"
- #include "log.h"
- #include "exp.h"
- #include "conn-zip.h"
- GLOBAL bool
- Zip_InitConn( CONN_ID Idx )
- {
- /* Kompression fuer Link initialisieren */
- assert( Idx > NONE );
- My_Connections[Idx].zip.in.avail_in = 0;
- My_Connections[Idx].zip.in.total_in = 0;
- My_Connections[Idx].zip.in.total_out = 0;
- My_Connections[Idx].zip.in.zalloc = NULL;
- My_Connections[Idx].zip.in.zfree = NULL;
- My_Connections[Idx].zip.in.data_type = Z_ASCII;
- if( inflateInit( &My_Connections[Idx].zip.in ) != Z_OK )
- {
- /* Fehler! */
- Log( LOG_ALERT, "Can't initialize compression on connection %d (zlib inflate)!", Idx );
- return false;
- }
- My_Connections[Idx].zip.out.total_in = 0;
- My_Connections[Idx].zip.out.total_in = 0;
- My_Connections[Idx].zip.out.zalloc = NULL;
- My_Connections[Idx].zip.out.zfree = NULL;
- My_Connections[Idx].zip.out.data_type = Z_ASCII;
- if( deflateInit( &My_Connections[Idx].zip.out, Z_DEFAULT_COMPRESSION ) != Z_OK )
- {
- /* Fehler! */
- Log( LOG_ALERT, "Can't initialize compression on connection %d (zlib deflate)!", Idx );
- return false;
- }
- My_Connections[Idx].zip.bytes_in = My_Connections[Idx].bytes_in;
- My_Connections[Idx].zip.bytes_out = My_Connections[Idx].bytes_out;
- Log( LOG_INFO, "Enabled link compression (zlib) on connection %d.", Idx );
- Conn_OPTION_ADD( &My_Connections[Idx], CONN_ZIP );
- return true;
- } /* Zip_InitConn */
- GLOBAL bool
- Zip_Buffer( CONN_ID Idx, char *Data, int Len )
- {
- /* Daten zum Komprimieren im "Kompressions-Puffer" sammeln.
- * Es wird true bei Erfolg, sonst false geliefert. */
- assert( Idx > NONE );
- assert( Data != NULL );
- assert( Len > 0 );
- /* Ist noch Platz im Kompressions-Puffer? */
- if( ZWRITEBUFFER_LEN - My_Connections[Idx].zip.wdatalen < Len + 50 )
- {
- /* Nein! Puffer zunaechst leeren ...*/
- if( ! Zip_Flush( Idx )) return false;
- }
- /* Daten kopieren */
- memmove( My_Connections[Idx].zip.wbuf + My_Connections[Idx].zip.wdatalen, Data, Len );
- My_Connections[Idx].zip.wdatalen += Len;
- return true;
- } /* Zip_Buffer */
- GLOBAL bool
- Zip_Flush( CONN_ID Idx )
- {
- /* Daten komprimieren und in Schreibpuffer kopieren.
- * Es wird true bei Erfolg, sonst false geliefert. */
- int result, out_len;
- z_stream *out;
- out = &My_Connections[Idx].zip.out;
- out->next_in = (void *)My_Connections[Idx].zip.wbuf;
- out->avail_in = My_Connections[Idx].zip.wdatalen;
- out->next_out = (void *)(My_Connections[Idx].wbuf + My_Connections[Idx].wdatalen);
- out->avail_out = WRITEBUFFER_LEN - My_Connections[Idx].wdatalen;
- result = deflate( out, Z_SYNC_FLUSH );
- if(( result != Z_OK ) || ( out->avail_in > 0 ))
- {
- Log( LOG_ALERT, "Compression error: code %d!?", result );
- Conn_Close( Idx, "Compression error!", NULL, false );
- return false;
- }
- out_len = WRITEBUFFER_LEN - My_Connections[Idx].wdatalen - out->avail_out;
- My_Connections[Idx].wdatalen += out_len;
- My_Connections[Idx].bytes_out += out_len;
- My_Connections[Idx].zip.bytes_out += My_Connections[Idx].zip.wdatalen;
- My_Connections[Idx].zip.wdatalen = 0;
- return true;
- } /* Zip_Flush */
- GLOBAL bool
- Unzip_Buffer( CONN_ID Idx )
- {
- /* Daten entpacken und in Lesepuffer kopieren. Bei Fehlern
- * wird false geliefert, ansonsten true. Der Fall, dass keine
- * Daten mehr zu entpacken sind, ist _kein_ Fehler! */
- int result, in_len, out_len;
- z_stream *in;
- assert( Idx > NONE );
- if( My_Connections[Idx].zip.rdatalen <= 0 ) return true;
- in = &My_Connections[Idx].zip.in;
- in->next_in = (void *)My_Connections[Idx].zip.rbuf;
- in->avail_in = My_Connections[Idx].zip.rdatalen;
- in->next_out = (void *)(My_Connections[Idx].rbuf + My_Connections[Idx].rdatalen);
- in->avail_out = READBUFFER_LEN - My_Connections[Idx].rdatalen - 1;
- result = inflate( in, Z_SYNC_FLUSH );
- if( result != Z_OK )
- {
- 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 );
- Conn_Close( Idx, "Decompression error!", NULL, false );
- return false;
- }
- in_len = My_Connections[Idx].zip.rdatalen - in->avail_in;
- out_len = READBUFFER_LEN - My_Connections[Idx].rdatalen - 1 - in->avail_out;
- My_Connections[Idx].rdatalen += out_len;
- if( in->avail_in > 0 )
- {
- /* es konnten nicht alle Daten entpackt werden, vermutlich war
- * im Ziel-Puffer kein Platz mehr. Umkopieren ... */
- My_Connections[Idx].zip.rdatalen -= in_len;
- memmove( My_Connections[Idx].zip.rbuf, My_Connections[Idx].zip.rbuf + in_len, My_Connections[Idx].zip.rdatalen );
- }
- else My_Connections[Idx].zip.rdatalen = 0;
- My_Connections[Idx].zip.bytes_in += out_len;
- return true;
- } /* Unzip_Buffer */
- GLOBAL long
- Zip_SendBytes( CONN_ID Idx )
- {
- /* Anzahl gesendeter Bytes (komprimiert!) liefern */
- assert( Idx > NONE );
- return My_Connections[Idx].zip.bytes_out;
- } /* Zip_SendBytes */
- GLOBAL long
- Zip_RecvBytes( CONN_ID Idx )
- {
- /* Anzahl gesendeter Bytes (komprimiert!) liefern */
- assert( Idx > NONE );
- return My_Connections[Idx].zip.bytes_in;
- } /* Zip_RecvBytes */
- #endif
- /* -eof- */
|