From 46aaeb56660ef727c30841718331fef45e8377be Mon Sep 17 00:00:00 2001 From: Thilo Schulz Date: Fri, 15 Jul 2011 16:51:54 +0000 Subject: Move rate limiting / queued packet sending logic from Com_Frame() to sv_main.c --- src/server/server.h | 3 ++ src/server/sv_init.c | 1 + src/server/sv_main.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+) (limited to 'src/server') diff --git a/src/server/server.h b/src/server/server.h index 9fcce725..3f3c2a3b 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -272,6 +272,7 @@ extern cvar_t *sv_mapChecksum; extern cvar_t *sv_serverid; extern cvar_t *sv_minRate; extern cvar_t *sv_maxRate; +extern cvar_t *sv_dlRate; extern cvar_t *sv_minPing; extern cvar_t *sv_maxPing; extern cvar_t *sv_pure; @@ -338,6 +339,8 @@ void SV_ExecuteClientCommand( client_t *cl, const char *s, qboolean clientOK ); void SV_ClientThink (client_t *cl, usercmd_t *cmd); int SV_WriteDownloadToClient(client_t *cl , msg_t *msg); +int SV_SendDownloadMessages(void); +int SV_SendQueuedMessages(void); #ifdef USE_VOIP void SV_WriteVoipToClient( client_t *cl, msg_t *msg ); diff --git a/src/server/sv_init.c b/src/server/sv_init.c index 4c0ae128..c5d11e74 100644 --- a/src/server/sv_init.c +++ b/src/server/sv_init.c @@ -634,6 +634,7 @@ void SV_Init (void) sv_minRate = Cvar_Get ("sv_minRate", "0", CVAR_ARCHIVE | CVAR_SERVERINFO ); sv_maxRate = Cvar_Get ("sv_maxRate", "0", CVAR_ARCHIVE | CVAR_SERVERINFO ); + sv_dlRate = Cvar_Get("sv_dlRate", "100", CVAR_ARCHIVE | CVAR_SERVERINFO); sv_minPing = Cvar_Get ("sv_minPing", "0", CVAR_ARCHIVE | CVAR_SERVERINFO ); sv_maxPing = Cvar_Get ("sv_maxPing", "0", CVAR_ARCHIVE | CVAR_SERVERINFO ); diff --git a/src/server/sv_main.c b/src/server/sv_main.c index 166e2241..fdd7127b 100644 --- a/src/server/sv_main.c +++ b/src/server/sv_main.c @@ -51,6 +51,7 @@ cvar_t *sv_mapChecksum; cvar_t *sv_serverid; cvar_t *sv_minRate; cvar_t *sv_maxRate; +cvar_t *sv_dlRate; cvar_t *sv_minPing; cvar_t *sv_maxPing; cvar_t *sv_pure; @@ -1188,3 +1189,83 @@ int SV_RateMsec(client_t *client) else return rateMsec - rate; } + +/* +==================== +SV_SendQueuedPackets + +Send download messages and queued packets in the time that we're idle, i.e. +not computing a server frame or sending client snapshots. +Return the time in msec until we expect to be called next +==================== +*/ + +int SV_SendQueuedPackets() +{ + int numBlocks; + int dlStart, deltaT, delayT; + static int dlNextRound = 0; + int timeVal = INT_MAX; + + // Send out fragmented packets now that we're idle + delayT = SV_SendQueuedMessages(); + if(delayT >= 0) + timeVal = delayT; + + if(sv_dlRate->integer) + { + // Rate limiting. This is very imprecise for high + // download rates due to millisecond timedelta resolution + dlStart = Sys_Milliseconds(); + deltaT = dlNextRound - dlStart; + + if(deltaT > 0) + { + if(deltaT < timeVal) + timeVal = deltaT + 1; + } + else + { + numBlocks = SV_SendDownloadMessages(); + + if(numBlocks) + { + // There are active downloads + deltaT = Sys_Milliseconds() - dlStart; + + delayT = 1000 * numBlocks * MAX_DOWNLOAD_BLKSIZE; + delayT /= sv_dlRate->integer * 1024; + + if(delayT <= deltaT + 1) + { + // Sending the last round of download messages + // took too long for given rate, don't wait for + // next round, but always enforce a 1ms delay + // between DL message rounds so we don't hog + // all of the bandwidth. This will result in an + // effective maximum rate of 1MB/s per user, but the + // low download window size limits this anyways. + if(timeVal > 2) + timeVal = 2; + + dlNextRound = dlStart + deltaT + 1; + } + else + { + dlNextRound = dlStart + delayT; + delayT -= deltaT; + + if(delayT < timeVal) + timeVal = delayT; + } + } + } + } + else + { + if(SV_SendDownloadMessages()) + timeVal = 0; + } + + return timeVal; +} -- cgit