X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Fconn.c;h=09f726ca2bf91016d54a8d2b2c7c10029943fa68;hp=407da1a3b0837ac2bd99c16054175a4b4070e006;hb=e7e47e77a3886c258368a14a8c0bb393280aac64;hpb=69803d6ff1ac8deb95e023bda6ad2aef435dc69a diff --git a/src/ngircd/conn.c b/src/ngircd/conn.c index 407da1a3..09f726ca 100644 --- a/src/ngircd/conn.c +++ b/src/ngircd/conn.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2010 Alexander Barton + * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors. * * 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 @@ -65,6 +65,7 @@ #include "ngircd.h" #include "array.h" #include "client.h" +#include "class.h" #include "conf.h" #include "conn-ssl.h" #include "conn-zip.h" @@ -81,8 +82,8 @@ #define SERVER_WAIT (NONE - 1) #define MAX_COMMANDS 3 -#define MAX_COMMANDS_SERVER 10 -#define MAX_COMMANDS_SERVICE MAX_COMMANDS_SERVER +#define MAX_COMMANDS_SERVER_MIN 10 +#define MAX_COMMANDS_SERVICE 10 static bool Handle_Write PARAMS(( CONN_ID Idx )); @@ -369,7 +370,7 @@ cb_clientserver_ssl(int sock, short what) /** - * Initialite connecion module. + * Initialize connecion module. */ GLOBAL void Conn_Init( void ) @@ -435,12 +436,13 @@ Conn_Exit( void ) * they don't hold connections open that the main process wants to close. */ GLOBAL void -Conn_CloseAllSockets(void) +Conn_CloseAllSockets(int ExceptOf) { CONN_ID idx; for(idx = 0; idx < Pool_Size; idx++) { - if(My_Connections[idx].sock > NONE) + if(My_Connections[idx].sock > NONE && + My_Connections[idx].sock != ExceptOf) close(My_Connections[idx].sock); } } @@ -741,6 +743,9 @@ Conn_Handler(void) Check_Servers(); Check_Connections(); + /* Expire outdated class/list items */ + Class_Expire(); + /* Look for non-empty read buffers ... */ for (i = 0; i < Pool_Size; i++) { if ((My_Connections[i].sock > NONE) @@ -931,22 +936,25 @@ Conn_Write( CONN_ID Idx, char *Data, size_t Len ) assert( Data != NULL ); assert( Len > 0 ); - c = Conn_GetClient(Idx); - assert( c != NULL); - - /* Servers do get special write buffer limits, so they can generate - * all the messages that are required while peering. */ - if (Client_Type(c) == CLIENT_SERVER) - writebuf_limit = WRITEBUFFER_SLINK_LEN; - /* Is the socket still open? A previous call to Conn_Write() * may have closed the connection due to a fatal error. * In this case it is sufficient to return an error, as well. */ - if( My_Connections[Idx].sock <= NONE ) { + if (My_Connections[Idx].sock <= NONE) { LogDebug("Skipped write on closed socket (connection %d).", Idx); return false; } + /* Make sure that there still exists a CLIENT structure associated + * with this connection and check if this is a server or not: */ + c = Conn_GetClient(Idx); + if (c) { + /* Servers do get special write buffer limits, so they can + * generate all the messages that are required while peering. */ + if (Client_Type(c) == CLIENT_SERVER) + writebuf_limit = WRITEBUFFER_SLINK_LEN; + } else + LogDebug("Write on socket without client (connection %d)!?", Idx); + #ifdef ZLIB if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP )) { /* Compressed link: @@ -1009,7 +1017,7 @@ Conn_Write( CONN_ID Idx, char *Data, size_t Len ) GLOBAL void Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClient ) { - /* Close connection. Open pipes of asyncronous resolver + /* Close connection. Open pipes of asynchronous resolver * sub-processes are closed down. */ CLIENT *c; @@ -1218,6 +1226,20 @@ Conn_SyncServerStruct(void) } /* SyncServerStruct */ +/** + * Get IP address string of a connection. + * + * @param Idx Connection index. + * @return Pointer to a global buffer containing the IP address as string. + */ +GLOBAL const char * +Conn_GetIPAInfo(CONN_ID Idx) +{ + assert(Idx > NONE); + return ng_ipaddr_tostr(&My_Connections[Idx].addr); +} + + /** * Send out data of write buffer; connect new sockets. * @@ -1416,7 +1438,7 @@ New_Connection(int Sock) return -1; } - c = Client_NewLocal(new_sock, ip_str, CLIENT_UNKNOWN, false); + c = Client_NewLocal(new_sock, NULL, CLIENT_UNKNOWN, false); if (!c) { Log(LOG_ALERT, "Can't accept connection: can't create client structure!"); @@ -1567,7 +1589,7 @@ Read_Request( CONN_ID Idx ) if (!array_catb(&My_Connections[Idx].zip.rbuf, readbuf, (size_t) len)) { Log(LOG_ERR, - "Could not append recieved data to zip input buffer (connn %d): %d bytes!", + "Could not append received data to zip input buffer (connection %d): %d bytes!", Idx, len); Conn_Close(Idx, "Receive buffer space exhausted", NULL, false); @@ -1577,7 +1599,9 @@ Read_Request( CONN_ID Idx ) #endif { if (!array_catb( &My_Connections[Idx].rbuf, readbuf, len)) { - Log( LOG_ERR, "Could not append recieved data to input buffer (connn %d): %d bytes!", Idx, len ); + Log(LOG_ERR, + "Could not append received data to input buffer (connection %d): %d bytes!", + Idx, len); Conn_Close(Idx, "Receive buffer space exhausted", NULL, false ); } } @@ -1650,16 +1674,15 @@ Handle_Buffer(CONN_ID Idx) assert(c != NULL); - /* Servers do get special command limits, so they can process - * all the messages that are required while peering. */ + /* Servers get special command limits that depend on the user count */ switch (Client_Type(c)) { case CLIENT_SERVER: - /* Allow servers to send more commands in the first 10 secods + maxcmd = (int)(Client_UserCount() / 5) + + MAX_COMMANDS_SERVER_MIN; + /* Allow servers to handle even more commands while peering * to speed up server login and network synchronisation. */ - if (starttime - Client_StartTime(c) < 10) - maxcmd = MAX_COMMANDS_SERVER * 5; - else - maxcmd = MAX_COMMANDS_SERVER; + if (Conn_LastPing(Idx) == 0) + maxcmd *= 5; break; case CLIENT_SERVICE: maxcmd = MAX_COMMANDS_SERVICE; break; @@ -1826,7 +1849,7 @@ Check_Connections(void) time(NULL) - Conf_PingTimeout) { /* We need to send a PING ... */ LogDebug("Connection %d: sending PING ...", i); - My_Connections[i].lastping = time(NULL); + Conn_UpdatePing(i); Conn_WriteStr(i, "PING :%s", Client_ID(Client_ThisServer())); } @@ -2151,6 +2174,7 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events ) char *identptr; #ifdef IDENTAUTH char readbuf[HOST_LEN + 2 + CLIENT_USER_LEN]; + char *ptr; #else char readbuf[HOST_LEN + 1]; #endif @@ -2203,11 +2227,30 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events ) #ifdef IDENTAUTH ++identptr; if (*identptr) { - Log(LOG_INFO, "IDENT lookup for connection %d: \"%s\".", i, identptr); - Client_SetUser(c, identptr, true); - if (Conf_NoticeAuth) + ptr = identptr; + while (*ptr) { + if ((*ptr < '0' || *ptr > '9') && + (*ptr < 'A' || *ptr > 'Z') && + (*ptr < 'a' || *ptr > 'z')) + break; + ptr++; + } + if (*ptr) { + /* Erroneous IDENT reply */ + Log(LOG_NOTICE, + "Got invalid IDENT reply for connection %d! Ignored.", + i); + } else { + Log(LOG_INFO, + "IDENT lookup for connection %d: \"%s\".", + i, identptr); + Client_SetUser(c, identptr, true); + } + if (Conf_NoticeAuth) { (void)Conn_WriteStr(i, - "NOTICE AUTH :*** Got ident response"); + "NOTICE AUTH :*** Got %sident response", + *ptr ? "invalid " : ""); + } } else { Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i); if (Conf_NoticeAuth && Conf_Ident) @@ -2215,6 +2258,7 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events ) "NOTICE AUTH :*** No ident response"); } #endif + Class_HandleServerBans(c); } #ifdef DEBUG else Log( LOG_DEBUG, "Resolver: discarding result for already registered connection %d.", i );