X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Fconn.c;h=882251bcd80f5abf8fe776ed152647649543e4b9;hp=d36980dbd17971a5fcd61919844379e5863476c2;hb=e744936d1919269ea8d5169e850b04ce896bf6d6;hpb=a2544e496c3d2887069e646c9451ec49968125f5 diff --git a/src/ngircd/conn.c b/src/ngircd/conn.c index d36980db..882251bc 100644 --- a/src/ngircd/conn.c +++ b/src/ngircd/conn.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de) + * Copyright (c)2001-2003 by Alexander Barton (alex@barton.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -12,9 +12,11 @@ */ +#define CONN_MODULE + #include "portab.h" -static char UNUSED id[] = "$Id: conn.c,v 1.111 2002/12/30 00:01:45 alex Exp $"; +static char UNUSED id[] = "$Id: conn.c,v 1.119 2003/03/07 17:16:49 alex Exp $"; #include "imp.h" #include @@ -38,70 +40,39 @@ static char UNUSED id[] = "$Id: conn.c,v 1.111 2002/12/30 00:01:45 alex Exp $"; #endif #ifdef HAVE_STDINT_H -#include /* u.a. fuer Mac OS X */ +#include /* e.g. for Mac OS X */ #endif -#ifdef USE_ZLIB -#include +#ifdef USE_TCPWRAP +#include /* for TCP Wrappers */ #endif +#include "defines.h" +#include "resolve.h" + #include "exp.h" #include "conn.h" #include "imp.h" #include "ngircd.h" #include "client.h" -#include "resolve.h" #include "conf.h" +#include "conn-zip.h" +#include "conn-func.h" #include "log.h" #include "parse.h" #include "tool.h" +#ifdef RENDEZVOUS +#include "rendezvous.h" +#endif + #include "exp.h" #define SERVER_WAIT (NONE - 1) -#ifdef USE_ZLIB -typedef struct _ZipData -{ - 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; /* Client address */ - RES_STAT *res_stat; /* Status of resolver process, if any */ - CHAR host[HOST_LEN]; /* Hostname */ - 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; /* Compression information */ -#endif -} CONNECTION; - - LOCAL VOID Handle_Read PARAMS(( INT sock )); LOCAL BOOLEAN Handle_Write PARAMS(( CONN_ID Idx )); LOCAL VOID New_Connection PARAMS(( INT Sock )); @@ -111,24 +82,20 @@ LOCAL BOOLEAN Try_Write PARAMS(( CONN_ID Idx )); LOCAL BOOLEAN Handle_Buffer PARAMS(( CONN_ID Idx )); LOCAL VOID Check_Connections PARAMS(( VOID )); LOCAL VOID Check_Servers PARAMS(( VOID )); -LOCAL VOID Init_Conn_Struct PARAMS(( LONG Idx )); +LOCAL VOID Init_Conn_Struct PARAMS(( CONN_ID 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 )); - -#ifdef USE_ZLIB -LOCAL BOOLEAN Zip_Buffer PARAMS(( CONN_ID Idx, CHAR *Data, INT Len )); -LOCAL BOOLEAN Zip_Flush PARAMS(( CONN_ID Idx )); -LOCAL BOOLEAN Unzip_Buffer PARAMS(( CONN_ID Idx )); -#endif - +LOCAL VOID Simple_Message PARAMS(( INT Sock, CHAR *Msg )); LOCAL fd_set My_Listeners; LOCAL fd_set My_Sockets; LOCAL fd_set My_Connects; -LOCAL CONNECTION *My_Connections; -LOCAL LONG Pool_Size, WCounter; +#ifdef USE_TCPWRAP +INT allow_severity = LOG_INFO; +INT deny_severity = LOG_ERR; +#endif GLOBAL VOID @@ -152,7 +119,7 @@ Conn_Init( VOID ) Log( LOG_EMERG, "Can't allocate memory! [Conn_Init]" ); exit( 1 ); } - Log( LOG_DEBUG, "Allocted connection pool for %ld items (%ld bytes).", Pool_Size, sizeof( CONNECTION ) * Pool_Size ); + Log( LOG_DEBUG, "Allocted connection pool for %d items (%ld bytes).", Pool_Size, sizeof( CONNECTION ) * Pool_Size ); /* zu Beginn haben wir keine Verbindungen */ FD_ZERO( &My_Listeners ); @@ -179,8 +146,13 @@ Conn_Exit( VOID ) CONN_ID idx; INT i; - /* Sockets schliessen */ Log( LOG_DEBUG, "Shutting down all connections ..." ); + +#ifdef RENDEZVOUS + Rendezvous_UnregisterListeners( ); +#endif + + /* Sockets schliessen */ for( i = 0; i < Conn_MaxFD + 1; i++ ) { if( FD_ISSET( i, &My_Sockets )) @@ -221,8 +193,7 @@ Conn_Exit( VOID ) GLOBAL INT Conn_InitListeners( VOID ) { - /* Ports, auf denen der Server Verbindungen entgegennehmen - * soll, initialisieren */ + /* Initialize ports on which the server should accept connections */ INT created, i; @@ -239,10 +210,14 @@ Conn_InitListeners( VOID ) GLOBAL VOID Conn_ExitListeners( VOID ) { - /* Alle "Listen-Sockets" schliessen */ + /* Close down all listening sockets */ INT i; +#ifdef RENDEZVOUS + Rendezvous_UnregisterListeners( ); +#endif + Log( LOG_INFO, "Shutting down all listening sockets ..." ); for( i = 0; i < Conn_MaxFD + 1; i++ ) { @@ -258,13 +233,14 @@ Conn_ExitListeners( VOID ) GLOBAL BOOLEAN Conn_NewListener( CONST UINT Port ) { - /* Neuen Listen-Socket erzeugen: der Server wartet dann auf - * dem angegebenen Port auf Verbindungen. Kann der Listen- - * Socket nicht erteugt werden, so wird NULL geliefert.*/ + /* Create new listening socket on specified port */ struct sockaddr_in addr; INT sock; - +#ifdef RENDEZVOUS + CHAR name[CLIENT_ID_LEN], *info; +#endif + /* Server-"Listen"-Socket initialisieren */ memset( &addr, 0, sizeof( addr )); addr.sin_family = AF_INET; @@ -305,6 +281,34 @@ Conn_NewListener( CONST UINT Port ) Log( LOG_INFO, "Now listening on port %d (socket %d).", Port, sock ); +#ifdef RENDEZVOUS + /* Get best server description text */ + if( ! Conf_ServerInfo[0] ) info = Conf_ServerName; + else + { + /* Use server info string */ + info = NULL; + if( Conf_ServerInfo[0] == '[' ) + { + /* Cut off leading hostname part in "[]" */ + info = strchr( Conf_ServerInfo, ']' ); + if( info ) + { + info++; + while( *info == ' ' ) info++; + } + } + if( ! info ) info = Conf_ServerInfo; + } + + /* Add port number to description if non-standard */ + if( Port != 6667 ) snprintf( name, sizeof( name ), "%s (port %u)", info, Port ); + else strlcpy( name, info, sizeof( name )); + + /* Register service */ + Rendezvous_Register( name, RENDEZVOUS_TYPE, Port ); +#endif + return TRUE; } /* Conn_NewListener */ @@ -327,7 +331,7 @@ Conn_Handler( VOID ) fd_set read_sockets, write_sockets; struct timeval tv; time_t start, t; - LONG i, idx; + CONN_ID i, idx; BOOLEAN timeout; start = time( NULL ); @@ -335,6 +339,10 @@ Conn_Handler( VOID ) { timeout = TRUE; +#ifdef RENDEZVOUS + Rendezvous_Handler( ); +#endif + /* Should the configuration be reloaded? */ if( NGIRCd_SignalRehash ) NGIRCd_Rehash( ); @@ -366,6 +374,7 @@ Conn_Handler( VOID ) FD_SET( My_Connections[i].sock, &write_sockets ); } } + /* Sockets mit im Aufbau befindlichen ausgehenden Verbindungen suchen */ for( i = 0; i < Pool_Size; i++ ) { @@ -391,7 +400,6 @@ 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++ ) @@ -579,6 +587,17 @@ Conn_Close( CONN_ID Idx, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN InformClient ) assert( Idx > NONE ); assert( My_Connections[Idx].sock > NONE ); + /* Is this link already shutting down? */ + if( My_Connections[Idx].options & CONN_ISCLOSING ) + { + /* Conn_Close() has been called recursively for this link; + * probabe reason: Try_Write() failed -- see below. */ + return; + } + + /* Mark link as "closing" */ + My_Connections[Idx].options |= CONN_ISCLOSING; + /* Search client, if any */ c = Client_GetFromConn( Idx ); @@ -600,7 +619,7 @@ Conn_Close( CONN_ID Idx, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN InformClient ) } /* Try to write out the write buffer */ - Try_Write( Idx ); + (VOID)Try_Write( Idx ); /* Shut down socket */ if( close( My_Connections[Idx].sock ) != 0 ) @@ -664,320 +683,6 @@ Conn_Close( CONN_ID Idx, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN InformClient ) } /* Conn_Close */ -GLOBAL VOID -Conn_UpdateIdle( CONN_ID Idx ) -{ - /* Idle-Timer zuruecksetzen */ - - assert( Idx > NONE ); - My_Connections[Idx].lastprivmsg = time( NULL ); -} - - -GLOBAL time_t -Conn_GetIdle( CONN_ID Idx ) -{ - /* Idle-Time einer Verbindung liefern (in Sekunden) */ - - assert( Idx > NONE ); - return time( NULL ) - My_Connections[Idx].lastprivmsg; -} /* Conn_GetIdle */ - - -GLOBAL time_t -Conn_LastPing( CONN_ID Idx ) -{ - /* Zeitpunkt des letzten PING liefern */ - - assert( Idx > NONE ); - return My_Connections[Idx].lastping; -} /* Conn_LastPing */ - - -GLOBAL VOID -Conn_SetPenalty( CONN_ID Idx, time_t Seconds ) -{ - /* Penalty-Delay fuer eine Verbindung (in Sekunden) setzen; - * waehrend dieser Zeit wird der entsprechende Socket vom Server - * bei Lese-Operationen komplett ignoriert. Der Delay kann mit - * dieser Funktion nur erhoeht, nicht aber verringert werden. */ - - time_t t; - - assert( Idx > NONE ); - assert( Seconds >= 0 ); - - t = time( NULL ) + Seconds; - if( t > My_Connections[Idx].delaytime ) My_Connections[Idx].delaytime = t; -} /* 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_SetOption( CONN_ID Idx, INT Option ) -{ - /* Option fuer Verbindung setzen. - * Initial sind alle Optionen _nicht_ gesetzt. */ - - assert( Idx > NONE ); - assert( Option != 0 ); - - My_Connections[Idx].options |= Option; -} /* Conn_SetOption */ - - -GLOBAL VOID -Conn_UnsetOption( CONN_ID Idx, INT Option ) -{ - /* Option fuer Verbindung loeschen */ - - assert( Idx > NONE ); - assert( Option != 0 ); - - My_Connections[Idx].options &= ~Option; -} /* Conn_UnsetOption */ - - -GLOBAL INT -Conn_Options( CONN_ID Idx ) -{ - assert( Idx > NONE ); - return My_Connections[Idx].options; -} /* Conn_Options */ - - -#ifdef USE_ZLIB - -GLOBAL BOOLEAN -Conn_InitZip( CONN_ID Idx ) -{ - /* Kompression fuer Link initialisieren */ - - assert( Idx > NONE ); - - My_Connections[Idx].zip.in.avail_in = 0; - My_Connections[Idx].zip.in.total_in = 0; - My_Connections[Idx].zip.in.total_out = 0; - My_Connections[Idx].zip.in.zalloc = NULL; - My_Connections[Idx].zip.in.zfree = NULL; - My_Connections[Idx].zip.in.data_type = Z_ASCII; - - if( inflateInit( &My_Connections[Idx].zip.in ) != Z_OK ) - { - /* Fehler! */ - Log( LOG_ALERT, "Can't initialize compression on connection %d (zlib inflate)!", Idx ); - return FALSE; - } - - My_Connections[Idx].zip.out.total_in = 0; - My_Connections[Idx].zip.out.total_in = 0; - My_Connections[Idx].zip.out.zalloc = NULL; - My_Connections[Idx].zip.out.zfree = NULL; - My_Connections[Idx].zip.out.data_type = Z_ASCII; - - if( deflateInit( &My_Connections[Idx].zip.out, Z_DEFAULT_COMPRESSION ) != Z_OK ) - { - /* Fehler! */ - Log( LOG_ALERT, "Can't initialize compression on connection %d (zlib deflate)!", Idx ); - return FALSE; - } - - My_Connections[Idx].zip.bytes_in = My_Connections[Idx].bytes_in; - My_Connections[Idx].zip.bytes_out = My_Connections[Idx].bytes_out; - - Log( LOG_INFO, "Enabled link compression (zlib) on connection %d.", Idx ); - Conn_SetOption( Idx, CONN_ZIP ); - - return TRUE; -} /* Conn_InitZip */ - - -GLOBAL LONG -Conn_SendBytesZip( CONN_ID Idx ) -{ - /* Anzahl gesendeter Bytes (komprimiert!) liefern */ - - assert( Idx > NONE ); - return My_Connections[Idx].zip.bytes_out; -} /* Conn_SendBytesZip */ - - -GLOBAL LONG -Conn_RecvBytesZip( CONN_ID Idx ) -{ - /* Anzahl gesendeter Bytes (komprimiert!) liefern */ - - assert( Idx > NONE ); - return My_Connections[Idx].zip.bytes_in; -} /* Conn_RecvBytesZip */ - -#endif - - -GLOBAL time_t -Conn_StartTime( CONN_ID Idx ) -{ - /* Zeitpunkt des Link-Starts liefern (in Sekunden) */ - - assert( Idx > NONE ); - return My_Connections[Idx].starttime; -} /* Conn_Uptime */ - - -GLOBAL INT -Conn_SendQ( CONN_ID Idx ) -{ - /* Laenge der Daten im Schreibbuffer liefern */ - - assert( Idx > NONE ); -#ifdef USE_ZLIB - if( My_Connections[Idx].options & CONN_ZIP ) return My_Connections[Idx].zip.wdatalen; - else -#endif - return My_Connections[Idx].wdatalen; -} /* Conn_SendQ */ - - -GLOBAL LONG -Conn_SendMsg( CONN_ID Idx ) -{ - /* Anzahl gesendeter Nachrichten liefern */ - - assert( Idx > NONE ); - return My_Connections[Idx].msg_out; -} /* Conn_SendMsg */ - - -GLOBAL LONG -Conn_SendBytes( CONN_ID Idx ) -{ - /* Anzahl gesendeter Bytes (unkomprimiert) liefern */ - - assert( Idx > NONE ); - return My_Connections[Idx].bytes_out; -} /* Conn_SendBytes */ - - -GLOBAL INT -Conn_RecvQ( CONN_ID Idx ) -{ - /* Laenge der Daten im Lesebuffer liefern */ - - assert( Idx > NONE ); -#ifdef USE_ZLIB - if( My_Connections[Idx].options & CONN_ZIP ) return My_Connections[Idx].zip.rdatalen; - else -#endif - return My_Connections[Idx].rdatalen; -} /* Conn_RecvQ */ - - -GLOBAL LONG -Conn_RecvMsg( CONN_ID Idx ) -{ - /* Anzahl empfangener Nachrichten liefern */ - - assert( Idx > NONE ); - return My_Connections[Idx].msg_in; -} /* Conn_RecvMsg */ - - -GLOBAL LONG -Conn_RecvBytes( CONN_ID Idx ) -{ - /* Anzahl empfangener Bytes (unkomprimiert) liefern */ - - assert( Idx > NONE ); - return My_Connections[Idx].bytes_in; -} /* Conn_RecvBytes */ - - -GLOBAL VOID -Conn_ResetWCounter( VOID ) -{ - WCounter = 0; -} /* Conn_ResetWCounter */ - - -GLOBAL LONG -Conn_WCounter( VOID ) -{ - return WCounter; -} /* Conn_WCounter */ - - LOCAL BOOLEAN Try_Write( CONN_ID Idx ) { @@ -1062,6 +767,7 @@ Handle_Write( CONN_ID Idx ) /* Daten aus Schreibpuffer versenden bzw. Connection aufbauen */ INT len, res, err; + CLIENT *c; assert( Idx > NONE ); assert( My_Connections[Idx].sock > NONE ); @@ -1085,8 +791,10 @@ Handle_Write( CONN_ID Idx ) 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[Conf_GetServer( Idx )].port, Idx, strerror( err )); - /* Socket etc. pp. aufraeumen */ + /* Clean up socket, connection and client structures */ FD_CLR( My_Connections[Idx].sock, &My_Sockets ); + c = Client_GetFromConn( Idx ); + if( c ) Client_DestroyNow( c ); close( My_Connections[Idx].sock ); Init_Conn_Struct( Idx ); @@ -1138,6 +846,9 @@ New_Connection( INT Sock ) /* Neue Client-Verbindung von Listen-Socket annehmen und * CLIENT-Struktur anlegen. */ +#ifdef USE_TCPWRAP + struct request_info req; +#endif struct sockaddr_in new_addr; INT new_sock, new_sock_len; RES_STAT *s; @@ -1156,6 +867,19 @@ New_Connection( INT Sock ) Log( LOG_CRIT, "Can't accept connection: %s!", strerror( errno )); return; } + +#ifdef USE_TCPWRAP + /* Validate socket using TCP Wrappers */ + request_init( &req, RQ_DAEMON, PACKAGE, RQ_FILE, new_sock, RQ_CLIENT_SIN, &new_addr, NULL ); + if( ! hosts_access( &req )) + { + /* Access denied! */ + Log( deny_severity, "Refused connection from %s (by TCP Wrappers)!", inet_ntoa( new_addr.sin_addr )); + Simple_Message( new_sock, "ERROR :Connection refused" ); + close( new_sock ); + return; + } +#endif /* Socket initialisieren */ Init_Socket( new_sock ); @@ -1176,11 +900,19 @@ New_Connection( INT Sock ) { /* Mehr Verbindungen duerfen wir leider nicht mehr annehmen ... */ Log( LOG_ALERT, "Can't accept connection: limit (%d) reached!", Pool_Size ); + Simple_Message( new_sock, "ERROR :Connection limit reached" ); close( new_sock ); return; } if( new_size > Conf_MaxConnections ) new_size = Conf_MaxConnections; } + if( new_size < Pool_Size ) + { + Log( LOG_ALERT, "Can't accespt connection: limit (%d) reached -- overflow!", Pool_Size ); + Simple_Message( new_sock, "ERROR :Connection limit reached" ); + close( new_sock ); + return; + } /* zunaechst realloc() versuchen; wenn das scheitert, malloc() versuchen * und Daten ggf. "haendisch" umkopieren. (Haesslich! Eine wirklich @@ -1194,6 +926,7 @@ New_Connection( INT Sock ) { /* Offenbar steht kein weiterer Sepeicher zur Verfuegung :-( */ Log( LOG_EMERG, "Can't allocate memory! [New_Connection]" ); + Simple_Message( new_sock, "ERROR: Internal error" ); close( new_sock ); return; } @@ -1221,6 +954,7 @@ New_Connection( INT Sock ) if( ! c ) { Log( LOG_ALERT, "Can't accept connection: can't create client structure!" ); + Simple_Message( new_sock, "ERROR :Internal error" ); close( new_sock ); return; } @@ -1469,7 +1203,7 @@ Check_Connections( VOID ) * auch das nicht "hilft", Client disconnectieren. */ CLIENT *c; - LONG i; + CONN_ID i; for( i = 0; i < Pool_Size; i++ ) { @@ -1520,9 +1254,6 @@ Check_Servers( VOID ) CONN_ID idx; INT i, n; - /* Don't connect in "passive mode" */ - if( NGIRCd_Passive ) return; - /* Serach all connections, are there results from the resolver? */ for( idx = 0; idx < Pool_Size; idx++ ) { @@ -1535,8 +1266,8 @@ Check_Servers( VOID ) /* 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; + /* Valid outgoing server which isn't already connected or disabled? */ + if(( ! Conf_Server[i].host[0] ) || ( ! Conf_Server[i].port > 0 ) || ( Conf_Server[i].conn_id > NONE ) || ( Conf_Server[i].flags & CONF_SFLAG_DISABLED )) continue; /* Is there already a connection in this group? */ if( Conf_Server[i].group > NONE ) @@ -1671,7 +1402,7 @@ New_Server( INT Server, CONN_ID Idx ) LOCAL VOID -Init_Conn_Struct( LONG Idx ) +Init_Conn_Struct( CONN_ID Idx ) { /* Connection-Struktur initialisieren */ @@ -1796,115 +1527,19 @@ Read_Resolver_Result( INT r_fd ) } /* Read_Resolver_Result */ -#ifdef USE_ZLIB - -LOCAL BOOLEAN -Zip_Buffer( CONN_ID Idx, CHAR *Data, INT Len ) -{ - /* Daten zum Komprimieren im "Kompressions-Puffer" sammeln. - * Es wird TRUE bei Erfolg, sonst FALSE geliefert. */ - - assert( Idx > NONE ); - assert( Data != NULL ); - assert( Len > 0 ); - - /* Ist noch Platz im Kompressions-Puffer? */ - if( ZWRITEBUFFER_LEN - My_Connections[Idx].zip.wdatalen < Len + 50 ) - { - /* Nein! Puffer zunaechst leeren ...*/ - if( ! Zip_Flush( Idx )) return FALSE; - } - - /* Daten kopieren */ - memmove( My_Connections[Idx].zip.wbuf + My_Connections[Idx].zip.wdatalen, Data, Len ); - My_Connections[Idx].zip.wdatalen += Len; - - return TRUE; -} /* Zip_Buffer */ - - -LOCAL BOOLEAN -Zip_Flush( CONN_ID Idx ) -{ - /* Daten komprimieren und in Schreibpuffer kopieren. - * Es wird TRUE bei Erfolg, sonst FALSE geliefert. */ - - INT result, out_len; - z_stream *out; - - out = &My_Connections[Idx].zip.out; - - out->next_in = My_Connections[Idx].zip.wbuf; - out->avail_in = My_Connections[Idx].zip.wdatalen; - out->next_out = My_Connections[Idx].wbuf + My_Connections[Idx].wdatalen; - out->avail_out = WRITEBUFFER_LEN - My_Connections[Idx].wdatalen; - - result = deflate( out, Z_SYNC_FLUSH ); - if(( result != Z_OK ) || ( out->avail_in > 0 )) - { - Log( LOG_ALERT, "Compression error: code %d!?", result ); - Conn_Close( Idx, "Compression error!", NULL, FALSE ); - return FALSE; - } - - out_len = WRITEBUFFER_LEN - My_Connections[Idx].wdatalen - out->avail_out; - My_Connections[Idx].wdatalen += out_len; - My_Connections[Idx].bytes_out += out_len; - My_Connections[Idx].zip.bytes_out += My_Connections[Idx].zip.wdatalen; - My_Connections[Idx].zip.wdatalen = 0; - - return TRUE; -} /* Zip_Flush */ - - -LOCAL BOOLEAN -Unzip_Buffer( CONN_ID Idx ) +LOCAL VOID +Simple_Message( INT Sock, CHAR *Msg ) { - /* Daten entpacken und in Lesepuffer kopieren. Bei Fehlern - * wird FALSE geliefert, ansonsten TRUE. Der Fall, dass keine - * Daten mehr zu entpacken sind, ist _kein_ Fehler! */ - - INT result, in_len, out_len; - z_stream *in; - - assert( Idx > NONE ); - - if( My_Connections[Idx].zip.rdatalen <= 0 ) return TRUE; - - in = &My_Connections[Idx].zip.in; - - in->next_in = My_Connections[Idx].zip.rbuf; - in->avail_in = My_Connections[Idx].zip.rdatalen; - in->next_out = My_Connections[Idx].rbuf + My_Connections[Idx].rdatalen; - in->avail_out = READBUFFER_LEN - My_Connections[Idx].rdatalen - 1; - - result = inflate( in, Z_SYNC_FLUSH ); - if( result != Z_OK ) - { - 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; - } - - in_len = My_Connections[Idx].zip.rdatalen - in->avail_in; - out_len = READBUFFER_LEN - My_Connections[Idx].rdatalen - 1 - in->avail_out; - My_Connections[Idx].rdatalen += out_len; - - if( in->avail_in > 0 ) - { - /* es konnten nicht alle Daten entpackt werden, vermutlich war - * im Ziel-Puffer kein Platz mehr. Umkopieren ... */ - My_Connections[Idx].zip.rdatalen -= in_len; - memmove( My_Connections[Idx].zip.rbuf, My_Connections[Idx].zip.rbuf + in_len, My_Connections[Idx].zip.rdatalen ); - } - else My_Connections[Idx].zip.rdatalen = 0; - My_Connections[Idx].zip.bytes_in += out_len; - - return TRUE; -} /* Unzip_Buffer */ + /* Write "simple" message to socket, without using compression + * or even the connection write buffers. Used e.g. for error + * messages by New_Connection(). */ + assert( Sock > NONE ); + assert( Msg != NULL ); -#endif + (VOID)send( Sock, Msg, strlen( Msg ), 0 ); + (VOID)send( Sock, "\r\n", 2, 0 ); +} /* Simple_Error */ /* -eof- */