X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Fconn.c;h=22fbaaee235aeb91367846c18d32edfa7e07fed6;hp=a9873e4fc87b25b0e29e992fa9d1a2057b1053e1;hb=a1437f1ad040dfc1c196ec01430d9ad35da81f97;hpb=65f3adca21aa7066bea2e8842e533aa0e25583f4 diff --git a/src/ngircd/conn.c b/src/ngircd/conn.c index a9873e4f..22fbaaee 100644 --- a/src/ngircd/conn.c +++ b/src/ngircd/conn.c @@ -9,7 +9,7 @@ * Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste * der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS. * - * $Id: conn.c,v 1.96 2002/11/26 23:07:24 alex Exp $ + * $Id: conn.c,v 1.100 2002/11/29 17:36:50 alex Exp $ * * connect.h: Verwaltung aller Netz-Verbindungen ("connections") */ @@ -570,11 +570,13 @@ Conn_Close( CONN_ID Idx, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN InformClient ) if( InformClient ) { +#ifndef STRICT_RFC /* Statistik an Client melden, wenn User */ if(( c != NULL ) && ( Client_Type( c ) == CLIENT_USER )) { Conn_WriteStr( Idx, "NOTICE %s :%sConnection statistics: client %.1f kb, server %.1f kb.", Client_ThisServer( ), NOTICE_TXTPREFIX, (DOUBLE)My_Connections[Idx].bytes_in / 1024, (DOUBLE)My_Connections[Idx].bytes_out / 1024 ); } +#endif /* ERROR an Client schicken (von RFC so vorgesehen!) */ if( FwdMsg ) Conn_WriteStr( Idx, "ERROR :%s", FwdMsg ); @@ -582,6 +584,10 @@ Conn_Close( CONN_ID Idx, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN InformClient ) if( My_Connections[Idx].sock == NONE ) return; } + /* zunaechst versuchen, noch im Schreibpuffer vorhandene + * Daten auf den Socket zu schreiben ... */ + Try_Write( Idx ); + if( close( My_Connections[Idx].sock ) != 0 ) { Log( LOG_ERR, "Error closing connection %d (socket %d) with %s:%d - %s!", Idx, My_Connections[Idx].sock, My_Connections[Idx].host, ntohs( My_Connections[Idx].addr.sin_port), strerror( errno )); @@ -864,15 +870,24 @@ Conn_InitZip( CONN_ID Idx ) LOCAL BOOLEAN Try_Write( CONN_ID Idx ) { - /* Versuchen, Daten aus dem Schreib-Puffer in den - * Socket zu schreiben. */ + /* Versuchen, Daten aus dem Schreib-Puffer in den Socket zu + * schreiben. TRUE wird geliefert, wenn entweder keine Daten + * zum Versenden vorhanden sind oder erfolgreich bearbeitet + * werden konnten. Im Fehlerfall wird FALSE geliefert und + * die Verbindung geschlossen. */ fd_set write_socket; struct timeval tv; assert( Idx > NONE ); assert( My_Connections[Idx].sock > NONE ); - assert( My_Connections[Idx].wdatalen > 0 ); + + /* sind ueberhaupt Daten vorhanden? */ +#ifdef USE_ZLIB + if(( ! My_Connections[Idx].wdatalen > 0 ) && ( ! My_Connections[Idx].zip.wdatalen )) return TRUE; +#else + if( ! My_Connections[Idx].wdatalen > 0 ) return TRUE; +#endif /* Timeout initialisieren: 0 Sekunden, also nicht blockieren */ tv.tv_sec = 0; tv.tv_usec = 0; @@ -1109,7 +1124,6 @@ New_Connection( INT Sock ) if( s ) { /* Sub-Prozess wurde asyncron gestartet */ - Conn_WriteStr( idx, "NOTICE AUTH :%sLooking up your hostname ...", NOTICE_TXTPREFIX ); My_Connections[idx].res_stat = s; } @@ -1146,15 +1160,26 @@ Read_Request( CONN_ID Idx ) /* Daten von Socket einlesen und entsprechend behandeln. * Tritt ein Fehler auf, so wird der Socket geschlossen. */ - INT len; + INT len, bsize; +#ifdef USE_ZLIB + CLIENT *c; +#endif assert( Idx > NONE ); assert( My_Connections[Idx].sock > NONE ); + /* wenn noch nicht registriert: maximal mit ZREADBUFFER_LEN arbeiten, + * ansonsten koennen Daten ggf. nicht umkopiert werden. */ + bsize = READBUFFER_LEN; +#ifdef USE_ZLIB + c = Client_GetFromConn( Idx ); + if(( Client_Type( c ) != CLIENT_USER ) && ( Client_Type( c ) != CLIENT_SERVER ) && ( Client_Type( c ) != CLIENT_SERVICE ) && ( bsize > ZREADBUFFER_LEN )) bsize = ZREADBUFFER_LEN; +#endif + #ifdef USE_ZLIB - if(( READBUFFER_LEN - My_Connections[Idx].rdatalen - 1 < 1 ) || ( ZREADBUFFER_LEN - My_Connections[Idx].zip.rdatalen < 1 )) + if(( bsize - My_Connections[Idx].rdatalen - 1 < 1 ) || ( ZREADBUFFER_LEN - My_Connections[Idx].zip.rdatalen < 1 )) #else - if( READBUFFER_LEN - My_Connections[Idx].rdatalen - 1 < 1 ) + if( bsize - My_Connections[Idx].rdatalen - 1 < 1 ) #endif { /* Der Lesepuffer ist voll */ @@ -1172,7 +1197,7 @@ Read_Request( CONN_ID Idx ) else #endif { - len = recv( My_Connections[Idx].sock, My_Connections[Idx].rbuf + My_Connections[Idx].rdatalen, READBUFFER_LEN - My_Connections[Idx].rdatalen - 1, 0 ); + len = recv( My_Connections[Idx].sock, My_Connections[Idx].rbuf + My_Connections[Idx].rdatalen, bsize - My_Connections[Idx].rdatalen - 1, 0 ); if( len > 0 ) My_Connections[Idx].rdatalen += len; } @@ -1218,6 +1243,9 @@ Handle_Buffer( CONN_ID Idx ) CHAR *ptr; INT len, delta; BOOLEAN action, result; +#ifdef USE_ZLIB + BOOLEAN old_z; +#endif result = FALSE; do @@ -1267,17 +1295,43 @@ Handle_Buffer( CONN_ID Idx ) Conn_Close( Idx, NULL, "Request too long", TRUE ); return FALSE; } - + +#ifdef USE_ZLIB + /* merken, ob Stream bereits komprimiert wird */ + old_z = My_Connections[Idx].options & CONN_ZIP; +#endif + if( len > delta ) { /* Es wurde ein Request gelesen */ if( ! Parse_Request( Idx, My_Connections[Idx].rbuf )) return FALSE; else action = TRUE; } - + /* Puffer anpassen */ My_Connections[Idx].rdatalen -= len; memmove( My_Connections[Idx].rbuf, My_Connections[Idx].rbuf + len, My_Connections[Idx].rdatalen ); + +#ifdef USE_ZLIB + if(( ! old_z ) && ( My_Connections[Idx].options & CONN_ZIP ) && ( My_Connections[Idx].rdatalen > 0 )) + { + /* Mit dem letzten Befehl wurde Socket-Kompression aktiviert. + * Evtl. schon vom Socket gelesene Daten in den Unzip-Puffer + * umkopieren, damit diese nun zunaechst entkomprimiert werden */ + { + if( My_Connections[Idx].rdatalen > ZREADBUFFER_LEN ) + { + /* Hupsa! Soviel Platz haben wir aber gar nicht! */ + Log( LOG_ALERT, "Can't move read buffer: No space left in unzip buffer (need %d bytes)!", My_Connections[Idx].rdatalen ); + return FALSE; + } + memcpy( My_Connections[Idx].zip.rbuf, My_Connections[Idx].rbuf, My_Connections[Idx].rdatalen ); + My_Connections[Idx].zip.rdatalen = My_Connections[Idx].rdatalen; + My_Connections[Idx].rdatalen = 0; + Log( LOG_DEBUG, "Moved already received data (%d bytes) to uncompression buffer.", My_Connections[Idx].zip.rdatalen ); + } + } +#endif } if( action ) result = TRUE; @@ -1610,8 +1664,6 @@ Read_Resolver_Result( INT r_fd ) assert( c != NULL ); strcpy( My_Connections[i].host, result ); Client_SetHostname( c, result ); - - Conn_WriteStr( i, "NOTICE AUTH :%sGot your hostname.", NOTICE_TXTPREFIX ); } else { @@ -1710,7 +1762,7 @@ Unzip_Buffer( CONN_ID Idx ) result = inflate( in, Z_SYNC_FLUSH ); if( result != Z_OK ) { - Log( LOG_ALERT, "Decompression error: code %d!?", result ); + 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 ); Conn_Close( Idx, "Decompression error!", NULL, FALSE ); return FALSE; }