[quake3-commits] r2065 - in trunk/code: qcommon server

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Thu Jul 7 12:07:58 EDT 2011


Author: thilo
Date: 2011-07-07 12:07:58 -0400 (Thu, 07 Jul 2011)
New Revision: 2065

Modified:
   trunk/code/qcommon/q_shared.c
   trunk/code/qcommon/q_shared.h
   trunk/code/server/server.h
   trunk/code/server/sv_client.c
Log:
- Add better protection against DoSing connecting users from connecting
- Have Com_sprintf return string length
- add STR_LEN macro for static strings


Modified: trunk/code/qcommon/q_shared.c
===================================================================
--- trunk/code/qcommon/q_shared.c	2011-06-28 08:28:12 UTC (rev 2064)
+++ trunk/code/qcommon/q_shared.c	2011-07-07 16:07:58 UTC (rev 2065)
@@ -919,7 +919,7 @@
 	return count;
 }
 
-void QDECL Com_sprintf(char *dest, int size, const char *fmt, ...)
+int QDECL Com_sprintf(char *dest, int size, const char *fmt, ...)
 {
 	int		len;
 	va_list		argptr;
@@ -930,6 +930,8 @@
 
 	if(len >= size)
 		Com_Printf("Com_sprintf: Output length %d too short, require %d bytes.\n", size, len + 1);
+	
+	return len;
 }
 
 /*

Modified: trunk/code/qcommon/q_shared.h
===================================================================
--- trunk/code/qcommon/q_shared.h	2011-06-28 08:28:12 UTC (rev 2064)
+++ trunk/code/qcommon/q_shared.h	2011-07-07 16:07:58 UTC (rev 2065)
@@ -206,8 +206,8 @@
 #define	MIN_QINT			(-MAX_QINT-1)
 
 #define ARRAY_LEN(x)			(sizeof(x) / sizeof(*(x)))
+#define STR_LEN(x)			(ARRAY_LEN(x) - 1)
 
-
 // angle indexes
 #define	PITCH				0		// up / down
 #define	YAW					1		// left / right
@@ -750,7 +750,7 @@
 void Parse3DMatrix (char **buf_p, int z, int y, int x, float *m);
 int Com_HexStrToInt( const char *str );
 
-void	QDECL Com_sprintf (char *dest, int size, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
+int QDECL Com_sprintf (char *dest, int size, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
 
 char *Com_SkipTokens( char *s, int numTokens, char *sep );
 char *Com_SkipCharset( char *s, char *sep );

Modified: trunk/code/server/server.h
===================================================================
--- trunk/code/server/server.h	2011-06-28 08:28:12 UTC (rev 2064)
+++ trunk/code/server/server.h	2011-07-07 16:07:58 UTC (rev 2065)
@@ -197,7 +197,11 @@
 // MAX_CHALLENGES is made large to prevent a denial
 // of service attack that could cycle all of them
 // out before legitimate users connected
-#define	MAX_CHALLENGES	1024
+#define	MAX_CHALLENGES	2048
+// Allow a certain amount of challenges to have the same IP address
+// to make it a bit harder to DOS one single IP address from connecting
+// while not allowing a single ip to grab all challenge resources
+#define MAX_CHALLENGES_MULTI (MAX_CHALLENGES / 2)
 
 #define	AUTHORIZE_TIMEOUT	5000
 

Modified: trunk/code/server/sv_client.c
===================================================================
--- trunk/code/server/sv_client.c	2011-06-28 08:28:12 UTC (rev 2064)
+++ trunk/code/server/sv_client.c	2011-07-07 16:07:58 UTC (rev 2065)
@@ -55,8 +55,10 @@
 	int		i;
 	int		oldest;
 	int		oldestTime;
-	const char *clientChallenge = Cmd_Argv(1);
+	int		oldestClientTime;
+	int		clientChallenge;
 	challenge_t	*challenge;
+	qboolean wasfound = qfalse;
 
 	// ignore if we are in single player
 	if ( Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER || Cvar_VariableValue("ui_singlePlayerActive")) {
@@ -64,15 +66,30 @@
 	}
 
 	oldest = 0;
-	oldestTime = 0x7fffffff;
+	oldestClientTime = oldestTime = 0x7fffffff;
 
 	// see if we already have a challenge for this ip
 	challenge = &svs.challenges[0];
-	for (i = 0 ; i < MAX_CHALLENGES ; i++, challenge++) {
-		if (!challenge->connected && NET_CompareAdr( from, challenge->adr ) ) {
+	clientChallenge = atoi(Cmd_Argv(1));
+
+	for(i = 0 ; i < MAX_CHALLENGES ; i++, challenge++)
+	{
+		if(!challenge->connected && NET_CompareAdr(from, challenge->adr))
+		{
+			wasfound = qtrue;
+			
+			if(challenge->time < oldestClientTime)
+				oldestClientTime = challenge->time;
+		}
+		
+		if(wasfound && i >= MAX_CHALLENGES_MULTI)
+		{
+			i = MAX_CHALLENGES;
 			break;
 		}
-		if ( challenge->time < oldestTime ) {
+		
+		if(challenge->time < oldestTime)
+		{
 			oldestTime = challenge->time;
 			oldest = i;
 		}
@@ -82,18 +99,17 @@
 	{
 		// this is the first time this client has asked for a challenge
 		challenge = &svs.challenges[oldest];
-		challenge->clientChallenge = 0;
+		challenge->clientChallenge = clientChallenge;
 		challenge->adr = from;
 		challenge->firstTime = svs.time;
-		challenge->time = svs.time;
 		challenge->connected = qfalse;
 	}
 
 	// always generate a new challenge number, so the client cannot circumvent sv_maxping
 	challenge->challenge = ( (rand() << 16) ^ rand() ) ^ svs.time;
 	challenge->wasrefused = qfalse;
+	challenge->time = svs.time;
 
-
 #ifndef STANDALONE
 	// Drop the authorize stuff if this client is coming in via v6 as the auth server does not support ipv6.
 	// Drop also for addresses coming in on local LAN and for stand-alone games independent from id's assets.
@@ -121,7 +137,7 @@
 		// if they have been challenging for a long time and we
 		// haven't heard anything from the authorize server, go ahead and
 		// let them in, assuming the id server is down
-		else if(svs.time - challenge->firstTime > AUTHORIZE_TIMEOUT)
+		else if(svs.time - oldestClientTime > AUTHORIZE_TIMEOUT)
 			Com_DPrintf( "authorize server timed out\n" );
 		else
 		{
@@ -129,10 +145,6 @@
 			cvar_t	*fs;
 			char	game[1024];
 
-			// If the client provided us with a client challenge, store it...
-			if(*clientChallenge)
-				challenge->clientChallenge = atoi(clientChallenge);
-			
 			Com_DPrintf( "sending getIpAuthorize for %s\n", NET_AdrToString( from ));
 		
 			strcpy(game, BASEGAME);
@@ -153,7 +165,8 @@
 #endif
 
 	challenge->pingTime = svs.time;
-	NET_OutOfBandPrint( NS_SERVER, challenge->adr, "challengeResponse %i %s", challenge->challenge, clientChallenge);
+	NET_OutOfBandPrint(NS_SERVER, challenge->adr, "challengeResponse %d %d",
+			   challenge->challenge, clientChallenge);
 }
 
 #ifndef STANDALONE



More information about the quake3-commits mailing list