diff options
author | thilo <thilo@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2009-10-08 20:03:25 +0000 |
---|---|---|
committer | thilo <thilo@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2009-10-08 20:03:25 +0000 |
commit | 8b5db2a3ee3f44a5a0af0d8fd84e15d9c5a1f76a (patch) | |
tree | defa576b8ce8812b397d564ef06d8b6dcbc432e1 | |
parent | 6f7eb0e4c943f44d7ec87c050f703a7eeb050d7c (diff) | |
download | ioquake3-aero-8b5db2a3ee3f44a5a0af0d8fd84e15d9c5a1f76a.tar.gz ioquake3-aero-8b5db2a3ee3f44a5a0af0d8fd84e15d9c5a1f76a.zip |
Fix circumventing sv_maxping restriction, thanks to Amanieu for reporting. http://bugzilla.icculus.org/show_bug.cgi?id=3423
git-svn-id: svn://svn.icculus.org/quake3/trunk@1649 edf5b092-35ff-0310-97b2-ce42778d08ea
-rw-r--r-- | code/server/server.h | 1 | ||||
-rw-r--r-- | code/server/sv_client.c | 49 |
2 files changed, 34 insertions, 16 deletions
diff --git a/code/server/server.h b/code/server/server.h index eab244b..bf85594 100644 --- a/code/server/server.h +++ b/code/server/server.h @@ -208,6 +208,7 @@ typedef struct { int time; // time the last packet was sent to the autherize server int pingTime; // time the challenge response was sent to client int firstTime; // time the adr was first used, for authorize timeout checks + qboolean wasrefused; qboolean connected; } challenge_t; diff --git a/code/server/sv_client.c b/code/server/sv_client.c index 773c89e..4387d24 100644 --- a/code/server/sv_client.c +++ b/code/server/sv_client.c @@ -69,7 +69,7 @@ void SV_GetChallenge(netadr_t from) // 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 ) ) { + if (!challenge->connected && NET_CompareAdr( from, challenge->adr ) ) { break; } if ( challenge->time < oldestTime ) { @@ -82,7 +82,6 @@ void SV_GetChallenge(netadr_t from) { // this is the first time this client has asked for a challenge challenge = &svs.challenges[oldest]; - challenge->challenge = ( (rand() << 16) ^ rand() ) ^ svs.time; challenge->clientChallenge = 0; challenge->adr = from; challenge->firstTime = svs.time; @@ -90,6 +89,11 @@ void SV_GetChallenge(netadr_t from) 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; + + #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. @@ -338,41 +342,54 @@ void SV_DirectConnect( netadr_t from ) { Info_SetValueForKey( userinfo, "ip", ip ); // see if the challenge is valid (LAN clients don't need to challenge) - if ( !NET_IsLocalAddress (from) ) { - int ping; + if (!NET_IsLocalAddress(from)) + { + int ping; + challenge_t *challengeptr; - for (i=0 ; i<MAX_CHALLENGES ; i++) { - if (NET_CompareAdr(from, svs.challenges[i].adr)) { - if ( challenge == svs.challenges[i].challenge ) + for (i=0; i<MAX_CHALLENGES; i++) + { + if (NET_CompareAdr(from, svs.challenges[i].adr)) + { + if(challenge == svs.challenges[i].challenge) break; } } - if (i == MAX_CHALLENGES) { - NET_OutOfBandPrint( NS_SERVER, from, "print\nNo or bad challenge for address.\n" ); + + if (i == MAX_CHALLENGES) + { + NET_OutOfBandPrint( NS_SERVER, from, "print\nNo or bad challenge for your address.\n" ); + return; + } + + challengeptr = &svs.challenges[i]; + + if(challengeptr->wasrefused) + { + // Return silently, so that error messages written by the server keep being displayed. return; } - ping = svs.time - svs.challenges[i].pingTime; - Com_Printf( "Client %i connecting with %i challenge ping\n", i, ping ); - svs.challenges[i].connected = qtrue; + ping = svs.time - challengeptr->pingTime; // never reject a LAN client based on ping if ( !Sys_IsLANAddress( from ) ) { if ( sv_minPing->value && ping < sv_minPing->value ) { - // don't let them keep trying until they get a big delay NET_OutOfBandPrint( NS_SERVER, from, "print\nServer is for high pings only\n" ); Com_DPrintf ("Client %i rejected on a too low ping\n", i); - // reset the address otherwise their ping will keep increasing - // with each connect message and they'd eventually be able to connect - svs.challenges[i].adr.port = 0; + challengeptr->wasrefused = qtrue; return; } if ( sv_maxPing->value && ping > sv_maxPing->value ) { NET_OutOfBandPrint( NS_SERVER, from, "print\nServer is for low pings only\n" ); Com_DPrintf ("Client %i rejected on a too high ping\n", i); + challengeptr->wasrefused = qtrue; return; } } + + Com_Printf("Client %i connecting with %i challenge ping\n", i, ping); + challengeptr->connected = qtrue; } newcl = &temp; |