summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThilo Schulz <arny@ats.s.bawue.de>2011-07-07 16:07:58 +0000
committerTim Angus <tim@ngus.net>2013-01-10 21:57:38 +0000
commit24661b24813af79575032cb1bcb55b28208ab76d (patch)
treea00895448a3f7955227fdd864154ba11e9fac8a1 /src
parent344f803c0fa88083e3597438cf0cdf86d5d3d486 (diff)
- Add better protection against DoSing connecting users from connecting - Have Com_sprintf return string length - add STR_LEN macro for static strings
Diffstat (limited to 'src')
-rw-r--r--src/qcommon/q_shared.c4
-rw-r--r--src/qcommon/q_shared.h4
-rw-r--r--src/server/server.h6
-rw-r--r--src/server/sv_client.c36
4 files changed, 36 insertions, 14 deletions
diff --git a/src/qcommon/q_shared.c b/src/qcommon/q_shared.c
index b930b0ec..d6aa5c90 100644
--- a/src/qcommon/q_shared.c
+++ b/src/qcommon/q_shared.c
@@ -938,7 +938,7 @@ void Q_ParseNewlines( char *dest, const char *src, int destsize )
*dest++ = '\0';
}
-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;
@@ -949,6 +949,8 @@ void QDECL Com_sprintf(char *dest, int size, const char *fmt, ...)
if(len >= size)
Com_Printf("Com_sprintf: Output length %d too short, require %d bytes.\n", size, len + 1);
+
+ return len;
}
/*
diff --git a/src/qcommon/q_shared.h b/src/qcommon/q_shared.h
index e1533b92..751c342d 100644
--- a/src/qcommon/q_shared.h
+++ b/src/qcommon/q_shared.h
@@ -193,7 +193,7 @@ typedef int clipHandle_t;
#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
@@ -799,7 +799,7 @@ void Parse2DMatrix (char **buf_p, int y, int x, float *m);
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 );
diff --git a/src/server/server.h b/src/server/server.h
index af3ebe7c..697d8a30 100644
--- a/src/server/server.h
+++ b/src/server/server.h
@@ -205,7 +205,11 @@ typedef struct client_s {
// 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
diff --git a/src/server/sv_client.c b/src/server/sv_client.c
index 8d69ba8e..082c0417 100644
--- a/src/server/sv_client.c
+++ b/src/server/sv_client.c
@@ -56,19 +56,36 @@ void SV_GetChallenge(netadr_t from)
int i;
int oldest;
int oldestTime;
- const char *clientChallenge = Cmd_Argv(1);
+ int oldestClientTime;
+ int clientChallenge;
challenge_t *challenge;
+ qboolean wasfound = qfalse;
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;
}
@@ -78,20 +95,19 @@ void SV_GetChallenge(netadr_t from)
{
// 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;
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);
}
/*