From: Alexander Barton Date: Mon, 14 Oct 2002 22:21:00 +0000 (+0000) Subject: - Segfault unter hoher Netzaktivitaet behoben: in Conn_Close() wird die X-Git-Tag: rel-0-6-0-pre1~163 X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=commitdiff_plain;h=3cf845fbfb0d4f8063d127afab51876b8627a537 - Segfault unter hoher Netzaktivitaet behoben: in Conn_Close() wird die Connection-Struktur nun frueher als "ungueltig" markiert. - besseres Error-Logging. --- diff --git a/src/ngircd/conn.c b/src/ngircd/conn.c index c5b935f2..095c0466 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.81 2002/10/10 15:01:12 alex Exp $ + * $Id: conn.c,v 1.82 2002/10/14 22:21:00 alex Exp $ * * connect.h: Verwaltung aller Netz-Verbindungen ("connections") */ @@ -236,7 +236,7 @@ Conn_Handler( VOID ) fd_set read_sockets, write_sockets; struct timeval tv; time_t start, t; - INT i; + INT i, idx; start = time( NULL ); while(( ! NGIRCd_Quit ) && ( ! NGIRCd_Restart )) @@ -318,7 +318,7 @@ Conn_Handler( VOID ) /* Fehler (z.B. Interrupt) */ if( errno != EINTR ) { - Log( LOG_EMERG, "select(): %s!", strerror( errno )); + Log( LOG_EMERG, "Conn_Handler: select(): %s!", strerror( errno )); Log( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE ); exit( 1 ); } @@ -328,7 +328,18 @@ Conn_Handler( VOID ) /* Koennen Daten geschrieben werden? */ for( i = 0; i < Conn_MaxFD + 1; i++ ) { - if( FD_ISSET( i, &write_sockets )) Handle_Write( Socket2Index( i )); + if( ! FD_ISSET( i, &write_sockets )) continue; + + /* Es kann geschrieben werden ... */ + idx = Socket2Index( i ); + if( ! idx ) continue; + + if( ! Handle_Write( idx )) + { + /* Fehler beim Schreiben! Diesen Socket nun + * auch aus dem Read-Set entfernen: */ + FD_CLR( i, &read_sockets ); + } } /* Daten zum Lesen vorhanden? */ @@ -466,12 +477,17 @@ Conn_Close( CONN_ID Idx, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN InformClient ) if( close( My_Connections[Idx].sock ) != 0 ) { - Log( LOG_ERR, "Error closing connection %d with %s:%d - %s!", Idx, inet_ntoa( My_Connections[Idx].addr.sin_addr ), ntohs( My_Connections[Idx].addr.sin_port), strerror( errno )); + Log( LOG_ERR, "Error closing connection %d (socket %d) with %s:%d - %s!", Idx, My_Connections[Idx].sock, inet_ntoa( My_Connections[Idx].addr.sin_addr ), ntohs( My_Connections[Idx].addr.sin_port), strerror( errno )); } else { - 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 )); + Log( LOG_INFO, "Connection %d (socket %d) with %s:%d closed.", Idx, My_Connections[Idx].sock, inet_ntoa( My_Connections[Idx].addr.sin_addr ), ntohs( My_Connections[Idx].addr.sin_port )); } + + /* Socket als "ungueltig" markieren */ + FD_CLR( My_Connections[Idx].sock, &My_Sockets ); + FD_CLR( My_Connections[Idx].sock, &My_Connects ); + My_Connections[Idx].sock = NONE; if( c ) Client_Destroy( c, LogMsg, FwdMsg, TRUE ); @@ -494,9 +510,8 @@ Conn_Close( CONN_ID Idx, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN InformClient ) Conf_Server[My_Connections[Idx].our_server].lasttry = time( NULL ) - Conf_ConnectRetry + RECONNECT_DELAY; } - FD_CLR( My_Connections[Idx].sock, &My_Sockets ); - FD_CLR( My_Connections[Idx].sock, &My_Connects ); - My_Connections[Idx].sock = NONE; + /* Connection-Struktur loeschen (=freigeben) */ + Init_Conn_Struct( Idx ); } /* Conn_Close */ @@ -575,7 +590,7 @@ Try_Write( CONN_ID Idx ) /* Fehler! */ if( errno != EINTR ) { - Log( LOG_ALERT, "select() failed: %s!", strerror( errno )); + Log( LOG_ALERT, "Try_Write: select() failed: %s (con=%d, sock=%d)!", strerror( errno ), Idx, My_Connections[Idx].sock ); Conn_Close( Idx, "Server error!", NULL, FALSE ); return FALSE; } @@ -616,7 +631,8 @@ Handle_Read( INT Sock ) /* Ein Client Socket: entweder ein User oder Server */ idx = Socket2Index( Sock ); - Read_Request( idx ); + if( idx > NONE ) Read_Request( idx ); + else Log( LOG_DEBUG, "Handle_Read: can't get connection for socket %d!", Sock ); } } /* Handle_Read */ @@ -628,7 +644,7 @@ Handle_Write( CONN_ID Idx ) INT len, res, err; - assert( Idx >= 0 ); + assert( Idx >= NONE ); assert( My_Connections[Idx].sock > NONE ); if( FD_ISSET( My_Connections[Idx].sock, &My_Connects )) @@ -664,9 +680,7 @@ Handle_Write( CONN_ID Idx ) /* PASS und SERVER verschicken */ Conn_WriteStr( Idx, "PASS %s %s", Conf_Server[My_Connections[Idx].our_server].pwd, NGIRCd_ProtoID ); - Conn_WriteStr( Idx, "SERVER %s :%s", Conf_ServerName, Conf_ServerInfo ); - - return TRUE; + return Conn_WriteStr( Idx, "SERVER %s :%s", Conf_ServerName, Conf_ServerInfo ); } assert( My_Connections[Idx].wdatalen > 0 ); @@ -676,8 +690,8 @@ Handle_Write( CONN_ID Idx ) if( len < 0 ) { /* Oops, ein Fehler! */ - Log( LOG_ERR, "Write error (buffer) on connection %d: %s!", Idx, strerror( errno )); - Conn_Close( Idx, "Write error (buffer)!", NULL, FALSE ); + Log( LOG_ERR, "Write error on connection %d (socket %d): %s!", Idx, My_Connections[Idx].sock, strerror( errno )); + Conn_Close( Idx, "Write error!", NULL, FALSE ); return FALSE; } @@ -714,7 +728,7 @@ New_Connection( INT Sock ) return; } - /* Freie Connection-Struktur suschen */ + /* Freie Connection-Struktur suchen */ for( idx = 0; idx < MAX_CONNECTIONS; idx++ ) if( My_Connections[idx].sock == NONE ) break; if( idx >= MAX_CONNECTIONS ) { @@ -774,8 +788,8 @@ Socket2Index( INT Sock ) for( idx = 0; idx < MAX_CONNECTIONS; idx++ ) if( My_Connections[idx].sock == Sock ) break; - assert( idx < MAX_CONNECTIONS ); - return idx; + if( idx >= MAX_CONNECTIONS ) return NONE; + else return idx; } /* Socket2Index */ @@ -811,7 +825,7 @@ Read_Request( CONN_ID Idx ) if( len < 0 ) { /* Fehler beim Lesen */ - Log( LOG_ERR, "Read error on connection %d: %s!", Idx, strerror( errno )); + Log( LOG_ERR, "Read error on connection %d (socket %d): %s!", Idx, My_Connections[Idx].sock, strerror( errno )); Conn_Close( Idx, "Read error!", "Client closed connection", FALSE ); return; }