Main Authors
~~~~~~~~~~~~
-Alexander Barton, <alex@barton.de>, "alex"
+Alexander Barton, <alex@barton.de> (alex)
Contributors
~~~~~~~~~~~~
-Goetz Hoffart, <goetz@hoffart.de>
-Ilja Osthoff, <i.osthoff@gmx.net>
+Goetz Hoffart, <goetz@hoffart.de> (goetz)
+Ilja Osthoff, <i.osthoff@gmx.net> (ilja)
Sean Reifschneider, <jafo-rpms@tummy.com>
+Code snippets
+~~~~~~~~~~~~~
+J. Kercheval: pattern matching functions
+Patrick Powell, <papowell@astart.com>: snprintf()-function
+Andrew Tridgell & Martin Pool: strl{cpy|cat}()-functions
+
+
--
-$Id: AUTHORS,v 1.5 2003/04/21 21:33:18 alex Exp $
+$Id: AUTHORS,v 1.5.2.1 2003/11/07 20:51:08 alex Exp $
-- ChangeLog --
+ngIRCd 0.7.5 (2003-11-07)
+
+ - Fixed ban behavior: users which are banned from a channel can't no
+ longer send PRIVMSG's to this channel (fixes Bug #47).
+ - Fixed and enhanced the "penalty handling" of the server: commands that
+ require more resources block the client for a short time.
+ - Changed the internal time resolution to one second.
+ - New configuration variable "MaxConnectionsIP" to limit the number of
+ simultaneous connections from a single IP that the server will accept.
+ This configuration options lowers the risk of denial of service attacks
+ (DoS), the default is 5 connections per client IP.
+ - Fixed build problems under Mac OS X 10.3.
+ - Use "-pipe" when compiling with gcc, speeds things up a little :-)
+ - Added new configuration variable "Listen" to bind all listening
+ sockets of the server to a single IP address.
+ - Suppress misleading error message of diff during make run.
+ - Enhanced test-suite and made it work on GNU/Hurd.
+ - Fixed minor typo in debug output :-)
+
ngIRCd 0.7.1 (2003-07-18)
-
+
- Included files to build Debian packages (located in "debian/").
- Updated config.guess and config.sub to newer upstream versions.
- NJOIN propagates user channel modes correctly again ... Upsa.
--
-$Id: ChangeLog,v 1.188.2.17 2003/07/18 20:54:47 alex Exp $
+$Id: ChangeLog,v 1.188.2.18 2003/11/07 20:51:08 alex Exp $
);
isa = PBXGroup;
name = Products;
- refType = 4;
+ path = "";
+ refType = 2;
};
//1A0
//1A1
};
F51F791401DFD0DE01D13771 = {
children = (
- FA550F3103D59CB300A85B04,
F5263AEF01E2A9B801CE8F8F,
F51F791501DFD0DE01D13771,
F5E9447D02C9EE2801A85B04,
+ FA0B193305060CB800A85B04,
F5B565290325412B01A85B04,
F5E9447E02C9EE2801A85B04,
F5E9447F02C9EE2801A85B04,
);
isa = PBXGroup;
name = doc;
- path = /Users/alex/Develop/ngircd/doc;
- refType = 0;
+ path = ../doc;
+ refType = 2;
};
F51F791501DFD0DE01D13771 = {
fileEncoding = 5;
);
isa = PBXGroup;
name = testsuite;
- path = /Users/alex/Develop/ngircd/src/testsuite;
- refType = 0;
+ path = ../src/testsuite;
+ refType = 2;
};
F520AEA90335E29001A85B04 = {
fileEncoding = 5;
);
isa = PBXGroup;
name = man;
- path = /Users/alex/Develop/ngircd/man;
- refType = 0;
+ path = ../man;
+ refType = 2;
};
F520AF180335F1B801A85B04 = {
fileEncoding = 5;
F576ABFE01D61D7401A85B03,
);
isa = PBXGroup;
- path = ngircd;
- refType = 4;
+ name = ngircd;
+ path = ../src/ngircd;
+ refType = 2;
};
F52162BB01C7B904012300F4 = {
fileEncoding = 5;
);
isa = PBXGroup;
path = ngircd.pbproj;
- refType = 4;
+ refType = 2;
};
F56D8BA101E0BFA00155ADA7 = {
fileEncoding = 5;
);
isa = PBXGroup;
name = contrib;
- refType = 4;
+ path = "";
+ refType = 2;
};
F5D3536203892AD201A85B04 = {
fileEncoding = 5;
);
isa = PBXGroup;
name = portab;
- path = /Users/alex/Develop/ngircd/src;
- refType = 0;
+ path = ../src/portab;
+ refType = 2;
};
F5F18133023EC63701A85B04 = {
fileEncoding = 5;
//FA2
//FA3
//FA4
+ FA0B193305060CB800A85B04 = {
+ fileEncoding = 5;
+ isa = PBXFileReference;
+ name = Platforms.txt;
+ path = ../doc/Platforms.txt;
+ refType = 2;
+ };
FA42C8AD03C0A00B00A85B04 = {
fileEncoding = 4;
isa = PBXFileReference;
);
isa = PBXGroup;
name = tool;
- refType = 4;
+ path = ../src;
+ refType = 2;
};
FA550F2A03D59C8200A85B04 = {
fileEncoding = 5;
settings = {
};
};
- FA550F3103D59CB300A85B04 = {
- children = (
- FA550F3503D59CD800A85B04,
- FA550F3403D59CD800A85B04,
- FA550F3703D59CD800A85B04,
- FA550F3203D59CD800A85B04,
- FA550F3303D59CD800A85B04,
- FA550F3603D59CD800A85B04,
- FA550F3803D59CD800A85B04,
- FA550F3903D59CD800A85B04,
- FA550F3A03D59CD800A85B04,
- FA550F3B03D59CD800A85B04,
- );
- isa = PBXGroup;
- name = de;
- refType = 4;
- };
- FA550F3203D59CD800A85B04 = {
- fileEncoding = 5;
- isa = PBXFileReference;
- name = CVS.txt;
- path = ../doc/de/CVS.txt;
- refType = 2;
- };
- FA550F3303D59CD800A85B04 = {
- fileEncoding = 5;
- isa = PBXFileReference;
- name = FAQ.txt;
- path = ../doc/de/FAQ.txt;
- refType = 2;
- };
- FA550F3403D59CD800A85B04 = {
- fileEncoding = 5;
- isa = PBXFileReference;
- name = INSTALL;
- path = ../doc/de/INSTALL;
- refType = 2;
- };
- FA550F3503D59CD800A85B04 = {
- fileEncoding = 5;
- isa = PBXFileReference;
- name = Makefile.am;
- path = ../doc/de/Makefile.am;
- refType = 2;
- };
- FA550F3603D59CD800A85B04 = {
- fileEncoding = 5;
- isa = PBXFileReference;
- name = Protocol.txt;
- path = ../doc/de/Protocol.txt;
- refType = 2;
- };
- FA550F3703D59CD800A85B04 = {
- fileEncoding = 5;
- isa = PBXFileReference;
- name = README;
- path = ../doc/de/README;
- refType = 2;
- };
- FA550F3803D59CD800A85B04 = {
- fileEncoding = 5;
- isa = PBXFileReference;
- name = "README-AUX.txt";
- path = "../doc/de/README-AUX.txt";
- refType = 2;
- };
- FA550F3903D59CD800A85B04 = {
- fileEncoding = 5;
- isa = PBXFileReference;
- name = "README-BeOS.txt";
- path = "../doc/de/README-BeOS.txt";
- refType = 2;
- };
- FA550F3A03D59CD800A85B04 = {
- fileEncoding = 5;
- isa = PBXFileReference;
- name = RFC.txt;
- path = ../doc/de/RFC.txt;
- refType = 2;
- };
- FA550F3B03D59CD800A85B04 = {
- fileEncoding = 5;
- isa = PBXFileReference;
- name = "sample-ngircd.conf";
- path = "../doc/de/sample-ngircd.conf";
- refType = 2;
- };
FAC0383C03BB318400A85B04 = {
fileRef = F51044520297ABF80173DE11;
isa = PBXBuildFile;
-- NEWS --
+ngIRCd 0.7.5 (2003-07-11)
+
+ - New configuration variable "MaxConnectionsIP" to limit the number of
+ simultaneous connections from a single IP that the server will accept.
+ This configuration options lowers the risk of denial of service attacks
+ (DoS), the default is 5 connections per client IP.
+ - Added new configuration variable "Listen" to bind all listening
+ sockets of the server to a single IP address.
+
ngIRCd 0.7.1 (2003-07-18)
- Added support for GNU/Hurd.
--
-$Id: NEWS,v 1.53.2.4 2003/07/18 20:54:47 alex Exp $
+$Id: NEWS,v 1.53.2.5 2003/11/07 20:51:08 alex Exp $
# (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information.
#
-# $Id: configure.in,v 1.89.2.10 2003/07/18 20:55:10 alex Exp $
+# $Id: configure.in,v 1.89.2.11 2003/11/07 20:51:08 alex Exp $
#
# -- Initialisierung --
AC_PREREQ(2.50)
-AC_INIT(ngircd, 0.7.1)
+AC_INIT(ngircd, 0.7.5)
AC_CONFIG_SRCDIR(src/ngircd/ngircd.c)
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE(1.6)
ansi=" -ansi"
pedantic=" -pedantic"
- $CC --version | grep 20020420 > /dev/null 2>&1
+ $CC --version | grep 20020420 >/dev/null 2>&1
if test $? -eq 0; then
# Mac OS X (and Darwin?) ship with a slightly broken
# prerelease of GCC 3.1 which don't like -pedantic:
pedantic=""
fi
- uname | grep "CYGWIN" > /dev/null 2>&1
+ $CC --version | grep 20030304 >/dev/null 2>&1
+ if test $? -eq 0; then
+ # Mac OS X 10.3 (and Darwin 7.0?) have a strange gcc (or
+ # system header files?) which produces lots of errors when
+ # using -ansi; so we don't =:-)
+ AC_MSG_RESULT([detected broken GNU C compiler, disabling "-ansi"])
+ ansi=""
+ fi
+
+ uname | grep "CYGWIN" >/dev/null 2>&1
if test $? -eq 0; then
# The include files of Cygwin don't like -ansi,
# so we disable it:
ansi=""
fi
- add_CFLAGS="-Wall -W${ansi}${pedantic} $CFLAGS $CFLAGS_ADD"
+ add_CFLAGS="-pipe -Wall -W${ansi}${pedantic} $CFLAGS $CFLAGS_ADD"
else
the_CFLAGS="$CFLAGS"
add_CFLAGS="$CFLAGS_ADD"
%define name ngircd
-%define version 0.7.1
+%define version 0.7.5
%define release 1
%define prefix %{_prefix}
-# $Id: sample-ngircd.conf,v 1.20.2.2 2003/04/29 12:37:17 alex Exp $
+# $Id: sample-ngircd.conf,v 1.20.2.3 2003/11/07 20:51:09 alex Exp $
#
# This is a sample configuration file for the ngIRCd, which must adept to
# Ports on which the server should listen. There may be more than
# one port, separated with ";". (Default: 6667)
;Ports = 6667, 6668, 66694
+
+ # IP address on which the server should listen. (Default: empty,
+ # so the server listens on all IP addresses of the system)
+ ;Listen = 1.2.3.4
# Text file with the "message of the day" (MOTD). This message will
# be shown to all users connecting to the server:
# Maximum number of simultaneous connection the server is allowed
# to accept (<=0: unlimited):
;MaxConnections = -1
+
+ # Maximum number of simultaneous connections from a single IP address
+ # the server will accept (<=0: unlimited):
+ ;MaxConnectionsIP = 5
# Maximum number of channels a user can be member of (<=0: no limit):
;MaxJoins = 10
.\"
-.\" $Id: ngircd.conf.5,v 1.9.2.1 2003/07/18 20:48:20 alex Exp $
+.\" $Id: ngircd.conf.5,v 1.9.2.2 2003/11/07 20:51:10 alex Exp $
.\"
.TH ngircd.conf 5 "Mai 2003" ngircd "ngIRCd Manual"
.SH NAME
Ports on which the server should listen. There may be more than one port,
separated with ';'. Default: 6667.
.TP
+\fBListen\fR
+The ip address on which the server should listen. Default is empty, so
+the server listens on all configured ip addresses and interfaces.
+.TP
\fBMotdFile\fR
Text file with the "message of the day" (MOTD). This message will be shown
to all users connecting to the server.
Maximum number of simultaneous connection the server is allowed to accept
(<=0: unlimited). Default: -1.
.TP
+\fBMaxConnectionsIP\fR
+Maximum number of simultaneous connections from a single IP address that
+the server will accept (<=0: unlimited). This configuration options lowers
+the risk of denial of service attacks (DoS). Default: 5.
+.TP
\fBMaxJoins\fR
Maximum number of channels a user can be member of (<=0: no limit).
Default: 10.
# (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information.
#
-# $Id: Makefile.am,v 1.39.2.1 2003/07/18 20:49:05 alex Exp $
+# $Id: Makefile.am,v 1.39.2.2 2003/11/07 20:51:10 alex Exp $
#
AUTOMAKE_OPTIONS = ../portab/ansi2knr
| $(AWK) "{ print \$$9 }" | sort | tail -1 \
| sed -e "s/\//-/g" )\"" > cvs-version.new \
|| echo "" > cvs-version.new
- diff cvs-version.h cvs-version.new || cp cvs-version.new cvs-version.h
+ diff cvs-version.h cvs-version.new 2>/dev/null \
+ || cp cvs-version.new cvs-version.h
TESTS = check-version check-help
#include "portab.h"
-static char UNUSED id[] = "$Id: channel.c,v 1.42 2002/12/30 17:15:42 alex Exp $";
+static char UNUSED id[] = "$Id: channel.c,v 1.42.2.1 2003/11/07 20:51:10 alex Exp $";
#include "imp.h"
#include <assert.h>
{
BOOLEAN is_member, has_voice, is_op, ok;
- /* Okay, Ziel ist ein Channel */
+ /* Okay, target is a channel */
is_member = has_voice = is_op = FALSE;
if( Channel_IsMemberOf( Chan, From ))
{
if( strchr( Channel_UserModes( Chan, From ), 'o' )) is_op = TRUE;
}
- /* pruefen, ob Client in Channel schreiben darf */
+ /* Check weather client is allowed to write to channel */
ok = TRUE;
if( strchr( Channel_Modes( Chan ), 'n' ) && ( ! is_member )) ok = FALSE;
if( strchr( Channel_Modes( Chan ), 'm' ) && ( ! is_op ) && ( ! has_voice )) ok = FALSE;
+
+ /* Is the client banned? */
+ if( Lists_CheckBanned( From, Chan ))
+ {
+ /* Client is banned, bus is he channel operator or has voice? */
+ if(( ! has_voice ) && ( ! is_op )) ok = FALSE;
+ }
if( ! ok ) return IRC_WriteStrClient( From, ERR_CANNOTSENDTOCHAN_MSG, Client_ID( From ), Channel_Name( Chan ));
- /* Text senden */
+ /* Send text */
if( Client_Conn( From ) > NONE ) Conn_UpdateIdle( Client_Conn( From ));
return IRC_WriteStrChannelPrefix( Client, Chan, From, TRUE, "PRIVMSG %s :%s", Channel_Name( Chan ), Text );
} /* Channel_Write */
#include "portab.h"
-static char UNUSED id[] = "$Id: conf.c,v 1.57.2.2 2003/04/29 12:37:18 alex Exp $";
+static char UNUSED id[] = "$Id: conf.c,v 1.57.2.3 2003/11/07 20:51:10 alex Exp $";
#include "imp.h"
#include <assert.h>
printf( "%u", Conf_ListenPorts[i] );
}
puts( "" );
+ printf( " Listen = %s\n", Conf_ListenAddress );
pwd = getpwuid( Conf_UID );
if( pwd ) printf( " ServerUID = %s\n", pwd->pw_name );
else printf( " ServerUID = %ld\n", (LONG)Conf_UID );
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( "" );
strlcat( Conf_MotdFile, MOTD_FILE, sizeof( Conf_MotdFile ));
Conf_ListenPorts_Count = 0;
+ strcpy( Conf_ListenAddress, "" );
Conf_UID = Conf_GID = 0;
Conf_OperCanMode = FALSE;
Conf_MaxConnections = -1;
+ Conf_MaxConnectionsIP = 5;
Conf_MaxJoins = 10;
/* Initialize server configuration structures */
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". */
Conf_MaxJoins = atoi( Arg );
return;
}
+ if( strcasecmp( Var, "Listen" ) == 0 )
+ {
+ /* IP-Address to bind sockets */
+ 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;
+ }
Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!", NGIRCd_ConfFile, Line, Var );
} /* Handle_GLOBAL */
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
- * $Id: conf.h,v 1.26 2002/12/31 16:12:50 alex Exp $
+ * $Id: conf.h,v 1.26.2.1 2003/11/07 20:51:11 alex Exp $
*
* Configuration management (header)
*/
GLOBAL UINT Conf_ListenPorts[MAX_LISTEN_PORTS];
GLOBAL INT Conf_ListenPorts_Count;
+/* Address to which the socket should be bound or empty (=all) */
+GLOBAL CHAR Conf_ListenAddress[16];
+
/* User and group ID the server should run with */
GLOBAL UINT Conf_UID;
GLOBAL UINT Conf_GID;
/* 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 ));
#include "portab.h"
-static char UNUSED id[] = "$Id: conn-func.c,v 1.1 2002/12/30 17:14:28 alex Exp $";
+static char UNUSED id[] = "$Id: conn-func.c,v 1.1.2.1 2003/11/07 20:51:11 alex Exp $";
#include "imp.h"
#include <assert.h>
+#include <log.h>
#include "conn.h"
assert( Idx > NONE );
assert( Seconds >= 0 );
-
+
t = time( NULL ) + Seconds;
if( t > My_Connections[Idx].delaytime ) My_Connections[Idx].delaytime = t;
} /* Conn_SetPenalty */
#include "portab.h"
-static char UNUSED id[] = "$Id: conn.c,v 1.122.2.1 2003/04/25 16:50:53 alex Exp $";
+static char UNUSED id[] = "$Id: conn.c,v 1.122.2.2 2003/11/07 20:51:11 alex Exp $";
#include "imp.h"
#include <assert.h>
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;
Log( LOG_EMERG, "Can't allocate memory! [Conn_Init]" );
exit( 1 );
}
- Log( LOG_DEBUG, "Allocted connection pool for %d items (%ld bytes).", Pool_Size, sizeof( CONNECTION ) * Pool_Size );
+#ifdef DEBUG
+ Log( LOG_DEBUG, "Allocated connection pool for %d items (%ld bytes).", Pool_Size, sizeof( CONNECTION ) * Pool_Size );
+#endif
/* zu Beginn haben wir keine Verbindungen */
FD_ZERO( &My_Listeners );
CONN_ID idx;
INT i;
+#ifdef DEBUG
Log( LOG_DEBUG, "Shutting down all connections ..." );
+#endif
#ifdef RENDEZVOUS
Rendezvous_UnregisterListeners( );
if( FD_ISSET( i, &My_Listeners ))
{
close( i );
+#ifdef DEBUG
Log( LOG_DEBUG, "Listening socket %d closed.", i );
+#endif
}
else if( FD_ISSET( i, &My_Connects ))
{
close( i );
+#ifdef DEBUG
Log( LOG_DEBUG, "Connection %d closed during creation (socket %d).", idx, i );
+#endif
}
else if( idx < Pool_Size )
{
if( FD_ISSET( i, &My_Sockets ) && FD_ISSET( i, &My_Listeners ))
{
close( i );
+#ifdef DEBUG
Log( LOG_DEBUG, "Listening socket %d closed.", i );
+#endif
}
}
} /* Conn_ExitListeners */
/* Create new listening socket on specified port */
struct sockaddr_in addr;
+ struct in_addr inaddr;
INT sock;
#ifdef RENDEZVOUS
CHAR name[CLIENT_ID_LEN], *info;
/* Server-"Listen"-Socket initialisieren */
memset( &addr, 0, sizeof( addr ));
+ memset( &inaddr, 0, sizeof( inaddr ));
addr.sin_family = AF_INET;
addr.sin_port = htons( Port );
- addr.sin_addr.s_addr = htonl( INADDR_ANY );
+ if( Conf_ListenAddress[0] )
+ {
+#ifdef HAVE_INET_ATON
+ if( inet_aton( Conf_ListenAddress, &inaddr ) == 0 )
+#else
+ inaddr.s_addr = inet_addr( Conf_ListenAddress );
+ if( inaddr.s_addr == (unsigned)-1 )
+#endif
+ {
+ Log( LOG_CRIT, "Can't listen on %s:%u: can't convert ip address %s!", Conf_ListenAddress, Port, Conf_ListenAddress );
+ return FALSE;
+ }
+ }
+ else inaddr.s_addr = htonl( INADDR_ANY );
+ addr.sin_addr = inaddr;
/* Socket erzeugen */
sock = socket( PF_INET, SOCK_STREAM, 0);
if( sock > Conn_MaxFD ) Conn_MaxFD = sock;
- Log( LOG_INFO, "Now listening on port %d (socket %d).", Port, sock );
+ if( Conf_ListenAddress[0]) Log( LOG_INFO, "Now listening on %s:%d (socket %d).", Conf_ListenAddress, Port, sock );
+ else Log( LOG_INFO, "Now listening on 0.0.0.0:%d (socket %d).", Port, sock );
#ifdef RENDEZVOUS
/* Get best server description text */
Check_Servers( );
Check_Connections( );
+ t = time( NULL );
+
/* noch volle Lese-Buffer suchen */
for( i = 0; i < Pool_Size; i++ )
{
- if(( My_Connections[i].sock > NONE ) && ( My_Connections[i].rdatalen > 0 ))
+ if(( My_Connections[i].sock > NONE ) && ( My_Connections[i].rdatalen > 0 ) &&
+ ( My_Connections[i].delaytime < t ))
{
/* Kann aus dem Buffer noch ein Befehl extrahiert werden? */
if( Handle_Buffer( i )) timeout = FALSE;
}
/* von welchen Sockets koennte gelesen werden? */
- t = time( NULL );
read_sockets = My_Sockets;
for( i = 0; i < Pool_Size; i++ )
{
/* Timeout initialisieren */
tv.tv_usec = 0;
- if( timeout ) tv.tv_sec = TIME_RES;
+ if( timeout ) tv.tv_sec = 1;
else tv.tv_sec = 0;
/* Auf Aktivitaet warten */
* In diesem Fall wird hier einfach ein Fehler geliefert. */
if( My_Connections[Idx].sock <= NONE )
{
+#ifdef DEBUG
Log( LOG_DEBUG, "Skipped write on closed socket (connection %d).", Idx );
+#endif
return FALSE;
}
return FALSE;
}
+#ifdef DEBUG
Log( LOG_DEBUG, "Connection %d with \"%s:%d\" established, now sendig PASS and SERVER ...", Idx, My_Connections[Idx].host, Conf_Server[Conf_GetServer( Idx )].port );
+#endif
/* PASS und SERVER verschicken */
Conn_WriteStr( Idx, "PASS %s %s", Conf_Server[Conf_GetServer( Idx )].pwd_out, NGIRCd_ProtoID );
CONN_ID idx;
CLIENT *c;
POINTER *ptr;
- LONG new_size;
+ LONG new_size, cnt;
assert( Sock > NONE );
/* 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;
/* Struktur umkopieren ... */
memcpy( ptr, My_Connections, sizeof( CONNECTION ) * Pool_Size );
+#ifdef DEBUG
Log( LOG_DEBUG, "Allocated new connection pool for %ld items (%ld bytes). [malloc()/memcpy()]", new_size, sizeof( CONNECTION ) * new_size );
+#endif
}
+#ifdef DEBUG
else Log( LOG_DEBUG, "Allocated new connection pool for %ld items (%ld bytes). [realloc()]", new_size, sizeof( CONNECTION ) * new_size );
+#endif
/* Adjust pointer to new block */
My_Connections = ptr;
{
/* die Connection wurde vermutlich (wegen eines
* Fehlers) bereits wieder abgebaut ... */
+#ifdef DEBUG
Log( LOG_DEBUG, "Socket2Index: can't get connection for socket %d!", Sock );
+#endif
return NONE;
}
else return idx;
result = FALSE;
do
{
+ /* Check penalty */
+ if( My_Connections[Idx].delaytime > time( NULL )) return result;
+
#ifdef USE_ZLIB
/* ggf. noch unkomprimiete Daten weiter entpacken */
if( My_Connections[Idx].options & CONN_ZIP )
memcpy( My_Connections[Idx].zip.rbuf, My_Connections[Idx].rbuf, My_Connections[Idx].rdatalen );
My_Connections[Idx].zip.rdatalen = My_Connections[Idx].rdatalen;
My_Connections[Idx].rdatalen = 0;
+#ifdef DEBUG
Log( LOG_DEBUG, "Moved already received data (%d bytes) to uncompression buffer.", My_Connections[Idx].zip.rdatalen );
+#endif
}
}
#endif
if( My_Connections[i].lastping < time( NULL ) - Conf_PongTimeout )
{
/* Timeout */
+#ifdef DEBUG
Log( LOG_DEBUG, "Connection %d: Ping timeout: %d seconds.", i, Conf_PongTimeout );
+#endif
Conn_Close( i, NULL, "Ping timeout", TRUE );
}
}
else if( My_Connections[i].lastdata < time( NULL ) - Conf_PingTimeout )
{
/* es muss ein PING gesendet werden */
+#ifdef DEBUG
Log( LOG_DEBUG, "Connection %d: sending PING ...", i );
+#endif
My_Connections[i].lastping = time( NULL );
Conn_WriteStr( i, "PING :%s", Client_ID( Client_ThisServer( )));
}
if( My_Connections[i].lastdata < time( NULL ) - Conf_PingTimeout )
{
/* Timeout */
+#ifdef DEBUG
Log( LOG_DEBUG, "Connection %d timed out ...", i );
+#endif
Conn_Close( i, NULL, "Timeout", FALSE );
}
}
Log( LOG_ALERT, "Can't establist server connection: connection limit reached (%d)!", Pool_Size );
return;
}
+#ifdef DEBUG
Log( LOG_DEBUG, "Preparing connection %d for \"%s\" ...", idx, Conf_Server[i].host );
+#endif
/* Verbindungs-Struktur initialisieren */
Init_Conn_Struct( idx );
FD_SET( new_sock, &My_Connects );
if( new_sock > Conn_MaxFD ) Conn_MaxFD = new_sock;
+#ifdef DEBUG
Log( LOG_DEBUG, "Registered new connection %d on socket %d.", Idx, My_Connections[Idx].sock );
+#endif
} /* New_Server */
/* Opsa! Keine passende Connection gefunden!? Vermutlich
* wurde sie schon wieder geschlossen. */
close( r_fd );
+#ifdef DEBUG
Log( LOG_DEBUG, "Resolver: Got result for unknown connection!?" );
+#endif
return;
}
+#ifdef DEBUG
Log( LOG_DEBUG, "Resolver: %s is \"%s\".", My_Connections[i].host, result );
+#endif
/* Aufraeumen */
close( My_Connections[i].res_stat->pipe[0] );
} /* 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- */
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
- * $Id: defines.h,v 1.42 2003/02/23 12:03:39 alex Exp $
+ * $Id: defines.h,v 1.42.2.1 2003/11/07 20:51:11 alex Exp $
*
* Global defines of ngIRCd.
*/
#define NONE -1
-#define TIME_RES 2 /* Zeit-Aufloesung des Servers in Sekunden */
-
#define FNAME_LEN 256 /* max. Laenge eines Dateinamen */
#define LINE_LEN 256 /* max. Laenge einer Konfigurationszeile */
#include "portab.h"
-static char UNUSED id[] = "$Id: irc-info.c,v 1.16.2.1 2003/07/18 20:49:35 alex Exp $";
+static char UNUSED id[] = "$Id: irc-info.c,v 1.16.2.2 2003/11/07 20:51:11 alex Exp $";
#include "imp.h"
#include <assert.h>
if( ! IRC_WriteStrClient( Client, RPL_ADMINLOC2_MSG, Client_ID( prefix ), Conf_ServerAdmin2 )) return DISCONNECTED;
if( ! IRC_WriteStrClient( Client, RPL_ADMINEMAIL_MSG, Client_ID( prefix ), Conf_ServerAdminMail )) return DISCONNECTED;
+ IRC_SetPenalty( Client, 1 );
return CONNECTED;
} /* IRC_ADMIN */
}
c = Client_Next( c );
}
-
+
+ IRC_SetPenalty( target, 1 );
return IRC_WriteStrClient( target, RPL_ENDOFLINKS_MSG, Client_ID( target ), mask );
} /* IRC_LINKS */
IRC_Send_LUSERS( target );
+ IRC_SetPenalty( target, 1 );
return CONNECTED;
} /* IRC_LUSERS */
}
}
+ IRC_SetPenalty( from, 3 );
return IRC_Show_MOTD( from );
} /* IRC_MOTD */
if( ! IRC_WriteStrClient( from, "%s", rpl )) return DISCONNECTED;
}
+ IRC_SetPenalty( from, 1 );
return IRC_WriteStrClient( from, RPL_ENDOFNAMES_MSG, Client_ID( from ), "*" );
} /* IRC_NAMES */
break;
}
+ IRC_SetPenalty( from, 2 );
return IRC_WriteStrClient( from, RPL_ENDOFSTATS_MSG, Client_ID( from ), query );
} /* IRC_STATS */
}
/* mit Versionsinfo antworten */
+ IRC_SetPenalty( Client, 1 );
#ifdef CVSDATE
strlcpy( ver, CVSDATE, sizeof( ver ));
strncpy( ver + 4, ver + 5, 2 );
#include "portab.h"
-static char UNUSED id[] = "$Id: irc-login.c,v 1.34 2003/03/31 15:54:21 alex Exp $";
+static char UNUSED id[] = "$Id: irc-login.c,v 1.34.2.1 2003/11/07 20:51:11 alex Exp $";
#include "imp.h"
#include <assert.h>
/* neuen Client-Nick speichern */
Client_SetID( target, Req->argv[0] );
+ IRC_SetPenalty( target, 2 );
}
return CONNECTED;
if( ! IRC_Send_LUSERS( Client )) return DISCONNECTED;
if( ! IRC_Show_MOTD( Client )) return DISCONNECTED;
+ /* Suspend the client for a second ... */
+ IRC_SetPenalty( Client, 1 );
+
return CONNECTED;
} /* Hello_User */
#include "portab.h"
-static char UNUSED id[] = "$Id: irc-mode.c,v 1.31 2003/01/21 21:04:16 alex Exp $";
+static char UNUSED id[] = "$Id: irc-mode.c,v 1.31.2.1 2003/11/07 20:51:11 alex Exp $";
#include "imp.h"
#include <assert.h>
}
Log( LOG_DEBUG, "User \"%s\": Mode change, now \"%s\".", Client_Mask( Target ), Client_Modes( Target ));
}
-
+
+ IRC_SetPenalty( Client, 1 );
return ok;
} /* Client_Mode */
}
}
+ IRC_SetPenalty( Client, 1 );
return CONNECTED;
} /* Channel_Mode */
#include "portab.h"
-static char UNUSED id[] = "$Id: irc-write.c,v 1.14 2002/12/30 17:15:42 alex Exp $";
+static char UNUSED id[] = "$Id: irc-write.c,v 1.14.2.1 2003/11/07 20:51:11 alex Exp $";
#include "imp.h"
#include <assert.h>
} /* IRC_WriteStrRelatedPrefix */
+GLOBAL VOID
+IRC_SetPenalty( CLIENT *Client, INT Seconds )
+{
+ CONN_ID c;
+
+ assert( Client != NULL );
+ assert( Seconds > 0 );
+
+ if( Client_Type( Client ) == CLIENT_SERVER ) return;
+
+ c = Client_Conn( Client );
+ if( c > NONE ) Conn_SetPenalty( c, Seconds );
+} /* IRC_SetPenalty */
+
+
LOCAL CHAR *
Get_Prefix( CLIENT *Target, CLIENT *Client )
{
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
- * $Id: irc-write.h,v 1.5 2002/12/12 12:23:43 alex Exp $
+ * $Id: irc-write.h,v 1.5.4.1 2003/11/07 20:51:11 alex Exp $
*
* Sending IRC commands over the network (header)
*/
#define __irc_write_h__
-GLOBAL BOOLEAN IRC_WriteStrClient PARAMS((CLIENT *Client, CHAR *Format, ... ));
-GLOBAL BOOLEAN IRC_WriteStrClientPrefix PARAMS((CLIENT *Client, CLIENT *Prefix, CHAR *Format, ... ));
+GLOBAL BOOLEAN IRC_WriteStrClient PARAMS(( CLIENT *Client, CHAR *Format, ... ));
+GLOBAL BOOLEAN IRC_WriteStrClientPrefix PARAMS(( CLIENT *Client, CLIENT *Prefix, CHAR *Format, ... ));
-GLOBAL BOOLEAN IRC_WriteStrChannel PARAMS((CLIENT *Client, CHANNEL *Chan, BOOLEAN Remote, CHAR *Format, ... ));
-GLOBAL BOOLEAN IRC_WriteStrChannelPrefix PARAMS((CLIENT *Client, CHANNEL *Chan, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... ));
+GLOBAL BOOLEAN IRC_WriteStrChannel PARAMS(( CLIENT *Client, CHANNEL *Chan, BOOLEAN Remote, CHAR *Format, ... ));
+GLOBAL BOOLEAN IRC_WriteStrChannelPrefix PARAMS(( CLIENT *Client, CHANNEL *Chan, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... ));
-GLOBAL VOID IRC_WriteStrServers PARAMS((CLIENT *ExceptOf, CHAR *Format, ... ));
-GLOBAL VOID IRC_WriteStrServersPrefix PARAMS((CLIENT *ExceptOf, CLIENT *Prefix, CHAR *Format, ... ));
-GLOBAL VOID IRC_WriteStrServersPrefixFlag PARAMS((CLIENT *ExceptOf, CLIENT *Prefix, CHAR Flag, CHAR *Format, ... ));
+GLOBAL VOID IRC_WriteStrServers PARAMS(( CLIENT *ExceptOf, CHAR *Format, ... ));
+GLOBAL VOID IRC_WriteStrServersPrefix PARAMS(( CLIENT *ExceptOf, CLIENT *Prefix, CHAR *Format, ... ));
+GLOBAL VOID IRC_WriteStrServersPrefixFlag PARAMS(( CLIENT *ExceptOf, CLIENT *Prefix, CHAR Flag, CHAR *Format, ... ));
-GLOBAL BOOLEAN IRC_WriteStrRelatedPrefix PARAMS((CLIENT *Client, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... ));
+GLOBAL BOOLEAN IRC_WriteStrRelatedPrefix PARAMS(( CLIENT *Client, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... ));
+
+GLOBAL VOID IRC_SetPenalty PARAMS(( CLIENT *Client, INT Seconds ));
#endif
#include "portab.h"
-static char UNUSED id[] = "$Id: irc.c,v 1.120.2.1 2003/04/29 12:20:14 alex Exp $";
+static char UNUSED id[] = "$Id: irc.c,v 1.120.2.2 2003/11/07 20:51:11 alex Exp $";
#include "imp.h"
#include <assert.h>
/* Some information about us */
if( ! IRC_WriteStrClient( from, RPL_TRACESERVER_MSG, Client_ID( from ), Conf_ServerName, Client_Mask( Client_ThisServer( )), Option_String( Client_Conn( Client )))) return DISCONNECTED;
+ IRC_SetPenalty( Client, 3 );
return IRC_WriteStrClient( from, RPL_TRACEEND_MSG, Client_ID( from ), Conf_ServerName, PACKAGE_NAME, PACKAGE_VERSION, NGIRCd_DebugLevel );
} /* IRC_TRACE */
if( ! IRC_WriteStrClient( Client, "NOTICE %s :%s", Client_ID( Client ), cmd->name )) return DISCONNECTED;
cmd++;
}
+
+ IRC_SetPenalty( Client, 2 );
return CONNECTED;
} /* IRC_HELP */
#!/bin/sh
# ngIRCd Test Suite
-# $Id: getpid.sh,v 1.2.4.1 2003/04/22 20:01:23 alex Exp $
+# $Id: getpid.sh,v 1.2.4.2 2003/11/07 20:51:11 alex Exp $
-# wurde ein Name uebergeben?
+# did we get a name?
[ $# -ne 1 ] && exit 1
-# Flags fuer "ps" ermitteln
+# detect flags for "ps" and "head"
if [ `uname` = "FreeBSD" ]; then
PS_FLAGS="-a"; PS_PIDCOL="1"; HEAD_FLAGS="-n 1"
elif [ `uname` = "A/UX" ]; then
PS_FLAGS="-ae"; PS_PIDCOL="1"; HEAD_FLAGS="-1"
+elif [ `uname` = "GNU" ]; then
+ PS_FLAGS="-ax"; PS_PIDCOL="2"; HEAD_FLAGS="-n 1"
else
PS_FLAGS="-f"; PS_PIDCOL="2"; HEAD_FLAGS="-n 1"
ps $PS_FLAGS > /dev/null 2>&1
if [ $? -ne 0 ]; then PS_FLAGS="a"; PS_PIDCOL="1"; fi
fi
-# PID ermitteln
+# debug output
+#echo "$0: PS_FLAGS=$PS_FLAGS"
+#echo "$0: PS_PIDCOL=$PS_PIDCOL"
+#echo "$0: HEAD_FLAGS=$HEAD_FLAGS"
+
+# search PID
ps $PS_FLAGS > procs.tmp
-cat procs.tmp | grep "$1" | awk "{print \$$PS_PIDCOL}" | sort -n > pids.tmp
+cat procs.tmp | grep -v "$0" | grep "$1" | awk "{print \$$PS_PIDCOL}" | sort -n > pids.tmp
pid=`head $HEAD_FLAGS pids.tmp`
rm -rf procs.tmp pids.tmp
-# ermittelte PID validieren
+# validate PID
[ "$pid" -gt 1 ] > /dev/null 2>&1
[ $? -ne 0 ] && exit 1
-# $Id: ngircd-test.conf,v 1.3 2002/10/21 13:45:23 alex Exp $
+# $Id: ngircd-test.conf,v 1.3.4.1 2003/11/07 20:51:11 alex Exp $
[Global]
Name = ngircd.test.server
Ports = 6789
MotdFile = ngircd-test.motd
AdminEMail = admin@irc.server
+ MaxConnectionsIP = 0
[Operator]
Name = TestOp
#!/bin/sh
# ngIRCd Test Suite
-# $Id: start-server.sh,v 1.10 2002/11/10 14:28:06 alex Exp $
+# $Id: start-server.sh,v 1.10.4.1 2003/11/07 20:51:11 alex Exp $
[ -z "$srcdir" ] && srcdir=`dirname $0`
echo " starting server ..."
-# alte Logfiles loeschen
+# remove old logfiles
rm -rf logs *.log
-# pruefen, ob getpid.sh gueltige PID's liefert. Wenn dem nicht so ist,
-# wird kein ngIRCd gestartet, da dieser ansonsten nicht mehr am Ende
-# des Testlaufs beendet werden koennte!
+# check weather getpid.sh returns valid PIDs. If not, don't start up the
+# test-server, because we won't be able to kill it at the end of the test.
./getpid.sh sh > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo " error: getpid.sh FAILED!"
exit 1
fi
-# MOTD fuer Test-Server erzeugen
+# check if there is a test-server already running
+./getpid.sh T-ngircd > /dev/null 2>&1
+if [ $? -eq 0 ]; then
+ echo " error: test-server already running!"
+ exit 1
+fi
+
+# generate MOTD for test-server
echo "This is an ngIRCd Test Server" > ngircd-test.motd
-# Test-Server starten ...
+# starting up test-server ...
./T-ngircd -np -f ${srcdir}/ngircd-test.conf > ngircd-test.log 2>&1 &
sleep 1
-# validieren, dass Server laeuft
+# validate running test-server
pid=`./getpid.sh T-ngircd`
[ -n "$pid" ] && kill -0 $pid > /dev/null 2>&1 || exit 1
#!/bin/sh
# ngIRCd Test Suite
-# $Id: stop-server.sh,v 1.9 2002/11/10 14:28:06 alex Exp $
+# $Id: stop-server.sh,v 1.9.4.1 2003/11/07 20:51:11 alex Exp $
[ -z "$srcdir" ] && srcdir=`dirname $0`
echo " stopping server ..."
-# Test-Server stoppen ...
+# stop test-server ...
pid=`./getpid.sh T-ngircd`
-[ -n "$pid" ] && kill $pid > /dev/null 2>&1 || exit 1
-sleep 1
+if [ -z "$pid" ]; then
+ echo " no running server found!?"
+ exit 1
+fi
+kill $pid > /dev/null 2>&1 || exit 1
-# jetzt duerfte der Prozess nicht mehr laufen
-kill -0 $pid > /dev/null 2>&1 && exit 1 || exit 0
+# waiting ...
+for i in 1 2 3 4 5; do
+ kill -0 $pid > /dev/null 2>&1 || exit 0
+ sleep 1
+done
+echo " server still running!?"
+exit 1
# -eof-
#!/bin/sh
# ngIRCd Test Suite
-# $Id: stress-server.sh,v 1.6.4.1 2003/04/22 20:01:23 alex Exp $
+# $Id: stress-server.sh,v 1.6.4.2 2003/11/07 20:51:11 alex Exp $
[ -z "$srcdir" ] && srcdir=`dirname $0`
type expect > /dev/null 2>&1
if [ $? -ne 0 ]; then
- echo "SKIP: ${name} -- \"expect\" not found."; exit 77
+ echo " ${name}: \"expect\" not found."; exit 77
fi
type telnet > /dev/null 2>&1
if [ $? -ne 0 ]; then
- echo "SKIP: ${name} -- \"telnet\" not found."; exit 77
+ echo " ${name}: \"telnet\" not found."; exit 77
fi
echo " stressing server with $CLIENTS clients (be patient!) ..."
#!/bin/sh
# ngIRCd Test Suite
-# $Id: tests.sh,v 1.3 2002/09/12 02:29:03 alex Exp $
+# $Id: tests.sh,v 1.3.6.1 2003/11/07 20:51:11 alex Exp $
name=`basename $0`
test=`echo ${name} | cut -d '.' -f 1`
type expect > /dev/null 2>&1
if [ $? -ne 0 ]; then
- echo "SKIP: ${name} -- \"expect\" not found."; exit 77
+ echo " ${name}: \"expect\" not found."; exit 77
fi
type telnet > /dev/null 2>&1
if [ $? -ne 0 ]; then
- echo "SKIP: ${name} -- \"telnet\" not found."; exit 77
+ echo " ${name}: \"telnet\" not found."; exit 77
fi
echo " doing ${test} ..."