Rate limit getchallenge

This commit is contained in:
Tim Angus 2013-06-10 20:30:48 +01:00
parent 2937ac7661
commit 7b15415042
3 changed files with 39 additions and 20 deletions

View File

@ -308,6 +308,28 @@ extern cvar_t *sv_voip;
//
// sv_main.c
//
typedef struct leakyBucket_s leakyBucket_t;
struct leakyBucket_s {
netadrtype_t type;
union {
byte _4[4];
byte _6[16];
} ipv;
int lastTime;
signed char burst;
long hash;
leakyBucket_t *prev, *next;
};
extern leakyBucket_t outboundLeakyBucket;
qboolean SVC_RateLimit( leakyBucket_t *bucket, int burst, int period );
qboolean SVC_RateLimitAddress( netadr_t from, int burst, int period );
void SV_FinalMessage (char *message);
void QDECL SV_SendServerCommand( client_t *cl, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));

View File

@ -67,6 +67,20 @@ void SV_GetChallenge(netadr_t from)
return;
}
// Prevent using getchallenge as an amplifier
if ( SVC_RateLimitAddress( from, 10, 1000 ) ) {
Com_DPrintf( "SV_GetChallenge: rate limit from %s exceeded, dropping request\n",
NET_AdrToString( from ) );
return;
}
// Allow getchallenge to be DoSed relatively easily, but prevent
// excess outbound bandwidth usage when being flooded inbound
if ( SVC_RateLimit( &outboundLeakyBucket, 10, 100 ) ) {
Com_DPrintf( "SV_GetChallenge: rate limit exceeded, dropping request\n" );
return;
}
gameName = Cmd_Argv(2);
#ifdef LEGACY_PROTOCOL

View File

@ -354,30 +354,13 @@ CONNECTIONLESS COMMANDS
==============================================================================
*/
typedef struct leakyBucket_s leakyBucket_t;
struct leakyBucket_s {
netadrtype_t type;
union {
byte _4[4];
byte _6[16];
} ipv;
int lastTime;
signed char burst;
long hash;
leakyBucket_t *prev, *next;
};
// This is deliberately quite large to make it more of an effort to DoS
#define MAX_BUCKETS 16384
#define MAX_HASHES 1024
static leakyBucket_t buckets[ MAX_BUCKETS ];
static leakyBucket_t *bucketHashes[ MAX_HASHES ];
static leakyBucket_t outboundLeakyBucket;
leakyBucket_t outboundLeakyBucket;
/*
================
@ -494,7 +477,7 @@ static leakyBucket_t *SVC_BucketForAddress( netadr_t address, int burst, int per
SVC_RateLimit
================
*/
static qboolean SVC_RateLimit( leakyBucket_t *bucket, int burst, int period ) {
qboolean SVC_RateLimit( leakyBucket_t *bucket, int burst, int period ) {
if ( bucket != NULL ) {
int now = Sys_Milliseconds();
int interval = now - bucket->lastTime;
@ -526,7 +509,7 @@ SVC_RateLimitAddress
Rate limit for a particular address
================
*/
static qboolean SVC_RateLimitAddress( netadr_t from, int burst, int period ) {
qboolean SVC_RateLimitAddress( netadr_t from, int burst, int period ) {
leakyBucket_t *bucket = SVC_BucketForAddress( from, burst, period );
return SVC_RateLimit( bucket, burst, period );