about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ngircd/client.c8
-rw-r--r--src/ngircd/conf.c171
-rw-r--r--src/ngircd/conn-func.c2
-rw-r--r--src/ngircd/conn.c58
-rw-r--r--src/ngircd/conn.h14
-rw-r--r--src/ngircd/irc-oper.c9
-rw-r--r--src/ngircd/ngircd.c1
-rw-r--r--src/portab/portab.h4
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 */