diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ngircd/client.c | 8 | ||||
| -rw-r--r-- | src/ngircd/conf.c | 171 | ||||
| -rw-r--r-- | src/ngircd/conn-func.c | 2 | ||||
| -rw-r--r-- | src/ngircd/conn.c | 58 | ||||
| -rw-r--r-- | src/ngircd/conn.h | 14 | ||||
| -rw-r--r-- | src/ngircd/irc-oper.c | 9 | ||||
| -rw-r--r-- | src/ngircd/ngircd.c | 1 | ||||
| -rw-r--r-- | src/portab/portab.h | 4 |
8 files changed, 74 insertions, 193 deletions
diff --git a/src/ngircd/client.c b/src/ngircd/client.c index a453312c..67c02604 100644 --- a/src/ngircd/client.c +++ b/src/ngircd/client.c @@ -337,9 +337,11 @@ Client_SetHostname( CLIENT *Client, const char *Hostname ) assert(Client != NULL); assert(Hostname != NULL); - /* Only cloak the hostmask if it has not yet been cloaked (the period - * indicates it's still an IP address). */ - if (Conf_CloakHost[0] && strchr(Client->host, '.')) { + /* Only cloak the hostmask if it has not yet been cloaked. + * The period or colon indicates it's still an IP address. + * An empty string means a rDNS lookup did not happen (yet). */ + if (Conf_CloakHost[0] && (!Client->host[0] || strchr(Client->host, '.') + || strchr(Client->host, ':'))) { char cloak[GETID_LEN]; strlcpy(cloak, Hostname, GETID_LEN); diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c index 02ed1f39..a58ac26e 100644 --- a/src/ngircd/conf.c +++ b/src/ngircd/conf.c @@ -903,7 +903,7 @@ Read_Config(bool TestOnly, bool IsStarting) FILE *fd; DIR *dh; - Log(LOG_INFO, "Using configuration file \"%s\" ...", NGIRCd_ConfFile); + Config_Error(LOG_INFO, "Using configuration file \"%s\" ...", NGIRCd_ConfFile); /* Open configuration file */ fd = fopen( NGIRCd_ConfFile, "r" ); @@ -1290,116 +1290,6 @@ WarnPAM(const char UNUSED *File, int UNUSED Line) #endif } -/** - * Handle legacy "NoXXX" options in [GLOBAL] section. - * - * TODO: This function and support for "NoXXX" could be removed starting - * with ngIRCd release 19 (one release after marking it "deprecated"). - * - * @param Var Variable name. - * @param Arg Argument string. - * @returns true if a NoXXX option has been processed; false otherwise. - */ -static bool -CheckLegacyNoOption(const char *Var, const char *Arg) -{ - if(strcasecmp(Var, "NoDNS") == 0) { - Conf_DNS = !Check_ArgIsTrue( Arg ); - return true; - } - if (strcasecmp(Var, "NoIdent") == 0) { - Conf_Ident = !Check_ArgIsTrue(Arg); - return true; - } - if(strcasecmp(Var, "NoPAM") == 0) { - Conf_PAM = !Check_ArgIsTrue(Arg); - return true; - } - return false; -} - -/** - * Handle deprecated legacy options in [GLOBAL] section. - * - * TODO: This function and support for these options in the [Global] section - * could be removed starting with ngIRCd release 19 (one release after - * marking it "deprecated"). - * - * @param Var Variable name. - * @param Arg Argument string. - * @returns true if a legacy option has been processed; false otherwise. - */ -static const char* -CheckLegacyGlobalOption(const char *File, int Line, char *Var, char *Arg) -{ - if (strcasecmp(Var, "AllowRemoteOper") == 0 - || strcasecmp(Var, "ChrootDir") == 0 - || strcasecmp(Var, "ConnectIPv4") == 0 - || strcasecmp(Var, "ConnectIPv6") == 0 - || strcasecmp(Var, "OperCanUseMode") == 0 - || strcasecmp(Var, "OperChanPAutoOp") == 0 - || strcasecmp(Var, "OperServerMode") == 0 - || strcasecmp(Var, "PredefChannelsOnly") == 0 - || strcasecmp(Var, "SyslogFacility") == 0 - || strcasecmp(Var, "WebircPassword") == 0) { - Handle_OPTIONS(File, Line, Var, Arg); - return "[Options]"; - } - if (strcasecmp(Var, "ConnectRetry") == 0 - || strcasecmp(Var, "IdleTimeout") == 0 - || strcasecmp(Var, "MaxConnections") == 0 - || strcasecmp(Var, "MaxConnectionsIP") == 0 - || strcasecmp(Var, "MaxJoins") == 0 - || strcasecmp(Var, "MaxNickLength") == 0 - || strcasecmp(Var, "PingTimeout") == 0 - || strcasecmp(Var, "PongTimeout") == 0) { - Handle_LIMITS(File, Line, Var, Arg); - return "[Limits]"; - } -#ifdef SSL_SUPPORT - if (strcasecmp(Var, "SSLCertFile") == 0 - || strcasecmp(Var, "SSLDHFile") == 0 - || strcasecmp(Var, "SSLKeyFile") == 0 - || strcasecmp(Var, "SSLKeyFilePassword") == 0 - || strcasecmp(Var, "SSLPorts") == 0) { - Handle_SSL(File, Line, Var + 3, Arg); - return "[SSL]"; - } -#endif - - return NULL; -} - -/** - * Strip "no" prefix of a string. - * - * TODO: This function and support for "NoXXX" should be removed starting - * with ngIRCd release 19! (One release after marking it "deprecated"). - * - * @param str Pointer to input string starting with "no". - * @returns New pointer to string without "no" prefix. - */ -static const char * -NoNo(const char *str) -{ - assert(strncasecmp("no", str, 2) == 0 && str[2]); - return str + 2; -} - -/** - * Invert "boolean" string. - * - * TODO: This function and support for "NoXXX" should be removed starting - * with ngIRCd release 19! (One release after marking it "deprecated"). - * - * @param arg "Boolean" input string. - * @returns Pointer to inverted "boolean string". - */ -static const char * -InvertArg(const char *arg) -{ - return yesno_to_str(!Check_ArgIsTrue(arg)); -} /** * Handle variable in [Global] configuration section. @@ -1414,7 +1304,6 @@ Handle_GLOBAL(const char *File, int Line, char *Var, char *Arg ) struct passwd *pwd; struct group *grp; size_t len; - const char *section; char *ptr; assert(File != NULL); @@ -1554,36 +1443,6 @@ Handle_GLOBAL(const char *File, int Line, char *Var, char *Arg ) return; } - if (CheckLegacyNoOption(Var, Arg)) { - /* TODO: This function and support for "NoXXX" could be - * be removed starting with ngIRCd release 19 (one release - * after marking it "deprecated"). */ - Config_Error(LOG_WARNING, - "%s, line %d (section \"Global\"): \"No\"-Prefix is deprecated, use \"%s = %s\" in [Options] section!", - File, Line, NoNo(Var), InvertArg(Arg)); - if (strcasecmp(Var, "NoIdent") == 0) - WarnIdent(File, Line); - else if (strcasecmp(Var, "NoPam") == 0) - WarnPAM(File, Line); - return; - } - if ((section = CheckLegacyGlobalOption(File, Line, Var, Arg))) { - /** TODO: This function and support for these options in the - * [Global] section could be removed starting with ngIRCd - * release 19 (one release after marking it "deprecated"). */ - if (strncasecmp(Var, "SSL", 3) == 0) { - Config_Error(LOG_WARNING, - "%s, line %d (section \"Global\"): \"%s\" is deprecated here, move it to %s and rename to \"%s\"!", - File, Line, Var, section, - Var + 3); - } else { - Config_Error(LOG_WARNING, - "%s, line %d (section \"Global\"): \"%s\" is deprecated here, move it to %s!", - File, Line, Var, section); - } - return; - } - Config_Error_Section(File, Line, Var, "Global"); } @@ -1808,18 +1667,6 @@ Handle_OPTIONS(const char *File, int Line, char *Var, char *Arg) Conf_MorePrivacy = Check_ArgIsTrue(Arg); return; } - if (strcasecmp(Var, "NoticeAuth") == 0) { - /* - * TODO: This section and support for "NoticeAuth" variable - * could be removed starting with ngIRCd release 24 (one - * release after marking it "deprecated") ... - */ - Config_Error(LOG_WARNING, - "%s, line %d (section \"Options\"): \"%s\" is deprecated, please use \"NoticeBeforeRegistration\"!", - File, Line, Var); - Conf_NoticeBeforeRegistration = Check_ArgIsTrue(Arg); - return; - } if (strcasecmp(Var, "NoticeBeforeRegistration") == 0) { Conf_NoticeBeforeRegistration = Check_ArgIsTrue(Arg); return; @@ -1851,22 +1698,6 @@ Handle_OPTIONS(const char *File, int Line, char *Var, char *Arg) Config_Error_TooLong(File, Line, Var); return; } - if (strcasecmp(Var, "PredefChannelsOnly") == 0) { - /* - * TODO: This section and support for "PredefChannelsOnly" - * could be removed starting with ngIRCd release 22 (one - * release after marking it "deprecated") ... - */ - Config_Error(LOG_WARNING, - "%s, line %d (section \"Options\"): \"%s\" is deprecated, please use \"AllowedChannelTypes\"!", - File, Line, Var); - if (Check_ArgIsTrue(Arg)) - Conf_AllowedChannelTypes[0] = '\0'; - else - strlcpy(Conf_AllowedChannelTypes, CHANTYPES, - sizeof(Conf_AllowedChannelTypes)); - return; - } #ifndef STRICT_RFC if (strcasecmp(Var, "RequireAuthPing") == 0) { Conf_AuthPing = Check_ArgIsTrue(Arg); diff --git a/src/ngircd/conn-func.c b/src/ngircd/conn-func.c index 72d38b86..4a2d32d6 100644 --- a/src/ngircd/conn-func.c +++ b/src/ngircd/conn-func.c @@ -51,7 +51,7 @@ GLOBAL void Conn_UpdatePing(CONN_ID Idx) { assert(Idx > NONE); - My_Connections[Idx].lastping = time(NULL); + My_Connections[Idx].lastping = My_Connections[Idx].lastdata = time(NULL); } /* diff --git a/src/ngircd/conn.c b/src/ngircd/conn.c index f62e9675..c304fdb5 100644 --- a/src/ngircd/conn.c +++ b/src/ngircd/conn.c @@ -10,6 +10,7 @@ */ #define CONN_MODULE +#define CONN_MODULE_GLOBAL_INIT #include "portab.h" @@ -659,12 +660,14 @@ Conn_Handler(void) size_t wdatalen; struct timeval tv; time_t t; + bool command_available; Log(LOG_NOTICE, "Server \"%s\" (on \"%s\") ready.", Client_ID(Client_ThisServer()), Client_Hostname(Client_ThisServer())); while (!NGIRCd_SignalQuit && !NGIRCd_SignalRestart) { t = time(NULL); + command_available = false; /* Check configured servers and established links */ Check_Servers(); @@ -733,16 +736,31 @@ Conn_Handler(void) continue; } + if (array_bytes(&My_Connections[i].rbuf) >= COMMAND_LEN) { + /* There is still more data in the read buffer + * than a single valid command can get long: + * so either there is a complete command, or + * invalid data. Therefore don't try to read in + * even more data from the network but wait for + * this command(s) to be handled first! */ + io_event_del(My_Connections[i].sock, + IO_WANTREAD); + command_available = true; + continue; + } + io_event_add(My_Connections[i].sock, IO_WANTREAD); } - /* Set the timeout for reading from the network to 1 second, - * which is the granularity with witch we handle "penalty - * times" for example. + /* Don't wait for data when there is still at least one command + * available in a read buffer which can be handled immediately; + * set the timeout for reading from the network to 1 second + * otherwise, which is the granularity with witch we handle + * "penalty times" for example. * Note: tv_sec/usec are undefined(!) after io_dispatch() * returns, so we have to set it before each call to it! */ tv.tv_usec = 0; - tv.tv_sec = 1; + tv.tv_sec = command_available ? 0 : 1; /* Wait for activity ... */ i = io_dispatch(&tv); @@ -1271,6 +1289,9 @@ Handle_Write( CONN_ID Idx ) if (errno == EAGAIN || errno == EINTR) return true; + /* Log write errors but do not close the connection yet. + * Calling Conn_Close() now could result in too many recursive calls. + */ if (!Conn_OPTION_ISSET(&My_Connections[Idx], CONN_ISCLOSING)) Log(LOG_ERR, "Write error on connection %d (socket %d): %s!", @@ -1278,7 +1299,7 @@ Handle_Write( CONN_ID Idx ) else LogDebug("Recursive write error on connection %d (socket %d): %s!", Idx, My_Connections[Idx].sock, strerror(errno)); - Conn_Close(Idx, "Write error", NULL, false); + return false; } @@ -1539,16 +1560,21 @@ Socket2Index( int Sock ) * @param Idx Connection index. */ static void -Read_Request( CONN_ID Idx ) +Read_Request(CONN_ID Idx) { ssize_t len; static const unsigned int maxbps = COMMAND_LEN / 2; char readbuf[READBUFFER_LEN]; time_t t; CLIENT *c; - assert( Idx > NONE ); - assert( My_Connections[Idx].sock > NONE ); + assert(Idx > NONE); + assert(My_Connections[Idx].sock > NONE); + + /* Check if the read buffer is "full". Basically this shouldn't happen + * here, because as long as there possibly are commands in the read + * buffer (buffer usage > COMMAND_LEN), the socket shouldn't be + * scheduled for reading in Conn_Handler() at all ... */ #ifdef ZLIB if ((array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN) || (array_bytes(&My_Connections[Idx].zip.rbuf) >= READBUFFER_LEN)) @@ -1556,7 +1582,6 @@ Read_Request( CONN_ID Idx ) if (array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN) #endif { - /* Read buffer is full */ Log(LOG_ERR, "Receive buffer space exhausted (connection %d): %d/%d bytes", Idx, array_bytes(&My_Connections[Idx].rbuf), READBUFFER_LEN); @@ -1564,12 +1589,14 @@ Read_Request( CONN_ID Idx ) return; } + /* Now read new data from the network, up to READBUFFER_LEN bytes ... */ #ifdef SSL_SUPPORT if (Conn_OPTION_ISSET(&My_Connections[Idx], CONN_SSL)) - len = ConnSSL_Read( &My_Connections[Idx], readbuf, sizeof(readbuf)); + len = ConnSSL_Read(&My_Connections[Idx], readbuf, sizeof(readbuf)); else #endif - len = read(My_Connections[Idx].sock, readbuf, sizeof(readbuf)); + len = read(My_Connections[Idx].sock, readbuf, sizeof(readbuf)); + if (len == 0) { LogDebug("Client \"%s:%u\" is closing connection %d ...", My_Connections[Idx].host, @@ -1579,13 +1606,20 @@ Read_Request( CONN_ID Idx ) } if (len < 0) { - if( errno == EAGAIN ) return; + if (errno == EAGAIN) + return; + 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; } + + /* Now append the newly received data to the connection buffer. + * NOTE: This can lead to connection read buffers being bigger(!) than + * READBUFFER_LEN bytes, as we add up to READBUFFER_LEN new bytes to a + * buffer possibly being "almost" READBUFFER_LEN bytes already! */ #ifdef ZLIB if (Conn_OPTION_ISSET(&My_Connections[Idx], CONN_ZIP)) { if (!array_catb(&My_Connections[Idx].zip.rbuf, readbuf, diff --git a/src/ngircd/conn.h b/src/ngircd/conn.h index c642541f..869477f0 100644 --- a/src/ngircd/conn.h +++ b/src/ngircd/conn.h @@ -105,9 +105,17 @@ typedef struct _Connection #endif } CONNECTION; -GLOBAL CONNECTION *My_Connections; -GLOBAL CONN_ID Pool_Size; -GLOBAL long WCounter; + +#ifdef CONN_MODULE_GLOBAL_INIT +CONNECTION *My_Connections; +CONN_ID Pool_Size; +long WCounter; +#else +extern CONNECTION *My_Connections; +extern CONN_ID Pool_Size; +extern long WCounter; +#endif + #define CONNECTION2ID(x) (long)(x - My_Connections) diff --git a/src/ngircd/irc-oper.c b/src/ngircd/irc-oper.c index e877213e..ae333b10 100644 --- a/src/ngircd/irc-oper.c +++ b/src/ngircd/irc-oper.c @@ -447,10 +447,11 @@ IRC_xLINE(CLIENT *Client, REQUEST *Req) if (Class_AddMask(class, Req->argv[0], timeout, Req->argv[2])) { - Log(LOG_NOTICE|LOG_snotice, - "\"%s\" added \"%s\" to %c-Line list: \"%s\" (%ld seconds).", - Client_Mask(from), Req->argv[0], class_c, - Req->argv[2], atol(Req->argv[1])); + if (Client_Type(from) != CLIENT_SERVER) + Log(LOG_NOTICE|LOG_snotice, + "\"%s\" added \"%s\" to %c-Line list: \"%s\" (%ld seconds).", + Client_Mask(from), Req->argv[0], class_c, + Req->argv[2], atol(Req->argv[1])); if (class == CLASS_GLINE) { /* Inform other servers */ IRC_WriteStrServersPrefix(Client, from, diff --git a/src/ngircd/ngircd.c b/src/ngircd/ngircd.c index 7166640b..41255ca0 100644 --- a/src/ngircd/ngircd.c +++ b/src/ngircd/ngircd.c @@ -9,6 +9,7 @@ * Please read the file COPYING, README and AUTHORS for more information. */ +#define GLOBAL_INIT #include "portab.h" /** diff --git a/src/portab/portab.h b/src/portab/portab.h index 70d5ed3e..43f2f907 100644 --- a/src/portab/portab.h +++ b/src/portab/portab.h @@ -102,7 +102,11 @@ typedef unsigned char bool; #endif #undef GLOBAL +#ifdef GLOBAL_INIT #define GLOBAL +#else +#define GLOBAL extern +#endif /* SPLint */ |