diff options
author | Thilo Schulz <arny@ats.s.bawue.de> | 2011-07-07 16:07:58 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2013-01-10 21:57:38 +0000 |
commit | 24661b24813af79575032cb1bcb55b28208ab76d (patch) | |
tree | a00895448a3f7955227fdd864154ba11e9fac8a1 /src/server | |
parent | 344f803c0fa88083e3597438cf0cdf86d5d3d486 (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/server')
-rw-r--r-- | src/server/server.h | 6 | ||||
-rw-r--r-- | src/server/sv_client.c | 36 |
2 files changed, 31 insertions, 11 deletions
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); } /* |