mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2024-11-10 23:02:01 +00:00
- Add better protection against DoSing connecting users from connecting
- Have Com_sprintf return string length - add STR_LEN macro for static strings
This commit is contained in:
parent
53d89b6c10
commit
74e538ffcf
4 changed files with 37 additions and 18 deletions
|
@ -919,7 +919,7 @@ int Q_CountChar(const char *string, char tocount)
|
||||||
return count;
|
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;
|
int len;
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
|
@ -930,6 +930,8 @@ void QDECL Com_sprintf(char *dest, int size, const char *fmt, ...)
|
||||||
|
|
||||||
if(len >= size)
|
if(len >= size)
|
||||||
Com_Printf("Com_sprintf: Output length %d too short, require %d bytes.\n", size, len + 1);
|
Com_Printf("Com_sprintf: Output length %d too short, require %d bytes.\n", size, len + 1);
|
||||||
|
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -206,7 +206,7 @@ typedef int clipHandle_t;
|
||||||
#define MIN_QINT (-MAX_QINT-1)
|
#define MIN_QINT (-MAX_QINT-1)
|
||||||
|
|
||||||
#define ARRAY_LEN(x) (sizeof(x) / sizeof(*(x)))
|
#define ARRAY_LEN(x) (sizeof(x) / sizeof(*(x)))
|
||||||
|
#define STR_LEN(x) (ARRAY_LEN(x) - 1)
|
||||||
|
|
||||||
// angle indexes
|
// angle indexes
|
||||||
#define PITCH 0 // up / down
|
#define PITCH 0 // up / down
|
||||||
|
@ -750,7 +750,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);
|
void Parse3DMatrix (char **buf_p, int z, int y, int x, float *m);
|
||||||
int Com_HexStrToInt( const char *str );
|
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_SkipTokens( char *s, int numTokens, char *sep );
|
||||||
char *Com_SkipCharset( char *s, char *sep );
|
char *Com_SkipCharset( char *s, char *sep );
|
||||||
|
|
|
@ -197,7 +197,11 @@ typedef struct client_s {
|
||||||
// MAX_CHALLENGES is made large to prevent a denial
|
// MAX_CHALLENGES is made large to prevent a denial
|
||||||
// of service attack that could cycle all of them
|
// of service attack that could cycle all of them
|
||||||
// out before legitimate users connected
|
// 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
|
#define AUTHORIZE_TIMEOUT 5000
|
||||||
|
|
||||||
|
|
|
@ -55,8 +55,10 @@ void SV_GetChallenge(netadr_t from)
|
||||||
int i;
|
int i;
|
||||||
int oldest;
|
int oldest;
|
||||||
int oldestTime;
|
int oldestTime;
|
||||||
const char *clientChallenge = Cmd_Argv(1);
|
int oldestClientTime;
|
||||||
|
int clientChallenge;
|
||||||
challenge_t *challenge;
|
challenge_t *challenge;
|
||||||
|
qboolean wasfound = qfalse;
|
||||||
|
|
||||||
// ignore if we are in single player
|
// ignore if we are in single player
|
||||||
if ( Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER || Cvar_VariableValue("ui_singlePlayerActive")) {
|
if ( Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER || Cvar_VariableValue("ui_singlePlayerActive")) {
|
||||||
|
@ -64,15 +66,30 @@ void SV_GetChallenge(netadr_t from)
|
||||||
}
|
}
|
||||||
|
|
||||||
oldest = 0;
|
oldest = 0;
|
||||||
oldestTime = 0x7fffffff;
|
oldestClientTime = oldestTime = 0x7fffffff;
|
||||||
|
|
||||||
// see if we already have a challenge for this ip
|
// see if we already have a challenge for this ip
|
||||||
challenge = &svs.challenges[0];
|
challenge = &svs.challenges[0];
|
||||||
for (i = 0 ; i < MAX_CHALLENGES ; i++, challenge++) {
|
clientChallenge = atoi(Cmd_Argv(1));
|
||||||
if (!challenge->connected && NET_CompareAdr( from, challenge->adr ) ) {
|
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
if ( challenge->time < oldestTime ) {
|
|
||||||
|
if(challenge->time < oldestTime)
|
||||||
|
{
|
||||||
oldestTime = challenge->time;
|
oldestTime = challenge->time;
|
||||||
oldest = i;
|
oldest = i;
|
||||||
}
|
}
|
||||||
|
@ -82,17 +99,16 @@ void SV_GetChallenge(netadr_t from)
|
||||||
{
|
{
|
||||||
// this is the first time this client has asked for a challenge
|
// this is the first time this client has asked for a challenge
|
||||||
challenge = &svs.challenges[oldest];
|
challenge = &svs.challenges[oldest];
|
||||||
challenge->clientChallenge = 0;
|
challenge->clientChallenge = clientChallenge;
|
||||||
challenge->adr = from;
|
challenge->adr = from;
|
||||||
challenge->firstTime = svs.time;
|
challenge->firstTime = svs.time;
|
||||||
challenge->time = svs.time;
|
|
||||||
challenge->connected = qfalse;
|
challenge->connected = qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
// always generate a new challenge number, so the client cannot circumvent sv_maxping
|
// always generate a new challenge number, so the client cannot circumvent sv_maxping
|
||||||
challenge->challenge = ( (rand() << 16) ^ rand() ) ^ svs.time;
|
challenge->challenge = ( (rand() << 16) ^ rand() ) ^ svs.time;
|
||||||
challenge->wasrefused = qfalse;
|
challenge->wasrefused = qfalse;
|
||||||
|
challenge->time = svs.time;
|
||||||
|
|
||||||
#ifndef STANDALONE
|
#ifndef STANDALONE
|
||||||
// Drop the authorize stuff if this client is coming in via v6 as the auth server does not support ipv6.
|
// Drop the authorize stuff if this client is coming in via v6 as the auth server does not support ipv6.
|
||||||
|
@ -121,7 +137,7 @@ void SV_GetChallenge(netadr_t from)
|
||||||
// if they have been challenging for a long time and we
|
// if they have been challenging for a long time and we
|
||||||
// haven't heard anything from the authorize server, go ahead and
|
// haven't heard anything from the authorize server, go ahead and
|
||||||
// let them in, assuming the id server is down
|
// 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" );
|
Com_DPrintf( "authorize server timed out\n" );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -129,10 +145,6 @@ void SV_GetChallenge(netadr_t from)
|
||||||
cvar_t *fs;
|
cvar_t *fs;
|
||||||
char game[1024];
|
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 ));
|
Com_DPrintf( "sending getIpAuthorize for %s\n", NET_AdrToString( from ));
|
||||||
|
|
||||||
strcpy(game, BASEGAME);
|
strcpy(game, BASEGAME);
|
||||||
|
@ -153,7 +165,8 @@ void SV_GetChallenge(netadr_t from)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
challenge->pingTime = 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef STANDALONE
|
#ifndef STANDALONE
|
||||||
|
|
Loading…
Reference in a new issue