diff --git a/ChangeLog b/ChangeLog index 74ba452d..7ad21180 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24,6 +24,8 @@ ngIRCd CVS-HEAD - If the server can't close a socket, it panics now. This is an error that can't occure during normal operation so there is something broken. - The order of log messages during disconnects is more "natural" now ;-) + - Cleaned up handling of server configuration structures: modifying and + removing servers during runtime works more reliable now. Older changes (sorry, only available in german language): @@ -387,4 +389,4 @@ ngIRCd 0.0.1, 31.12.2001 -- -$Id: ChangeLog,v 1.156 2002/12/27 13:24:55 alex Exp $ +$Id: ChangeLog,v 1.157 2002/12/30 00:01:42 alex Exp $ diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c index 50c9ee1b..c12658d9 100644 --- a/src/ngircd/conf.c +++ b/src/ngircd/conf.c @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: conf.c,v 1.51 2002/12/26 17:04:54 alex Exp $"; +static char UNUSED id[] = "$Id: conf.c,v 1.52 2002/12/30 00:01:45 alex Exp $"; #include "imp.h" #include @@ -46,9 +46,11 @@ static char UNUSED id[] = "$Id: conf.c,v 1.51 2002/12/26 17:04:54 alex Exp $"; LOCAL BOOLEAN Use_Log = TRUE; +LOCAL CONF_SERVER New_Server; +LOCAL INT New_Server_Idx; -LOCAL VOID Set_Defaults PARAMS(( VOID )); +LOCAL VOID Set_Defaults PARAMS(( BOOLEAN InitServers )); LOCAL VOID Read_Config PARAMS(( VOID )); LOCAL VOID Validate_Config PARAMS(( BOOLEAN TestOnly )); @@ -59,16 +61,27 @@ LOCAL VOID Handle_CHANNEL PARAMS(( INT Line, CHAR *Var, CHAR *Arg )); LOCAL VOID Config_Error PARAMS(( CONST INT Level, CONST CHAR *Format, ... )); +LOCAL VOID Init_Server_Struct PARAMS(( CONF_SERVER *Server )); + GLOBAL VOID Conf_Init( VOID ) { - Set_Defaults( ); + Set_Defaults( TRUE ); Read_Config( ); Validate_Config( FALSE ); } /* Config_Init */ +GLOBAL VOID +Conf_Rehash( VOID ) +{ + Set_Defaults( FALSE ); + Read_Config( ); + Validate_Config( FALSE ); +} /* Config_Rehash */ + + GLOBAL INT Conf_Test( VOID ) { @@ -79,7 +92,7 @@ Conf_Test( VOID ) INT i; Use_Log = FALSE; - Set_Defaults( ); + Set_Defaults( TRUE ); Read_Config( ); Validate_Config( TRUE ); @@ -134,7 +147,7 @@ Conf_Test( VOID ) puts( "" ); } - for( i = 0; i < Conf_Server_Count; i++ ) + for( i = 0; i < MAX_SERVERS; i++ ) { if( ! Conf_Server[i].name[0] ) continue; @@ -165,11 +178,79 @@ Conf_Test( VOID ) } /* Conf_Test */ +GLOBAL VOID +Conf_UnsetServer( CONN_ID Idx ) +{ + /* Set next time for next connection attempt, if this is a server + * link that is (still) configured here. If the server is set as + * "once", delete it from our configuration. + * Non-Server-Connections will be silently ignored. */ + + INT i; + + /* Check all our configured servers */ + for( i = 0; i < MAX_SERVERS; i++ ) + { + if( Conf_Server[i].conn_id != Idx ) continue; + + /* Gotcha! Mark server configuration as "unused": */ + Conf_Server[i].conn_id = NONE; + + if( Conf_Server[i].once ) + { + /* Delete configuration here */ + Init_Server_Struct( &Conf_Server[i] ); + } + else + { + /* Set time for next connect attempt */ + if( Conf_Server[i].lasttry < time( NULL ) - Conf_ConnectRetry ) + { + /* Okay, the connection was established "long enough": */ + Conf_Server[i].lasttry = time( NULL ) - Conf_ConnectRetry + RECONNECT_DELAY; + } + } + break; + } +} /* Conf_UnsetServer */ + + +GLOBAL VOID +Conf_SetServer( INT ConfServer, CONN_ID Idx ) +{ + /* Set connection for specified configured server */ + + assert( ConfServer > NONE ); + assert( Idx > NONE ); + + Conf_Server[ConfServer].conn_id = Idx; +} /* Conf_SetServer */ + + +GLOBAL INT +Conf_GetServer( CONN_ID Idx ) +{ + /* Get index of server in configuration structure */ + + INT i; + + assert( Idx > NONE ); + + for( i = 0; i < MAX_SERVERS; i++ ) + { + if( Conf_Server[i].conn_id == Idx ) return i; + } + return NONE; +} /* Conf_GetServer */ + + LOCAL VOID -Set_Defaults( VOID ) +Set_Defaults( BOOLEAN InitServers ) { /* Initialize configuration variables with default values. */ + INT i; + strcpy( Conf_ServerName, "" ); sprintf( Conf_ServerInfo, "%s %s", PACKAGE, VERSION ); strcpy( Conf_ServerPwd, "" ); @@ -191,13 +272,15 @@ Set_Defaults( VOID ) Conf_ConnectRetry = 60; Conf_Oper_Count = 0; - Conf_Server_Count = 0; Conf_Channel_Count = 0; Conf_OperCanMode = FALSE; Conf_MaxConnections = -1; Conf_MaxJoins = 10; + + /* Initialize server configuration structures */ + if( InitServers ) for( i = 0; i < MAX_SERVERS; Init_Server_Struct( &Conf_Server[i++] )); } /* Set_Defaults */ @@ -207,9 +290,10 @@ Read_Config( VOID ) /* Read configuration file. */ CHAR section[LINE_LEN], str[LINE_LEN], *var, *arg, *ptr; - INT line; + INT line, i; FILE *fd; + /* Open configuration file */ fd = fopen( NGIRCd_ConfFile, "r" ); if( ! fd ) { @@ -221,8 +305,22 @@ Read_Config( VOID ) Config_Error( LOG_INFO, "Reading configuration from \"%s\" ...", NGIRCd_ConfFile ); + /* Clean up server configuration structure: mark all already + * configured servers as "once" so that they are deleted + * after the next disconnect and delete all unused servers. */ + for( i = 0; i < MAX_SERVERS; i++ ) + { + if( Conf_Server[i].conn_id == NONE ) Init_Server_Struct( &Conf_Server[i] ); + else Conf_Server[i].once = TRUE; + } + + /* Initialize variables */ line = 0; strcpy( section, "" ); + Init_Server_Struct( &New_Server ); + New_Server_Idx = NONE; + + /* Read configuration file */ while( TRUE ) { if( ! fgets( str, LINE_LEN, fd )) break; @@ -251,21 +349,30 @@ Read_Config( VOID ) } if( strcasecmp( section, "[SERVER]" ) == 0 ) { - if( Conf_Server_Count + 1 > MAX_SERVERS ) Config_Error( LOG_ERR, "Too many servers configured." ); - else + /* Check if there is already a server to add */ + if( New_Server.name[0] ) { - /* Initialize new server structure */ - strcpy( Conf_Server[Conf_Server_Count].host, "" ); - strcpy( Conf_Server[Conf_Server_Count].ip, "" ); - strcpy( Conf_Server[Conf_Server_Count].name, "" ); - strcpy( Conf_Server[Conf_Server_Count].pwd_in, "" ); - strcpy( Conf_Server[Conf_Server_Count].pwd_out, "" ); - Conf_Server[Conf_Server_Count].port = 0; - Conf_Server[Conf_Server_Count].group = -1; - Conf_Server[Conf_Server_Count].lasttry = time( NULL ) - Conf_ConnectRetry + STARTUP_DELAY; - Conf_Server[Conf_Server_Count].res_stat = NULL; - Conf_Server_Count++; + /* Copy data to "real" server structure */ + assert( New_Server_Idx > NONE ); + Conf_Server[New_Server_Idx] = New_Server; } + + /* Re-init structure for new server */ + Init_Server_Struct( &New_Server ); + + /* Search unused item in server configuration structure */ + for( i = 0; i < MAX_SERVERS; i++ ) + { + /* Is this item used? */ + if( ! Conf_Server[i].name[0] ) break; + } + if( i >= MAX_SERVERS ) + { + /* Oops, no free item found! */ + Config_Error( LOG_ERR, "Too many servers configured." ); + New_Server_Idx = NONE; + } + else New_Server_Idx = i; continue; } if( strcasecmp( section, "[CHANNEL]" ) == 0 ) @@ -303,8 +410,17 @@ Read_Config( VOID ) else if( strcasecmp( section, "[CHANNEL]" ) == 0 ) Handle_CHANNEL( line, var, arg ); else Config_Error( LOG_ERR, "%s, line %d: Variable \"%s\" outside section!", NGIRCd_ConfFile, line, var ); } - + + /* Close configuration file */ fclose( fd ); + + /* Check if there is still a server to add */ + if( New_Server.name[0] ) + { + /* Copy data to "real" server structure */ + assert( New_Server_Idx > NONE ); + Conf_Server[New_Server_Idx] = New_Server; + } /* If there are no ports configured use the default: 6667 */ if( Conf_ListenPorts_Count < 1 ) @@ -519,35 +635,38 @@ Handle_SERVER( INT Line, CHAR *Var, CHAR *Arg ) assert( Var != NULL ); assert( Arg != NULL ); + /* Ignore server block if no space is left in server configuration structure */ + if( New_Server_Idx <= NONE ) return; + if( strcasecmp( Var, "Host" ) == 0 ) { /* Hostname of the server */ - if( strlcpy( Conf_Server[Conf_Server_Count - 1].host, Arg, sizeof( Conf_Server[Conf_Server_Count - 1].host )) >= sizeof( Conf_Server[Conf_Server_Count - 1].host )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Host\" too long!", NGIRCd_ConfFile, Line ); + if( strlcpy( New_Server.host, Arg, sizeof( New_Server.host )) >= sizeof( New_Server.host )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Host\" too long!", NGIRCd_ConfFile, Line ); return; } if( strcasecmp( Var, "Name" ) == 0 ) { /* Name of the server ("Nick"/"ID") */ - if( strlcpy( Conf_Server[Conf_Server_Count - 1].name, Arg, sizeof( Conf_Server[Conf_Server_Count - 1].name )) >= sizeof( Conf_Server[Conf_Server_Count - 1].name )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Name\" too long!", NGIRCd_ConfFile, Line ); + if( strlcpy( New_Server.name, Arg, sizeof( New_Server.name )) >= sizeof( New_Server.name )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Name\" too long!", NGIRCd_ConfFile, Line ); return; } if( strcasecmp( Var, "MyPassword" ) == 0 ) { /* Password of this server which is sent to the peer */ - if( strlcpy( Conf_Server[Conf_Server_Count - 1].pwd_in, Arg, sizeof( Conf_Server[Conf_Server_Count - 1].pwd_in )) >= sizeof( Conf_Server[Conf_Server_Count - 1].pwd_in )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"MyPassword\" too long!", NGIRCd_ConfFile, Line ); + if( strlcpy( New_Server.pwd_in, Arg, sizeof( New_Server.pwd_in )) >= sizeof( New_Server.pwd_in )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"MyPassword\" too long!", NGIRCd_ConfFile, Line ); return; } if( strcasecmp( Var, "PeerPassword" ) == 0 ) { /* Passwort of the peer which must be received */ - if( strlcpy( Conf_Server[Conf_Server_Count - 1].pwd_out, Arg, sizeof( Conf_Server[Conf_Server_Count - 1].pwd_out )) >= sizeof( Conf_Server[Conf_Server_Count - 1].pwd_out )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"PeerPassword\" too long!", NGIRCd_ConfFile, Line ); + if( strlcpy( New_Server.pwd_out, Arg, sizeof( New_Server.pwd_out )) >= sizeof( New_Server.pwd_out )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"PeerPassword\" too long!", NGIRCd_ConfFile, Line ); return; } if( strcasecmp( Var, "Port" ) == 0 ) { /* Port to which this server should connect */ port = atol( Arg ); - if( port > 0 && port < 0xFFFF ) Conf_Server[Conf_Server_Count - 1].port = (INT)port; + if( port > 0 && port < 0xFFFF ) New_Server.port = (INT)port; else Config_Error( LOG_ERR, "%s, line %d (section \"Server\"): Illegal port number %ld!", NGIRCd_ConfFile, Line, port ); return; } @@ -558,7 +677,7 @@ Handle_SERVER( INT Line, CHAR *Var, CHAR *Arg ) if( ! isdigit( *Arg )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Group\" is not a number!", NGIRCd_ConfFile, Line ); else #endif - Conf_Server[Conf_Server_Count - 1].group = atoi( Arg ); + New_Server.group = atoi( Arg ); return; } @@ -600,7 +719,11 @@ LOCAL VOID Validate_Config( BOOLEAN Configtest ) { /* Validate configuration settings. */ - + +#ifdef DEBUG + INT i, servers, servers_once; +#endif + if( ! Conf_ServerName[0] ) { /* No server name configured! */ @@ -639,6 +762,19 @@ Validate_Config( BOOLEAN Configtest ) #else Config_Error( LOG_WARN, "Don't know how many file descriptors select() can handle on this system, don't set MaxConnections too high!" ); #endif + +#ifdef DEBUG + servers = servers_once = 0; + for( i = 0; i < MAX_SERVERS; i++ ) + { + if( Conf_Server[i].name[0] ) + { + servers++; + if( Conf_Server[i].once ) servers_once++; + } + } + Log( LOG_DEBUG, "Configuration: Operators=%d, Servers=%d[%d], Channels=%d", Conf_Oper_Count, servers, servers_once, Conf_Channel_Count ); +#endif } /* Validate_Config */ @@ -674,4 +810,25 @@ va_dcl } /* Config_Error */ +LOCAL VOID +Init_Server_Struct( CONF_SERVER *Server ) +{ + /* Initialize server configuration structur to default values */ + + assert( Server != NULL ); + + strcpy( Server->host, "" ); + strcpy( Server->ip, "" ); + strcpy( Server->name, "" ); + strcpy( Server->pwd_in, "" ); + strcpy( Server->pwd_out, "" ); + Server->port = 0; + Server->group = NONE; + Server->lasttry = time( NULL ) - Conf_ConnectRetry + STARTUP_DELAY; + Server->res_stat = NULL; + Server->once = FALSE; + Server->conn_id = NONE; +} /* Init_Server_Struct */ + + /* -eof- */ diff --git a/src/ngircd/conf.h b/src/ngircd/conf.h index c4cf3383..dce12fba 100644 --- a/src/ngircd/conf.h +++ b/src/ngircd/conf.h @@ -8,7 +8,7 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: conf.h,v 1.24 2002/12/14 13:36:19 alex Exp $ + * $Id: conf.h,v 1.25 2002/12/30 00:01:45 alex Exp $ * * Configuration management (header) */ @@ -39,6 +39,8 @@ typedef struct _Conf_Server INT group; /* Group of server */ time_t lasttry; /* Last connect attempt */ RES_STAT *res_stat; /* Status of the resolver */ + BOOLEAN once; /* This server is valid only once */ + CONN_ID conn_id; /* ID of server connection or NONE */ } CONF_SERVER; typedef struct _Conf_Channel @@ -87,7 +89,6 @@ GLOBAL INT Conf_Oper_Count; /* Servers */ GLOBAL CONF_SERVER Conf_Server[MAX_SERVERS]; -GLOBAL INT Conf_Server_Count; /* Pre-defined channels */ GLOBAL CONF_CHANNEL Conf_Channel[MAX_DEFCHANNELS]; @@ -104,8 +105,13 @@ GLOBAL INT Conf_MaxJoins; GLOBAL VOID Conf_Init PARAMS((VOID )); +GLOBAL VOID Conf_Rehash PARAMS((VOID )); GLOBAL INT Conf_Test PARAMS((VOID )); +GLOBAL VOID Conf_UnsetServer PARAMS(( CONN_ID Idx )); +GLOBAL VOID Conf_SetServer PARAMS(( INT ConfServer, CONN_ID Idx )); +GLOBAL INT Conf_GetServer PARAMS(( CONN_ID Idx )); + #endif diff --git a/src/ngircd/conn.c b/src/ngircd/conn.c index 2e605caf..d36980db 100644 --- a/src/ngircd/conn.c +++ b/src/ngircd/conn.c @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: conn.c,v 1.110 2002/12/27 13:20:13 alex Exp $"; +static char UNUSED id[] = "$Id: conn.c,v 1.111 2002/12/30 00:01:45 alex Exp $"; #include "imp.h" #include @@ -66,39 +66,38 @@ static char UNUSED id[] = "$Id: conn.c,v 1.110 2002/12/27 13:20:13 alex Exp $"; #ifdef USE_ZLIB typedef struct _ZipData { - z_stream in; /* "Handle" fuer Input-Stream */ - z_stream out; /* "Handle" fuer Output-Stream */ - CHAR rbuf[READBUFFER_LEN]; /* Lesepuffer */ - INT rdatalen; /* Laenge der Daten im Lesepuffer (komprimiert) */ - CHAR wbuf[WRITEBUFFER_LEN]; /* Schreibpuffer */ - INT wdatalen; /* Laenge der Daten im Schreibpuffer (unkomprimiert) */ - LONG bytes_in, bytes_out; /* Counter fuer Statistik (unkomprimiert!) */ + z_stream in; /* "Handle" for input stream */ + z_stream out; /* "Handle" for output stream */ + CHAR rbuf[READBUFFER_LEN]; /* Read buffer */ + INT rdatalen; /* Length of data in read buffer (compressed) */ + CHAR wbuf[WRITEBUFFER_LEN]; /* Write buffer */ + INT wdatalen; /* Length of data in write buffer (uncompressed) */ + LONG bytes_in, bytes_out; /* Counter for statistics (uncompressed!) */ } ZIPDATA; #endif typedef struct _Connection { - INT sock; /* Socket Handle */ - struct sockaddr_in addr; /* Adresse des Client */ - RES_STAT *res_stat; /* "Resolver-Status", s.o. */ + INT sock; /* Socket handle */ + struct sockaddr_in addr; /* Client address */ + RES_STAT *res_stat; /* Status of resolver process, if any */ CHAR host[HOST_LEN]; /* Hostname */ - CHAR rbuf[READBUFFER_LEN]; /* Lesepuffer */ - INT rdatalen; /* Laenge der Daten im Lesepuffer */ - CHAR wbuf[WRITEBUFFER_LEN]; /* Schreibpuffer */ - INT wdatalen; /* Laenge der Daten im Schreibpuffer */ - INT our_server; /* wenn von uns zu connectender Server: ID */ - time_t starttime; /* Startzeit des Links */ - time_t lastdata; /* Letzte Aktivitaet */ - time_t lastping; /* Letzter PING */ - time_t lastprivmsg; /* Letzte PRIVMSG */ - time_t delaytime; /* Nicht beachten bis ("penalty") */ - LONG bytes_in, bytes_out; /* Empfangene uns gesendete Bytes */ - LONG msg_in, msg_out; /* Empfangene uns gesendete Nachtichten */ - INT flag; /* "Markierungs-Flag" (vgl. "irc-write"-Modul) */ - INT options; /* Link-Optionen */ + CHAR rbuf[READBUFFER_LEN]; /* Read buffer */ + INT rdatalen; /* Length of data in read buffer */ + CHAR wbuf[WRITEBUFFER_LEN]; /* Write buffer */ + INT wdatalen; /* Length of data in write buffer */ + time_t starttime; /* Start time of link */ + time_t lastdata; /* Last activity */ + time_t lastping; /* Last PING */ + time_t lastprivmsg; /* Last PRIVMSG */ + time_t delaytime; /* Ignore link ("penalty") */ + LONG bytes_in, bytes_out; /* Received and sent bytes */ + LONG msg_in, msg_out; /* Received and sent IRC messages */ + INT flag; /* Flag (see "irc-write" module) */ + INT options; /* Link options */ #ifdef USE_ZLIB - ZIPDATA zip; /* Kompressionsinformationen */ + ZIPDATA zip; /* Compression information */ #endif } CONNECTION; @@ -649,14 +648,7 @@ Conn_Close( CONN_ID Idx, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN InformClient ) } /* Servers: Modify time of next connect attempt? */ - 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": - * 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; - } + Conf_UnsetServer( Idx ); #ifdef USE_ZLIB /* Clean up zlib, if link was compressed */ @@ -793,19 +785,6 @@ Conn_Next( CONN_ID Idx ) } /* 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 */ - - GLOBAL VOID Conn_SetOption( CONN_ID Idx, INT Option ) { @@ -1104,7 +1083,7 @@ Handle_Write( CONN_ID Idx ) { /* Fehler! */ if( res != 0 ) Log( LOG_CRIT, "getsockopt (connection %d): %s!", Idx, strerror( errno )); - else Log( LOG_CRIT, "Can't connect socket to \"%s:%d\" (connection %d): %s!", My_Connections[Idx].host, Conf_Server[My_Connections[Idx].our_server].port, Idx, strerror( err )); + else Log( LOG_CRIT, "Can't connect socket to \"%s:%d\" (connection %d): %s!", My_Connections[Idx].host, Conf_Server[Conf_GetServer( Idx )].port, Idx, strerror( err )); /* Socket etc. pp. aufraeumen */ FD_CLR( My_Connections[Idx].sock, &My_Sockets ); @@ -1112,14 +1091,15 @@ Handle_Write( CONN_ID Idx ) Init_Conn_Struct( Idx ); /* Bei Server-Verbindungen lasttry-Zeitpunkt auf "jetzt" setzen */ - Conf_Server[My_Connections[Idx].our_server].lasttry = time( NULL ); + Conf_Server[Conf_GetServer( Idx )].lasttry = time( NULL ); + Conf_UnsetServer( Idx ); return FALSE; } - Log( LOG_DEBUG, "Connection %d with \"%s:%d\" established, now sendig PASS and SERVER ...", Idx, My_Connections[Idx].host, Conf_Server[My_Connections[Idx].our_server].port ); + Log( LOG_DEBUG, "Connection %d with \"%s:%d\" established, now sendig PASS and SERVER ...", Idx, My_Connections[Idx].host, Conf_Server[Conf_GetServer( Idx )].port ); /* PASS und SERVER verschicken */ - Conn_WriteStr( Idx, "PASS %s %s", Conf_Server[My_Connections[Idx].our_server].pwd_out, NGIRCd_ProtoID ); + Conn_WriteStr( Idx, "PASS %s %s", Conf_Server[Conf_GetServer( Idx )].pwd_out, NGIRCd_ProtoID ); return Conn_WriteStr( Idx, "SERVER %s :%s", Conf_ServerName, Conf_ServerInfo ); } @@ -1534,51 +1514,48 @@ Check_Connections( VOID ) LOCAL VOID Check_Servers( VOID ) { - /* Pruefen, ob Server-Verbindungen aufgebaut werden - * muessen bzw. koennen */ + /* Check if we can establish further server links */ RES_STAT *s; - LONG idx, n; - INT i; + CONN_ID idx; + INT i, n; - /* Wenn "Passive-Mode" aktiv: nicht verbinden */ + /* Don't connect in "passive mode" */ if( NGIRCd_Passive ) return; - for( i = 0; i < Conf_Server_Count; i++ ) + /* Serach all connections, are there results from the resolver? */ + for( idx = 0; idx < Pool_Size; idx++ ) { - /* Ist ein Hostname und Port definiert? */ - if(( ! Conf_Server[i].host[0] ) || ( ! Conf_Server[i].port > 0 )) continue; + if( My_Connections[idx].sock != SERVER_WAIT ) continue; - /* Haben wir schon eine Verbindung? */ - for( n = 0; n < Pool_Size; n++ ) + /* IP resolved? */ + if( My_Connections[idx].res_stat == NULL ) New_Server( Conf_GetServer( idx ), idx ); + } + + /* Check all configured servers */ + for( i = 0; i < MAX_SERVERS; i++ ) + { + /* Valid outgoing server which isn't already connected? */ + if(( ! Conf_Server[i].host[0] ) || ( ! Conf_Server[i].port > 0 ) || ( Conf_Server[i].conn_id > NONE )) continue; + + /* Is there already a connection in this group? */ + if( Conf_Server[i].group > NONE ) { - if( My_Connections[n].sock == NONE ) continue; - - /* Verbindung zu diesem Server? */ - if( My_Connections[n].our_server == i ) + for( n = 0; n < MAX_SERVERS; n++ ) { - /* Komplett aufgebaute Verbindung? */ - if( My_Connections[n].sock > NONE ) break; - - /* IP schon aufgeloest? */ - if( My_Connections[n].res_stat == NULL ) New_Server( i, n ); - } - - /* Verbindung in dieser Server-Gruppe? */ - if(( My_Connections[n].our_server != NONE ) && ( Conf_Server[i].group != NONE )) - { - if( Conf_Server[My_Connections[n].our_server].group == Conf_Server[i].group ) break; + if( n == i ) continue; + if(( Conf_Server[n].conn_id > NONE ) && ( Conf_Server[n].group == Conf_Server[i].group )) break; } + if( n < MAX_SERVERS ) continue; } - if( n < Pool_Size ) continue; - /* Wann war der letzte Connect-Versuch? */ + /* Check last connect attempt? */ if( Conf_Server[i].lasttry > time( NULL ) - Conf_ConnectRetry ) continue; - /* Okay, Verbindungsaufbau versuchen */ + /* Okay, try to connect now */ Conf_Server[i].lasttry = time( NULL ); - /* Freie Connection-Struktur suschen */ + /* Search free connection structure */ for( idx = 0; idx < Pool_Size; idx++ ) if( My_Connections[idx].sock == NONE ) break; if( idx >= Pool_Size ) { @@ -1590,11 +1567,10 @@ Check_Servers( VOID ) /* Verbindungs-Struktur initialisieren */ Init_Conn_Struct( idx ); My_Connections[idx].sock = SERVER_WAIT; - My_Connections[idx].our_server = i; + Conf_Server[i].conn_id = idx; - /* Hostnamen in IP aufloesen (Default bzw. im Fehlerfall: versuchen, den - * konfigurierten Text direkt als IP-Adresse zu verwenden ... */ - strlcpy( Conf_Server[My_Connections[idx].our_server].ip, Conf_Server[i].host, sizeof( Conf_Server[My_Connections[idx].our_server].ip )); + /* Resolve Hostname. If this fails, try to use it as an IP address */ + strlcpy( Conf_Server[i].ip, Conf_Server[i].host, sizeof( Conf_Server[i].ip )); strlcpy( My_Connections[idx].host, Conf_Server[i].host, sizeof( My_Connections[idx].host )); s = Resolve_Name( Conf_Server[i].host ); if( s ) @@ -1706,7 +1682,6 @@ Init_Conn_Struct( LONG Idx ) My_Connections[Idx].rdatalen = 0; My_Connections[Idx].wbuf[0] = '\0'; My_Connections[Idx].wdatalen = 0; - My_Connections[Idx].our_server = NONE; My_Connections[Idx].starttime = time( NULL ); My_Connections[Idx].lastdata = time( NULL ); My_Connections[Idx].lastping = 0; @@ -1763,7 +1738,7 @@ Read_Resolver_Result( INT r_fd ) CHAR result[HOST_LEN]; CLIENT *c; - INT len, i; + INT len, i, n; FD_CLR( r_fd, &Resolver_FDs ); @@ -1811,8 +1786,9 @@ Read_Resolver_Result( INT r_fd ) else { /* Ausgehende Verbindung (=Server): IP setzen */ - assert( My_Connections[i].our_server > NONE ); - strlcpy( Conf_Server[My_Connections[i].our_server].ip, result, sizeof( Conf_Server[My_Connections[i].our_server].ip )); + n = Conf_GetServer( i ); + if( n > NONE ) strlcpy( Conf_Server[n].ip, result, sizeof( Conf_Server[n].ip )); + else Log( LOG_ERR, "Got resolver result for non-configured server!?" ); } /* Penalty-Zeit zurueck setzen */ diff --git a/src/ngircd/conn.h b/src/ngircd/conn.h index b9812156..d2edc4fa 100644 --- a/src/ngircd/conn.h +++ b/src/ngircd/conn.h @@ -8,7 +8,7 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: conn.h,v 1.26 2002/12/18 13:50:22 alex Exp $ + * $Id: conn.h,v 1.27 2002/12/30 00:01:45 alex Exp $ * * Connection management (header) */ @@ -62,8 +62,6 @@ GLOBAL VOID Conn_ClearFlags PARAMS(( VOID )); GLOBAL INT Conn_Flag PARAMS(( CONN_ID Idx )); GLOBAL VOID Conn_SetFlag PARAMS(( CONN_ID Idx, INT Flag )); -GLOBAL VOID Conn_SetServer PARAMS(( CONN_ID Idx, INT ConfServer )); - GLOBAL CONN_ID Conn_First PARAMS(( VOID )); GLOBAL CONN_ID Conn_Next PARAMS(( CONN_ID Idx )); diff --git a/src/ngircd/irc-login.c b/src/ngircd/irc-login.c index f7224357..0e559cd0 100644 --- a/src/ngircd/irc-login.c +++ b/src/ngircd/irc-login.c @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-login.c,v 1.28 2002/12/22 23:31:21 alex Exp $"; +static char UNUSED id[] = "$Id: irc-login.c,v 1.29 2002/12/30 00:01:45 alex Exp $"; #include "imp.h" #include @@ -24,8 +24,8 @@ static char UNUSED id[] = "$Id: irc-login.c,v 1.28 2002/12/22 23:31:21 alex Exp #include "ngircd.h" #include "resolve.h" -#include "conf.h" #include "conn.h" +#include "conf.h" #include "client.h" #include "channel.h" #include "log.h" diff --git a/src/ngircd/irc-oper.c b/src/ngircd/irc-oper.c index 2a1c09c2..c784e7fa 100644 --- a/src/ngircd/irc-oper.c +++ b/src/ngircd/irc-oper.c @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-oper.c,v 1.15 2002/12/27 13:17:32 alex Exp $"; +static char UNUSED id[] = "$Id: irc-oper.c,v 1.16 2002/12/30 00:01:45 alex Exp $"; #include "imp.h" #include @@ -22,8 +22,8 @@ static char UNUSED id[] = "$Id: irc-oper.c,v 1.15 2002/12/27 13:17:32 alex Exp $ #include "ngircd.h" #include "resolve.h" -#include "conf.h" #include "conn.h" +#include "conf.h" #include "client.h" #include "channel.h" #include "irc-write.h" diff --git a/src/ngircd/irc-server.c b/src/ngircd/irc-server.c index 60f75659..ea0e5573 100644 --- a/src/ngircd/irc-server.c +++ b/src/ngircd/irc-server.c @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-server.c,v 1.28 2002/12/26 17:14:48 alex Exp $"; +static char UNUSED id[] = "$Id: irc-server.c,v 1.29 2002/12/30 00:01:45 alex Exp $"; #include "imp.h" #include @@ -23,8 +23,8 @@ static char UNUSED id[] = "$Id: irc-server.c,v 1.28 2002/12/26 17:14:48 alex Exp #include #include "resolve.h" -#include "conf.h" #include "conn.h" +#include "conf.h" #include "client.h" #include "channel.h" #include "irc-write.h" @@ -63,8 +63,8 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req ) if(( Req->argc != 2 ) && ( Req->argc != 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); /* Ist dieser Server bei uns konfiguriert? */ - for( i = 0; i < Conf_Server_Count; i++ ) if( strcasecmp( Req->argv[0], Conf_Server[i].name ) == 0 ) break; - if( i >= Conf_Server_Count ) + for( i = 0; i < MAX_SERVERS; i++ ) if( strcasecmp( Req->argv[0], Conf_Server[i].name ) == 0 ) break; + if( i >= MAX_SERVERS ) { /* Server ist nicht konfiguriert! */ Log( LOG_ERR, "Connection %d: Server \"%s\" not configured here!", Client_Conn( Client ), Req->argv[0] ); @@ -114,7 +114,7 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req ) Log( LOG_NOTICE|LOG_snotice, "Server \"%s\" registered (connection %d, 1 hop - direct link).", Client_ID( Client ), con ); Client_SetType( Client, CLIENT_SERVER ); - Conn_SetServer( con, i ); + Conf_SetServer( i, con ); #ifdef USE_ZLIB /* Kompression initialisieren, wenn erforderlich */ diff --git a/src/ngircd/ngircd.c b/src/ngircd/ngircd.c index 473ecfc6..5b71ef0a 100644 --- a/src/ngircd/ngircd.c +++ b/src/ngircd/ngircd.c @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: ngircd.c,v 1.69 2002/12/26 17:04:54 alex Exp $"; +static char UNUSED id[] = "$Id: ngircd.c,v 1.70 2002/12/30 00:01:45 alex Exp $"; #include "imp.h" #include @@ -403,7 +403,7 @@ NGIRCd_Rehash( VOID ) strcpy( old_name, Conf_ServerName ); /* Konfiguration neu lesen ... */ - Conf_Init( ); + Conf_Rehash( ); /* Alten Server-Namen wiederherstellen: dieser * kann nicht zur Laufzeit geaendert werden ... */