X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Fconn.c;h=15a0b28beccdf0b63eb735e11540579a8925465c;hp=95df15c9a6f129c0d4518c1d663741ff68028c0f;hb=a4d5ca633a613869627cfc8988c495cb2234944f;hpb=67d79b92e65f9c7cbe7667cd626960f989513239 diff --git a/src/ngircd/conn.c b/src/ngircd/conn.c index 95df15c9..15a0b28b 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.74 2002/09/26 16:11:26 alex Exp $ + * $Id: conn.c,v 1.88 2002/11/05 14:18:39 alex Exp $ * * connect.h: Verwaltung aller Netz-Verbindungen ("connections") */ @@ -75,6 +75,8 @@ 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 */ + INT flag; /* Channel-Flag (vgl. "irc-write"-Modul) */ } CONNECTION; @@ -87,7 +89,7 @@ LOCAL BOOLEAN Try_Write PARAMS(( CONN_ID Idx )); LOCAL VOID Handle_Buffer PARAMS(( CONN_ID Idx )); LOCAL VOID Check_Connections PARAMS(( VOID )); LOCAL VOID Check_Servers PARAMS(( VOID )); -LOCAL VOID Init_Conn_Struct PARAMS(( INT Idx )); +LOCAL VOID Init_Conn_Struct PARAMS(( LONG Idx )); LOCAL BOOLEAN Init_Socket PARAMS(( INT Sock )); LOCAL VOID New_Server PARAMS(( INT Server, CONN_ID Idx )); LOCAL VOID Read_Resolver_Result PARAMS(( INT r_fd )); @@ -97,7 +99,8 @@ LOCAL fd_set My_Listeners; LOCAL fd_set My_Sockets; LOCAL fd_set My_Connects; -LOCAL CONNECTION My_Connections[MAX_CONNECTIONS]; +LOCAL CONNECTION *My_Connections; +LOCAL LONG Pool_Size; GLOBAL VOID @@ -107,15 +110,32 @@ Conn_Init( VOID ) CONN_ID i; + /* Speicher fuer Verbindungs-Pool anfordern */ + Pool_Size = CONNECTION_POOL; + if( Conf_MaxConnections > 0 ) + { + /* konfiguriertes Limit beachten */ + if( Pool_Size > Conf_MaxConnections ) Pool_Size = Conf_MaxConnections; + } + My_Connections = malloc( sizeof( CONNECTION ) * Pool_Size ); + if( ! My_Connections ) + { + /* Speicher konnte nicht alloziert werden! */ + Log( LOG_EMERG, "Can't allocate memory! [Conn_Init]" ); + exit( 1 ); + } + Log( LOG_DEBUG, "Allocted connection pool for %ld items.", Pool_Size ); + /* zu Beginn haben wir keine Verbindungen */ FD_ZERO( &My_Listeners ); FD_ZERO( &My_Sockets ); FD_ZERO( &My_Connects ); + /* Groesster File-Descriptor fuer select() */ Conn_MaxFD = 0; /* Connection-Struktur initialisieren */ - for( i = 0; i < MAX_CONNECTIONS; i++ ) Init_Conn_Struct( i ); + for( i = 0; i < Pool_Size; i++ ) Init_Conn_Struct( i ); } /* Conn_Init */ @@ -134,7 +154,7 @@ Conn_Exit( VOID ) { if( FD_ISSET( i, &My_Sockets )) { - for( idx = 0; idx < MAX_CONNECTIONS; idx++ ) + for( idx = 0; idx < Pool_Size; idx++ ) { if( My_Connections[idx].sock == i ) break; } @@ -148,7 +168,7 @@ Conn_Exit( VOID ) close( i ); Log( LOG_DEBUG, "Connection %d closed during creation (socket %d).", idx, i ); } - else if( idx < MAX_CONNECTIONS ) + else if( idx < Pool_Size ) { if( NGIRCd_Restart ) Conn_Close( idx, NULL, "Server going down (restarting)", TRUE ); else Conn_Close( idx, NULL, "Server going down", TRUE ); @@ -160,6 +180,10 @@ Conn_Exit( VOID ) } } } + + free( My_Connections ); + My_Connections = NULL; + Pool_Size = 0; } /* Conn_Exit */ @@ -235,7 +259,7 @@ Conn_Handler( VOID ) fd_set read_sockets, write_sockets; struct timeval tv; time_t start, t; - INT i; + LONG i, idx; start = time( NULL ); while(( ! NGIRCd_Quit ) && ( ! NGIRCd_Restart )) @@ -245,7 +269,7 @@ Conn_Handler( VOID ) Check_Connections( ); /* noch volle Lese-Buffer suchen */ - for( i = 0; i < MAX_CONNECTIONS; i++ ) + for( i = 0; i < Pool_Size; i++ ) { if(( My_Connections[i].sock > NONE ) && ( My_Connections[i].rdatalen > 0 )) { @@ -256,7 +280,7 @@ Conn_Handler( VOID ) /* noch volle Schreib-Puffer suchen */ FD_ZERO( &write_sockets ); - for( i = 0; i < MAX_CONNECTIONS; i++ ) + for( i = 0; i < Pool_Size; i++ ) { if(( My_Connections[i].sock > NONE ) && ( My_Connections[i].wdatalen > 0 )) { @@ -265,7 +289,7 @@ Conn_Handler( VOID ) } } /* Sockets mit im Aufbau befindlichen ausgehenden Verbindungen suchen */ - for( i = 0; i < MAX_CONNECTIONS; i++ ) + for( i = 0; i < Pool_Size; i++ ) { if(( My_Connections[i].sock > NONE ) && ( FD_ISSET( My_Connections[i].sock, &My_Connects ))) FD_SET( My_Connections[i].sock, &write_sockets ); } @@ -273,7 +297,7 @@ Conn_Handler( VOID ) /* von welchen Sockets koennte gelesen werden? */ t = time( NULL ); read_sockets = My_Sockets; - for( i = 0; i < MAX_CONNECTIONS; i++ ) + for( i = 0; i < Pool_Size; i++ ) { if(( My_Connections[i].sock > NONE ) && ( My_Connections[i].host[0] == '\0' )) { @@ -317,7 +341,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 ); } @@ -327,7 +351,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 == NONE ) 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? */ @@ -358,7 +393,7 @@ va_dcl BOOLEAN ok; va_list ap; - assert( Idx >= 0 ); + assert( Idx > NONE ); assert( Format != NULL ); #ifdef PROTOTYPES @@ -391,7 +426,7 @@ Conn_Write( CONN_ID Idx, CHAR *Data, INT Len ) /* Daten in Socket schreiben. Bei "fatalen" Fehlern wird * der Client disconnectiert und FALSE geliefert. */ - assert( Idx >= 0 ); + assert( Idx > NONE ); assert( Data != NULL ); assert( Len > 0 ); @@ -444,11 +479,20 @@ Conn_Close( CONN_ID Idx, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN InformClient ) CLIENT *c; - assert( Idx >= 0 ); + assert( Idx > NONE ); 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: client %.1f kb, server %.1f kb.", 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; @@ -456,14 +500,18 @@ 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; - c = Client_GetFromConn( Idx ); if( c ) Client_Destroy( c, LogMsg, FwdMsg, TRUE ); if( My_Connections[Idx].res_stat ) @@ -475,18 +523,18 @@ Conn_Close( CONN_ID Idx, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN InformClient ) free( My_Connections[Idx].res_stat ); } - /* Bei Server-Verbindungen lasttry-Zeitpunkt so setzen, dass - * der naechste Verbindungsversuch in RECONNECT_DELAY Sekunden - * gestartet wird. */ - if(( My_Connections[Idx].our_server >= 0 ) && ( Conf_Server[My_Connections[Idx].our_server].lasttry < time( NULL ))) + /* Startzeit des naechsten Connect-Versuchs modifizieren? */ + if(( My_Connections[Idx].our_server > NONE ) && ( Conf_Server[My_Connections[Idx].our_server].lasttry < time( NULL ) - Conf_ConnectRetry )) { - /* Okay, die Verbindung stand schon "genuegend lange" */ + /* Okay, die Verbindung stand schon "genuegend lange": + * lasttry-Zeitpunkt so setzen, dass der naechste + * Verbindungsversuch in RECONNECT_DELAY Sekunden + * gestartet wird. */ 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 */ @@ -495,7 +543,7 @@ Conn_UpdateIdle( CONN_ID Idx ) { /* Idle-Timer zuruecksetzen */ - assert( Idx >= 0 ); + assert( Idx > NONE ); My_Connections[Idx].lastprivmsg = time( NULL ); } @@ -505,7 +553,7 @@ Conn_GetIdle( CONN_ID Idx ) { /* Idle-Time einer Verbindung liefern (in Sekunden) */ - assert( Idx >= 0 ); + assert( Idx > NONE ); return time( NULL ) - My_Connections[Idx].lastprivmsg; } /* Conn_GetIdle */ @@ -515,7 +563,7 @@ Conn_LastPing( CONN_ID Idx ) { /* Zeitpunkt des letzten PING liefern */ - assert( Idx >= 0 ); + assert( Idx > NONE ); return My_Connections[Idx].lastping; } /* Conn_LastPing */ @@ -530,7 +578,7 @@ Conn_SetPenalty( CONN_ID Idx, time_t Seconds ) time_t t; - assert( Idx >= 0 ); + assert( Idx > NONE ); assert( Seconds >= 0 ); t = time( NULL ) + Seconds; @@ -538,6 +586,92 @@ Conn_SetPenalty( CONN_ID Idx, time_t Seconds ) } /* Conn_SetPenalty */ +GLOBAL VOID +Conn_ResetPenalty( CONN_ID Idx ) +{ + assert( Idx > NONE ); + My_Connections[Idx].delaytime = 0; +} /* Conn_ResetPenalty */ + + +GLOBAL VOID +Conn_ClearFlags( VOID ) +{ + /* Alle Connection auf "nicht-markiert" setzen */ + + LONG i; + + for( i = 0; i < Pool_Size; i++ ) My_Connections[i].flag = 0; +} /* Conn_ClearFlags */ + + +GLOBAL INT +Conn_Flag( CONN_ID Idx ) +{ + /* Ist eine Connection markiert (TRUE) oder nicht? */ + + assert( Idx > NONE ); + return My_Connections[Idx].flag; +} /* Conn_Flag */ + + +GLOBAL VOID +Conn_SetFlag( CONN_ID Idx, INT Flag ) +{ + /* Connection markieren */ + + assert( Idx > NONE ); + My_Connections[Idx].flag = Flag; +} /* Conn_SetFlag */ + + +GLOBAL CONN_ID +Conn_First( VOID ) +{ + /* Connection-Struktur der ersten Verbindung liefern; + * Ist keine Verbindung vorhanden, wird NONE geliefert. */ + + LONG i; + + for( i = 0; i < Pool_Size; i++ ) + { + if( My_Connections[i].sock != NONE ) return i; + } + return NONE; +} /* Conn_First */ + + +GLOBAL CONN_ID +Conn_Next( CONN_ID Idx ) +{ + /* Naechste Verbindungs-Struktur liefern; existiert keine + * weitere, so wird NONE geliefert. */ + + LONG i = NONE; + + assert( Idx > NONE ); + + for( i = Idx + 1; i < Pool_Size; i++ ) + { + if( My_Connections[i].sock != NONE ) return i; + } + return NONE; +} /* Conn_Next */ + + +GLOBAL VOID +Conn_SetServer( CONN_ID Idx, INT ConfServer ) +{ + /* Connection als Server markieren: Index des konfigurierten + * Servers speichern. Verbindung muss bereits bestehen! */ + + assert( Idx > NONE ); + assert( My_Connections[Idx].sock > NONE ); + + My_Connections[Idx].our_server = ConfServer; +} /* Conn_SetServer */ + + LOCAL BOOLEAN Try_Write( CONN_ID Idx ) { @@ -546,7 +680,7 @@ Try_Write( CONN_ID Idx ) fd_set write_socket; - assert( Idx >= 0 ); + assert( Idx > NONE ); assert( My_Connections[Idx].sock > NONE ); assert( My_Connections[Idx].wdatalen > 0 ); @@ -557,7 +691,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; } @@ -578,7 +712,7 @@ Handle_Read( INT Sock ) CONN_ID idx; - assert( Sock >= 0 ); + assert( Sock > NONE ); if( FD_ISSET( Sock, &My_Listeners )) { @@ -598,7 +732,7 @@ Handle_Read( INT Sock ) /* Ein Client Socket: entweder ein User oder Server */ idx = Socket2Index( Sock ); - Read_Request( idx ); + if( idx > NONE ) Read_Request( idx ); } } /* Handle_Read */ @@ -610,7 +744,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 )) @@ -646,9 +780,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 ); @@ -658,11 +790,14 @@ 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; } + /* 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 ); @@ -682,8 +817,10 @@ New_Connection( INT Sock ) RES_STAT *s; CONN_ID idx; CLIENT *c; + POINTER *ptr; + LONG new_size; - assert( Sock >= 0 ); + assert( Sock > NONE ); new_sock_len = sizeof( new_addr ); new_sock = accept( Sock, (struct sockaddr *)&new_addr, (socklen_t *)&new_sock_len ); @@ -693,13 +830,53 @@ New_Connection( INT Sock ) return; } - /* Freie Connection-Struktur suschen */ - for( idx = 0; idx < MAX_CONNECTIONS; idx++ ) if( My_Connections[idx].sock == NONE ) break; - if( idx >= MAX_CONNECTIONS ) + /* Freie Connection-Struktur suchen */ + for( idx = 0; idx < Pool_Size; idx++ ) if( My_Connections[idx].sock == NONE ) break; + if( idx >= Pool_Size ) { - Log( LOG_ALERT, "Can't accept connection: limit reached (%d)!", MAX_CONNECTIONS ); - close( new_sock ); - return; + new_size = Pool_Size + CONNECTION_POOL; + + /* Im bisherigen Pool wurde keine freie Connection-Struktur mehr gefunden. + * Wenn erlaubt und moeglich muss nun der Pool vergroessert werden: */ + + if( Conf_MaxConnections > 0 ) + { + /* Es ist ein Limit konfiguriert */ + if( Pool_Size >= Conf_MaxConnections ) + { + /* Mehr Verbindungen duerfen wir leider nicht mehr annehmen ... */ + Log( LOG_ALERT, "Can't accept connection: limit (%d) reached!", Pool_Size ); + close( new_sock ); + return; + } + if( new_size > Conf_MaxConnections ) new_size = Conf_MaxConnections; + } + + /* zunaechst realloc() versuchen; wenn das scheitert, malloc() versuchen + * und Daten ggf. "haendisch" umkopieren. (Haesslich! Eine wirklich + * dynamische Verwaltung waere wohl _deutlich_ besser ...) */ + ptr = realloc( My_Connections, sizeof( CONNECTION ) * new_size ); + if( ! ptr ) + { + /* realloc() ist fehlgeschlagen. Nun malloc() probieren: */ + ptr = malloc( sizeof( CONNECTION ) * new_size ); + if( ! ptr ) + { + /* Offenbar steht kein weiterer Sepeicher zur Verfuegung :-( */ + Log( LOG_EMERG, "Can't allocate memory! [New_Connection]" ); + close( new_sock ); + return; + } + + /* Struktur umkopieren ... */ + memcpy( ptr, My_Connections, sizeof( CONNECTION ) * Pool_Size ); + + Log( LOG_DEBUG, "Allocated new connection pool for %ld items. [malloc()/memcpy()]", new_size ); + } + else Log( LOG_DEBUG, "Allocated new connection pool for %ld items. [realloc()]", new_size ); + + My_Connections = ptr; + Pool_Size = new_size; } /* Client-Struktur initialisieren */ @@ -727,6 +904,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 @@ -737,7 +915,7 @@ New_Connection( INT Sock ) } /* Penalty-Zeit setzen */ - Conn_SetPenalty( idx, 1 ); + Conn_SetPenalty( idx, 4 ); } /* New_Connection */ @@ -748,12 +926,18 @@ Socket2Index( INT Sock ) CONN_ID idx; - assert( Sock >= 0 ); + assert( Sock > NONE ); - for( idx = 0; idx < MAX_CONNECTIONS; idx++ ) if( My_Connections[idx].sock == Sock ) break; + for( idx = 0; idx < Pool_Size; idx++ ) if( My_Connections[idx].sock == Sock ) break; - assert( idx < MAX_CONNECTIONS ); - return idx; + if( idx >= Pool_Size ) + { + /* die Connection wurde vermutlich (wegen eines + * Fehlers) bereits wieder abgebaut ... */ + Log( LOG_DEBUG, "Socket2Index: can't get connection for socket %d!", Sock ); + return NONE; + } + else return idx; } /* Socket2Index */ @@ -765,7 +949,7 @@ Read_Request( CONN_ID Idx ) INT len; - assert( Idx >= 0 ); + assert( Idx > NONE ); assert( My_Connections[Idx].sock > NONE ); if( READBUFFER_LEN - My_Connections[Idx].rdatalen - 2 < 0 ) @@ -789,11 +973,14 @@ 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; } + /* Connection-Statistik aktualisieren */ + My_Connections[Idx].bytes_in += len; + /* Lesebuffer updaten */ My_Connections[Idx].rdatalen += len; assert( My_Connections[Idx].rdatalen < READBUFFER_LEN ); @@ -811,7 +998,10 @@ Handle_Buffer( CONN_ID Idx ) { /* Daten im Lese-Puffer einer Verbindung verarbeiten. */ - CHAR *ptr, *ptr1, *ptr2; +#ifndef STRICT_RFC + CHAR *ptr1, *ptr2; +#endif + CHAR *ptr; INT len, delta; /* Eine komplette Anfrage muss mit CR+LF enden, vgl. @@ -869,9 +1059,9 @@ Check_Connections( VOID ) * auch das nicht "hilft", Client disconnectieren. */ CLIENT *c; - INT i; + LONG i; - for( i = 0; i < MAX_CONNECTIONS; i++ ) + for( i = 0; i < Pool_Size; i++ ) { if( My_Connections[i].sock == NONE ) continue; @@ -917,8 +1107,9 @@ Check_Servers( VOID ) /* Pruefen, ob Server-Verbindungen aufgebaut werden * muessen bzw. koennen */ - INT idx, i, n; RES_STAT *s; + LONG idx, n; + INT i; /* Wenn "Passive-Mode" aktiv: nicht verbinden */ if( NGIRCd_Passive ) return; @@ -929,7 +1120,7 @@ Check_Servers( VOID ) if(( ! Conf_Server[i].host[0] ) || ( ! Conf_Server[i].port > 0 )) continue; /* Haben wir schon eine Verbindung? */ - for( n = 0; n < MAX_CONNECTIONS; n++ ) + for( n = 0; n < Pool_Size; n++ ) { if( My_Connections[n].sock == NONE ) continue; @@ -949,7 +1140,7 @@ Check_Servers( VOID ) if( Conf_Server[My_Connections[n].our_server].group == Conf_Server[i].group ) break; } } - if( n < MAX_CONNECTIONS ) continue; + if( n < Pool_Size ) continue; /* Wann war der letzte Connect-Versuch? */ if( Conf_Server[i].lasttry > time( NULL ) - Conf_ConnectRetry ) continue; @@ -958,10 +1149,10 @@ Check_Servers( VOID ) Conf_Server[i].lasttry = time( NULL ); /* Freie Connection-Struktur suschen */ - for( idx = 0; idx < MAX_CONNECTIONS; idx++ ) if( My_Connections[idx].sock == NONE ) break; - if( idx >= MAX_CONNECTIONS ) + for( idx = 0; idx < Pool_Size; idx++ ) if( My_Connections[idx].sock == NONE ) break; + if( idx >= Pool_Size ) { - Log( LOG_ALERT, "Can't establist server connection: connection limit reached (%d)!", MAX_CONNECTIONS ); + Log( LOG_ALERT, "Can't establist server connection: connection limit reached (%d)!", Pool_Size ); return; } Log( LOG_DEBUG, "Preparing connection %d for \"%s\" ...", idx, Conf_Server[i].host ); @@ -998,8 +1189,8 @@ New_Server( INT Server, CONN_ID Idx ) INT new_sock; CLIENT *c; - assert( Server >= 0 ); - assert( Idx >= 0 ); + assert( Server > NONE ); + assert( Idx > NONE ); /* Wurde eine gueltige IP-Adresse gefunden? */ if( ! Conf_Server[Server].ip[0] ) @@ -1072,11 +1263,13 @@ New_Server( INT Server, CONN_ID Idx ) FD_SET( new_sock, &My_Sockets ); FD_SET( new_sock, &My_Connects ); if( new_sock > Conn_MaxFD ) Conn_MaxFD = new_sock; + + Log( LOG_DEBUG, "Registered new connection %d on socket %d.", Idx, My_Connections[Idx].sock ); } /* New_Server */ LOCAL VOID -Init_Conn_Struct( INT Idx ) +Init_Conn_Struct( LONG Idx ) { /* Connection-Struktur initialisieren */ @@ -1092,6 +1285,9 @@ 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; + My_Connections[Idx].flag = 0; } /* Init_Conn_Struct */ @@ -1133,7 +1329,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 */ @@ -1144,14 +1340,14 @@ Read_Resolver_Result( INT r_fd ) result[len] = '\0'; /* zugehoerige Connection suchen */ - for( i = 0; i < MAX_CONNECTIONS; i++ ) + for( i = 0; i < Pool_Size; i++ ) { if(( My_Connections[i].sock != NONE ) && ( My_Connections[i].res_stat ) && ( My_Connections[i].res_stat->pipe[0] == r_fd )) break; } - if( i >= MAX_CONNECTIONS ) + if( i >= Pool_Size ) { /* Opsa! Keine passende Connection gefunden!? Vermutlich - * wurde sie schon wieder geschlossen. */ + * wurde sie schon wieder geschlossen. */ close( r_fd ); Log( LOG_DEBUG, "Resolver: Got result for unknown connection!?" ); return; @@ -1170,13 +1366,18 @@ 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 { /* Ausgehende Verbindung (=Server): IP setzen */ - assert( My_Connections[i].our_server >= 0 ); + assert( My_Connections[i].our_server > NONE ); strcpy( Conf_Server[My_Connections[i].our_server].ip, result ); } + + /* Penalty-Zeit zurueck setzen */ + Conn_ResetPenalty( i ); } /* Read_Resolver_Result */