X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Fconn.c;h=16e2685596da2fdfd1a9dc1c2c0b9083aa43b841;hp=194c181b8e7c550ef137db3c0ca6dd956b7ac3a5;hb=af719e60c5e277ac006d3e3e19ef308f94c61b71;hpb=d58431a097cb5600b85bb23cb86b4a8002de9539 diff --git a/src/ngircd/conn.c b/src/ngircd/conn.c index 194c181b..16e26855 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.69 2002/09/02 19:03:09 alex Exp $ + * $Id: conn.c,v 1.79 2002/10/09 17:02:49 alex Exp $ * * connect.h: Verwaltung aller Netz-Verbindungen ("connections") */ @@ -75,6 +75,7 @@ typedef struct _Connection time_t lastping; /* Letzter PING */ time_t lastprivmsg; /* Letzte PRIVMSG */ time_t delaytime; /* Nicht beachten bis ("penalty") */ + LONG bytes_in, bytes_out; /* Counter fuer Statistik */ } CONNECTION; @@ -220,8 +221,10 @@ Conn_NewListener( CONST UINT Port ) GLOBAL VOID Conn_Handler( VOID ) { - /* Aktive Verbindungen ueberwachen. Folgende Aktionen - * werden durchgefuehrt: + /* "Hauptschleife": Aktive Verbindungen ueberwachen. Folgende Aktionen + * werden dabei durchgefuehrt, bis der Server terminieren oder neu + * starten soll: + * * - neue Verbindungen annehmen, * - Server-Verbindungen aufbauen, * - geschlossene Verbindungen loeschen, @@ -242,10 +245,6 @@ Conn_Handler( VOID ) Check_Connections( ); - /* Timeout initialisieren */ - tv.tv_sec = 1; - tv.tv_usec = 0; - /* noch volle Lese-Buffer suchen */ for( i = 0; i < MAX_CONNECTIONS; i++ ) { @@ -291,6 +290,7 @@ Conn_Handler( VOID ) { /* Fuer die Verbindung ist eine "Penalty-Zeit" gesetzt */ FD_CLR( My_Connections[i].sock, &read_sockets ); + FD_CLR( My_Connections[i].sock, &write_sockets ); } } for( i = 0; i < Conn_MaxFD + 1; i++ ) @@ -302,9 +302,20 @@ Conn_Handler( VOID ) } } + /* Timeout initialisieren */ + tv.tv_sec = 1; + tv.tv_usec = 0; + /* Auf Aktivitaet warten */ - if( select( Conn_MaxFD + 1, &read_sockets, &write_sockets, NULL, &tv ) == -1 ) + i = select( Conn_MaxFD + 1, &read_sockets, &write_sockets, NULL, &tv ); + if( i == 0 ) { + /* keine Veraenderung an den Sockets */ + continue; + } + if( i == -1 ) + { + /* Fehler (z.B. Interrupt) */ if( errno != EINTR ) { Log( LOG_EMERG, "select(): %s!", strerror( errno )); @@ -349,7 +360,6 @@ va_dcl va_list ap; assert( Idx >= 0 ); - assert( My_Connections[Idx].sock > NONE ); assert( Format != NULL ); #ifdef PROTOTYPES @@ -383,10 +393,20 @@ Conn_Write( CONN_ID Idx, CHAR *Data, INT Len ) * der Client disconnectiert und FALSE geliefert. */ assert( Idx >= 0 ); - assert( My_Connections[Idx].sock > NONE ); assert( Data != NULL ); assert( Len > 0 ); + /* Ist der entsprechende Socket ueberhaupt noch offen? + * In einem "Handler-Durchlauf" kann es passieren, dass + * dem nicht mehr so ist, wenn einer von mehreren + * Conn_Write()'s fehlgeschlagen ist. In diesem Fall + * wird hier einfach ein Fehler geliefert. */ + if( My_Connections[Idx].sock <= NONE ) + { + Log( LOG_DEBUG, "Skipped write on closed socket (connection %d).", Idx ); + return FALSE; + } + /* pruefen, ob Daten im Schreibpuffer sind. Wenn ja, zunaechst * pruefen, ob diese gesendet werden koennen */ if( My_Connections[Idx].wdatalen > 0 ) @@ -428,8 +448,17 @@ Conn_Close( CONN_ID Idx, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN InformClient ) assert( Idx >= 0 ); assert( My_Connections[Idx].sock > NONE ); + c = Client_GetFromConn( Idx ); + if( InformClient ) { + /* Statistik an Client melden, wenn User */ + if(( c != NULL ) && ( Client_Type( c ) == CLIENT_USER )) + { + Conn_WriteStr( Idx, "NOTICE %s :%sConnection statistics: %.1f kb received, %.1f kb sent.", Client_ThisServer( ), NOTICE_TXTPREFIX, (DOUBLE)My_Connections[Idx].bytes_in / 1024, (DOUBLE)My_Connections[Idx].bytes_out / 1024 ); + } + + /* ERROR an Client schicken (von RFC so vorgesehen!) */ if( FwdMsg ) Conn_WriteStr( Idx, "ERROR :%s", FwdMsg ); else Conn_WriteStr( Idx, "ERROR :Closing connection." ); if( My_Connections[Idx].sock == NONE ) return; @@ -444,7 +473,6 @@ Conn_Close( CONN_ID Idx, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN InformClient ) Log( LOG_INFO, "Connection %d with %s:%d closed.", Idx, inet_ntoa( My_Connections[Idx].addr.sin_addr ), ntohs( My_Connections[Idx].addr.sin_port )); } - c = Client_GetFromConn( Idx ); if( c ) Client_Destroy( c, LogMsg, FwdMsg, TRUE ); if( My_Connections[Idx].res_stat ) @@ -644,6 +672,9 @@ Handle_Write( CONN_ID Idx ) return FALSE; } + /* Connection-Statistik aktualisieren */ + My_Connections[Idx].bytes_out += len; + /* Puffer anpassen */ My_Connections[Idx].wdatalen -= len; memmove( My_Connections[Idx].wbuf, My_Connections[Idx].wbuf + len, My_Connections[Idx].wdatalen ); @@ -708,6 +739,7 @@ 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; } else @@ -775,6 +807,9 @@ Read_Request( CONN_ID Idx ) return; } + /* Connection-Statistik aktualisieren */ + My_Connections[Idx].bytes_in += len; + /* Lesebuffer updaten */ My_Connections[Idx].rdatalen += len; assert( My_Connections[Idx].rdatalen < READBUFFER_LEN ); @@ -1073,6 +1108,8 @@ Init_Conn_Struct( INT Idx ) My_Connections[Idx].lastping = 0; My_Connections[Idx].lastprivmsg = time( NULL ); My_Connections[Idx].delaytime = 0; + My_Connections[Idx].bytes_in = 0; + My_Connections[Idx].bytes_out = 0; } /* Init_Conn_Struct */ @@ -1114,7 +1151,7 @@ Read_Resolver_Result( INT r_fd ) FD_CLR( r_fd, &Resolver_FDs ); /* Anfrage vom Parent lesen */ - len = read( r_fd, result, HOST_LEN); + len = read( r_fd, result, HOST_LEN - 1 ); if( len < 0 ) { /* Fehler beim Lesen aus der Pipe */ @@ -1151,6 +1188,8 @@ 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 {