Rate limit getchallenge
This commit is contained in:
parent
2937ac7661
commit
7b15415042
3 changed files with 39 additions and 20 deletions
|
@ -308,6 +308,28 @@ extern cvar_t *sv_voip;
|
||||||
//
|
//
|
||||||
// sv_main.c
|
// 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 SV_FinalMessage (char *message);
|
||||||
void QDECL SV_SendServerCommand( client_t *cl, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
|
void QDECL SV_SendServerCommand( client_t *cl, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,20 @@ void SV_GetChallenge(netadr_t from)
|
||||||
return;
|
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);
|
gameName = Cmd_Argv(2);
|
||||||
|
|
||||||
#ifdef LEGACY_PROTOCOL
|
#ifdef LEGACY_PROTOCOL
|
||||||
|
|
|
@ -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
|
// This is deliberately quite large to make it more of an effort to DoS
|
||||||
#define MAX_BUCKETS 16384
|
#define MAX_BUCKETS 16384
|
||||||
#define MAX_HASHES 1024
|
#define MAX_HASHES 1024
|
||||||
|
|
||||||
static leakyBucket_t buckets[ MAX_BUCKETS ];
|
static leakyBucket_t buckets[ MAX_BUCKETS ];
|
||||||
static leakyBucket_t *bucketHashes[ MAX_HASHES ];
|
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
|
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 ) {
|
if ( bucket != NULL ) {
|
||||||
int now = Sys_Milliseconds();
|
int now = Sys_Milliseconds();
|
||||||
int interval = now - bucket->lastTime;
|
int interval = now - bucket->lastTime;
|
||||||
|
@ -526,7 +509,7 @@ SVC_RateLimitAddress
|
||||||
Rate limit for a particular address
|
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 );
|
leakyBucket_t *bucket = SVC_BucketForAddress( from, burst, period );
|
||||||
|
|
||||||
return SVC_RateLimit( bucket, burst, period );
|
return SVC_RateLimit( bucket, burst, period );
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue