From 2bf2118d79994cfd805c3ffb5b421c6a65658b84 Mon Sep 17 00:00:00 2001 From: Thilo Schulz Date: Wed, 13 Jul 2011 17:11:30 +0000 Subject: - Improve snapshot rate and data rate control - Make server send packet fragments and queued packets when server is idle - Voip protocol detection is tied to com_protocol making past-end-of-message reading unncessary - Use Hunk_AllocateTempMemory() for buffering VOIP packets and fix buffering scheme that ryan hates so much - Disable packet scrambling for new protocol as it is useless now - Get rid of the old packet scrambling functions predating latest point release - Use Hunk_AllocateTempMemory() for netchan packet queue to fix memory leak when client gets disconnected with packets in the queue - Use Hunk_AllocateTempMemory() for download blocks to fix memory leak when client gets disconnected with download blocks in the queue - Fix SV_RateMsec to account for udp/udp6 packet lengths --- src/qcommon/common.c | 21 +++++++++-- src/qcommon/net_chan.c | 96 +++++--------------------------------------------- src/qcommon/qcommon.h | 12 +++---- 3 files changed, 32 insertions(+), 97 deletions(-) (limited to 'src/qcommon') diff --git a/src/qcommon/common.c b/src/qcommon/common.c index da0e8967..8732eab6 100644 --- a/src/qcommon/common.c +++ b/src/qcommon/common.c @@ -2948,7 +2948,11 @@ void Com_Frame( void ) { { if(com_sv_running->integer) { - // Send out download messages now that we're idle + // Send out fragmented packets now that we're idle + delayT = SV_SendQueuedMessages(); + if(delayT >= 0 && delayT < timeVal) + timeVal = delayT; + if(sv_dlRate->integer) { // Rate limiting. This is very imprecise for high @@ -2982,21 +2986,32 @@ void Com_Frame( void ) { // 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. - timeVal = 2; + if(timeVal > 2) + timeVal = 2; + dlNextRound = dlStart + deltaT + 1; } else { dlNextRound = dlStart + delayT; - timeVal = delayT - deltaT; + delayT -= deltaT; + + if(delayT < timeVal) + timeVal = delayT; } } } } else + { SV_SendDownloadMessages(); + timeVal = 1; + } } + if(timeVal == 0) + timeVal = 1; + if(com_busyWait->integer) NET_Sleep(0); else diff --git a/src/qcommon/net_chan.c b/src/qcommon/net_chan.c index d9c6760b..8f2d8de7 100644 --- a/src/qcommon/net_chan.c +++ b/src/qcommon/net_chan.c @@ -96,92 +96,6 @@ void Netchan_Setup(netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, int chan->challenge = challenge; } -// TTimo: unused, commenting out to make gcc happy -#if 0 -/* -============== -Netchan_ScramblePacket - -A probably futile attempt to make proxy hacking somewhat -more difficult. -============== -*/ -#define SCRAMBLE_START 6 -static void Netchan_ScramblePacket( msg_t *buf ) { - unsigned seed; - int i, j, c, mask, temp; - int seq[MAX_PACKETLEN]; - - seed = ( LittleLong( *(unsigned *)buf->data ) * 3 ) ^ ( buf->cursize * 123 ); - c = buf->cursize; - if ( c <= SCRAMBLE_START ) { - return; - } - if ( c > MAX_PACKETLEN ) { - Com_Error( ERR_DROP, "MAX_PACKETLEN" ); - } - - // generate a sequence of "random" numbers - for (i = 0 ; i < c ; i++) { - seed = (119 * seed + 1); - seq[i] = seed; - } - - // transpose each character - for ( mask = 1 ; mask < c-SCRAMBLE_START ; mask = ( mask << 1 ) + 1 ) { - } - mask >>= 1; - for (i = SCRAMBLE_START ; i < c ; i++) { - j = SCRAMBLE_START + ( seq[i] & mask ); - temp = buf->data[j]; - buf->data[j] = buf->data[i]; - buf->data[i] = temp; - } - - // byte xor the data after the header - for (i = SCRAMBLE_START ; i < c ; i++) { - buf->data[i] ^= seq[i]; - } -} - -static void Netchan_UnScramblePacket( msg_t *buf ) { - unsigned seed; - int i, j, c, mask, temp; - int seq[MAX_PACKETLEN]; - - seed = ( LittleLong( *(unsigned *)buf->data ) * 3 ) ^ ( buf->cursize * 123 ); - c = buf->cursize; - if ( c <= SCRAMBLE_START ) { - return; - } - if ( c > MAX_PACKETLEN ) { - Com_Error( ERR_DROP, "MAX_PACKETLEN" ); - } - - // generate a sequence of "random" numbers - for (i = 0 ; i < c ; i++) { - seed = (119 * seed + 1); - seq[i] = seed; - } - - // byte xor the data after the header - for (i = SCRAMBLE_START ; i < c ; i++) { - buf->data[i] ^= seq[i]; - } - - // transpose each character in reverse order - for ( mask = 1 ; mask < c-SCRAMBLE_START ; mask = ( mask << 1 ) + 1 ) { - } - mask >>= 1; - for (i = c-1 ; i >= SCRAMBLE_START ; i--) { - j = SCRAMBLE_START + ( seq[i] & mask ); - temp = buf->data[j]; - buf->data[j] = buf->data[i]; - buf->data[i] = temp; - } -} -#endif - /* ================= Netchan_TransmitNextFragment @@ -219,7 +133,11 @@ void Netchan_TransmitNextFragment( netchan_t *chan ) { MSG_WriteData( &send, chan->unsentBuffer + chan->unsentFragmentStart, fragmentLength ); // send the datagram - NET_SendPacket( chan->sock, send.cursize, send.data, chan->remoteAddress ); + NET_SendPacket(chan->sock, send.cursize, send.data, chan->remoteAddress); + + // Store send time and size of this packet for rate control + chan->lastSentTime = Sys_Milliseconds(); + chan->lastSentSize = send.cursize; if ( showpackets->integer ) { Com_Printf ("%s send %4i : s=%i fragment=%i,%i\n" @@ -289,6 +207,10 @@ void Netchan_Transmit( netchan_t *chan, int length, const byte *data ) { // send the datagram NET_SendPacket( chan->sock, send.cursize, send.data, chan->remoteAddress ); + // Store send time and size of this packet for rate control + chan->lastSentTime = Sys_Milliseconds(); + chan->lastSentSize = send.cursize; + if ( showpackets->integer ) { Com_Printf( "%s send %4i : s=%i ack=%i\n" , netsrcString[ chan->sock ] diff --git a/src/qcommon/qcommon.h b/src/qcommon/qcommon.h index 28834168..49501d52 100644 --- a/src/qcommon/qcommon.h +++ b/src/qcommon/qcommon.h @@ -225,6 +225,8 @@ typedef struct { byte unsentBuffer[MAX_MSGLEN]; int challenge; + int lastSentTime; + int lastSentSize; } netchan_t; void Netchan_Init( int qport ); @@ -277,9 +279,7 @@ enum svc_ops_e { svc_snapshot, svc_EOF, - // svc_extension follows a svc_EOF, followed by another svc_* ... - // this keeps legacy clients compatible. - svc_extension, +// new commands, supported only by ioquake3 protocol but not legacy svc_voip, // not wrapped in USE_VOIP, so this value is reserved. }; @@ -295,9 +295,7 @@ enum clc_ops_e { clc_clientCommand, // [string] message clc_EOF, - // clc_extension follows a clc_EOF, followed by another clc_* ... - // this keeps legacy servers compatible. - clc_extension, +// new commands, supported only by ioquake3 protocol but not legacy clc_voip, // not wrapped in USE_VOIP, so this value is reserved. }; @@ -1013,7 +1011,7 @@ void SV_PacketEvent( netadr_t from, msg_t *msg ); int SV_FrameMsec(void); qboolean SV_GameCommand( void ); int SV_SendDownloadMessages(void); - +int SV_SendQueuedMessages(void); // // UI interface -- cgit