about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAlexander Barton <alex@barton.de>2003-11-05 21:41:01 +0000
committerAlexander Barton <alex@barton.de>2003-11-05 21:41:01 +0000
commit2981fe9eb707b340107b5131018805ee2a469950 (patch)
treea032cdd22d69e9a1412a2a00f71728e19b7ea02d /src
parent20d002e155fdd370fc86f715f884963f803c9d60 (diff)
downloadngircd-2981fe9eb707b340107b5131018805ee2a469950.tar.gz
ngircd-2981fe9eb707b340107b5131018805ee2a469950.zip
New configuration option "MaxConnectionsIP".
Diffstat (limited to 'src')
-rw-r--r--src/ngircd/conf.c17
-rw-r--r--src/ngircd/conf.h5
-rw-r--r--src/ngircd/conn.c30
3 files changed, 47 insertions, 5 deletions
diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c
index 0abb3c81..d17168c3 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.60 2003/09/11 12:05:28 alex Exp $";
+static char UNUSED id[] = "$Id: conf.c,v 1.61 2003/11/05 21:41:02 alex Exp $";
 
 #include "imp.h"
 #include <assert.h>
@@ -133,6 +133,8 @@ Conf_Test( VOID )
 	printf( "  OperCanUseMode = %s\n", Conf_OperCanMode == TRUE ? "yes" : "no" );
 	if( Conf_MaxConnections > 0 ) printf( "  MaxConnections = %ld\n", Conf_MaxConnections );
 	else printf( "  MaxConnections = -1\n" );
+	if( Conf_MaxConnectionsIP > 0 ) printf( "  MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP );
+	else printf( "  MaxConnectionsIP = -1\n" );
 	if( Conf_MaxJoins > 0 ) printf( "  MaxJoins = %d\n", Conf_MaxJoins );
 	else printf( "  MaxJoins = -1\n" );
 	puts( "" );
@@ -356,6 +358,7 @@ Set_Defaults( BOOLEAN InitServers )
 	Conf_OperCanMode = FALSE;
 	
 	Conf_MaxConnections = -1;
+	Conf_MaxConnectionsIP = 5;
 	Conf_MaxJoins = 10;
 
 	/* Initialize server configuration structures */
@@ -691,6 +694,16 @@ Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg )
 		Conf_MaxConnections = atol( Arg );
 		return;
 	}
+	if( strcasecmp( Var, "MaxConnectionsIP" ) == 0 )
+	{
+		/* Maximum number of simoultanous connections from one IP. Values <= 0 are equal to "no limit". */
+#ifdef HAVE_ISDIGIT
+		if( ! isdigit( *Arg )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"MaxConnectionsIP\" is not a number!", NGIRCd_ConfFile, Line );
+		else
+#endif
+		Conf_MaxConnectionsIP = atoi( Arg );
+		return;
+	}
 	if( strcasecmp( Var, "MaxJoins" ) == 0 )
 	{
 		/* Maximum number of channels a user can join. Values <= 0 are equal to "no limit". */
@@ -707,8 +720,8 @@ Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg )
 		if( strlcpy( Conf_ListenAddress, Arg, sizeof( Conf_ListenAddress )) >= sizeof( Conf_ListenAddress ))
 		{
 			Config_Error( LOG_WARNING, "%s, line %d: Value of \"Listen\" too long!", NGIRCd_ConfFile, Line );
-			return;
 		}
+		return;
 	}
 
 	Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!", NGIRCd_ConfFile, Line, Var );
diff --git a/src/ngircd/conf.h b/src/ngircd/conf.h
index 15a7093d..b900610b 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.27 2003/09/11 12:05:28 alex Exp $
+ * $Id: conf.h,v 1.28 2003/11/05 21:41:02 alex Exp $
  *
  * Configuration management (header)
  */
@@ -110,6 +110,9 @@ GLOBAL LONG Conf_MaxConnections;
 /* Maximum number of channels a user can join */
 GLOBAL INT Conf_MaxJoins;
 
+/* Maximum number of connections per IP address */
+GLOBAL INT Conf_MaxConnectionsIP;
+
 
 GLOBAL VOID Conf_Init PARAMS((VOID ));
 GLOBAL VOID Conf_Rehash PARAMS((VOID ));
diff --git a/src/ngircd/conn.c b/src/ngircd/conn.c
index 56824594..2c65f26e 100644
--- a/src/ngircd/conn.c
+++ b/src/ngircd/conn.c
@@ -16,7 +16,7 @@
 
 #include "portab.h"
 
-static char UNUSED id[] = "$Id: conn.c,v 1.125 2003/09/11 12:05:28 alex Exp $";
+static char UNUSED id[] = "$Id: conn.c,v 1.126 2003/11/05 21:41:02 alex Exp $";
 
 #include "imp.h"
 #include <assert.h>
@@ -87,6 +87,7 @@ 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 ));
 LOCAL VOID Simple_Message PARAMS(( INT Sock, CHAR *Msg ));
+LOCAL INT Count_Connections PARAMS(( struct sockaddr_in addr ));
 
 LOCAL fd_set My_Listeners;
 LOCAL fd_set My_Sockets;
@@ -904,7 +905,7 @@ New_Connection( INT Sock )
 	CONN_ID idx;
 	CLIENT *c;
 	POINTER *ptr;
-	LONG new_size;
+	LONG new_size, cnt;
 
 	assert( Sock > NONE );
 
@@ -932,6 +933,17 @@ New_Connection( INT Sock )
 
 	/* Socket initialisieren */
 	Init_Socket( new_sock );
+	
+	/* Check IP-based connection limit */
+	cnt = Count_Connections( new_addr );
+	if(( Conf_MaxConnectionsIP > 0 ) && ( cnt >= Conf_MaxConnectionsIP ))
+	{
+		/* Access denied, too many connections from this IP! */
+		Log( LOG_ERR, "Refused connection from %s: too may connections (%ld) from this IP!", inet_ntoa( new_addr.sin_addr ), cnt);
+		Simple_Message( new_sock, "ERROR :Connection refused, too many connections from your IP!" );
+		close( new_sock );
+		return;
+	}
 
 	/* Freie Connection-Struktur suchen */
 	for( idx = 0; idx < Pool_Size; idx++ ) if( My_Connections[idx].sock == NONE ) break;
@@ -1599,4 +1611,18 @@ Simple_Message( INT Sock, CHAR *Msg )
 } /* Simple_Error */
 
 
+LOCAL INT
+Count_Connections( struct sockaddr_in addr_in )
+{
+	INT i, cnt;
+	
+	cnt = 0;
+	for( i = 0; i < Pool_Size; i++ )
+	{
+		if(( My_Connections[i].sock > NONE ) && ( My_Connections[i].addr.sin_addr.s_addr == addr_in.sin_addr.s_addr )) cnt++;
+	}
+	return cnt;
+} /* Count_Connections */
+
+
 /* -eof- */