diff options
Diffstat (limited to 'code')
-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; |