diff options
-rw-r--r-- | src/client/cl_main.c | 47 | ||||
-rw-r--r-- | src/client/cl_net_chan.c | 6 | ||||
-rw-r--r-- | src/qcommon/net_chan.c | 25 | ||||
-rw-r--r-- | src/qcommon/q_shared.c | 4 | ||||
-rw-r--r-- | src/qcommon/q_shared.h | 2 | ||||
-rw-r--r-- | src/qcommon/qcommon.h | 9 | ||||
-rw-r--r-- | src/server/server.h | 6 | ||||
-rw-r--r-- | src/server/sv_client.c | 48 |
8 files changed, 53 insertions, 94 deletions
diff --git a/src/client/cl_main.c b/src/client/cl_main.c index 128db604..d357334f 100644 --- a/src/client/cl_main.c +++ b/src/client/cl_main.c @@ -585,6 +585,7 @@ void CL_WriteDemoMessage ( msg_t *msg, int headerBytes ) { len = clc.serverMessageSequence; swlen = LittleLong( len ); FS_Write (&swlen, 4, clc.demofile); + // skip the packet sequencing information len = msg->cursize - headerBytes; swlen = LittleLong(len); @@ -716,6 +717,7 @@ void CL_Record_f( void ) { clc.spDemoRecording = qfalse; } + Q_strncpyz( clc.demoName, demoName, sizeof( clc.demoName ) ); // don't start saving messages until a non-delta compressed message is received @@ -939,13 +941,14 @@ void CL_ReadDemoMessage( void ) { CL_WalkDemoExt ==================== */ -static int CL_WalkDemoExt(char *arg, char *name, int *demofile) +static void CL_WalkDemoExt(char *arg, char *name, int *demofile) { int i = 0; *demofile = 0; - Com_sprintf(name, MAX_OSPATH, "demos/%s.%s%d", arg, DEMOEXT, PROTOCOL_VERSION); - FS_FOpenFileRead(name, demofile, qtrue); + Com_sprintf (name, MAX_OSPATH, "demos/%s.%s%d", arg, DEMOEXT, PROTOCOL_VERSION); + + FS_FOpenFileRead( name, demofile, qtrue ); if (*demofile) { @@ -957,23 +960,17 @@ static int CL_WalkDemoExt(char *arg, char *name, int *demofile) while(demo_protocols[i]) { - if(demo_protocols[i] == PROTOCOL_VERSION) - continue; - Com_sprintf (name, MAX_OSPATH, "demos/%s.%s%d", arg, DEMOEXT, demo_protocols[i]); FS_FOpenFileRead( name, demofile, qtrue ); if (*demofile) { Com_Printf("Demo file: %s\n", name); - - return demo_protocols[i]; + break; } else Com_Printf("Not found: %s\n", name); i++; } - - return -1; } /* @@ -1050,11 +1047,11 @@ void CL_PlayDemo_f( void ) { Q_strncpyz(retry, arg, len + 1); retry[len] = '\0'; - protocol = CL_WalkDemoExt(retry, name, &clc.demofile); + CL_WalkDemoExt(retry, name, &clc.demofile); } } else - protocol = CL_WalkDemoExt(arg, name, &clc.demofile); + CL_WalkDemoExt(arg, name, &clc.demofile); if (!clc.demofile) { Com_Error( ERR_DROP, "couldn't open %s", name); @@ -2606,7 +2603,6 @@ Responses to broadcasts, etc void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) { char *s; char *c; - int challenge; MSG_BeginReadingOOB( msg ); MSG_ReadLong( msg ); // skip the -1 @@ -2628,17 +2624,15 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) { return; } - c = Cmd_Argv(2); - if(*c) - challenge = atoi(c); - if(!NET_CompareAdr(from, clc.serverAddress)) { // This challenge response is not coming from the expected address. // Check whether we have a matching client challenge to prevent // connection hi-jacking. - - if(!*c || challenge != clc.challenge) + + c = Cmd_Argv(2); + + if(!*c || atoi(c) != clc.challenge) { Com_DPrintf("Challenge response received from unexpected source. Ignored.\n"); return; @@ -2672,10 +2666,7 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) { Com_Printf( "connectResponse from wrong address. Ignored.\n" ); return; } - - Netchan_Setup(NS_CLIENT, &clc.netchan, from, Cvar_VariableValue("net_qport"), - clc.challenge); - + Netchan_Setup (NS_CLIENT, &clc.netchan, from, Cvar_VariableValue( "net_qport" ) ); cls.state = CA_CONNECTED; clc.lastPacketSentTime = -9999; // send first packet immediately return; @@ -2693,6 +2684,13 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) { return; } + // a disconnect message from the server, which will happen if the server + // dropped the connection but it is still getting packets from us + if (!Q_stricmp(c, "disconnect")) { + CL_DisconnectPacket( from ); + return; + } + // echo request from server if ( !Q_stricmp(c, "echo") ) { NET_OutOfBandPrint( NS_CLIENT, from, "%s", Cmd_Argv(1) ); @@ -2706,9 +2704,8 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) { } // echo request from server - if(!Q_stricmp(c, "print")){ + if ( !Q_stricmp(c, "print") ) { s = MSG_ReadString( msg ); - Q_strncpyz( clc.serverMessage, s, sizeof( clc.serverMessage ) ); while( clc.serverMessage[ strlen( clc.serverMessage ) - 1 ] == '\n' ) diff --git a/src/client/cl_net_chan.c b/src/client/cl_net_chan.c index fbfc4dc9..561f322a 100644 --- a/src/client/cl_net_chan.c +++ b/src/client/cl_net_chan.c @@ -148,6 +148,9 @@ void CL_Netchan_Transmit( netchan_t *chan, msg_t* msg ) { Netchan_Transmit( chan, msg->cursize, msg->data ); } +extern int oldsize; +int newsize = 0; + /* ================= CL_Netchan_Process @@ -159,8 +162,7 @@ qboolean CL_Netchan_Process( netchan_t *chan, msg_t *msg ) { ret = Netchan_Process( chan, msg ); if (!ret) return qfalse; - CL_Netchan_Decode( msg ); - + newsize += msg->cursize; return qtrue; } diff --git a/src/qcommon/net_chan.c b/src/qcommon/net_chan.c index 67ef54e0..4aacfa7e 100644 --- a/src/qcommon/net_chan.c +++ b/src/qcommon/net_chan.c @@ -84,8 +84,7 @@ Netchan_Setup called to open a channel to a remote system ============== */ -void Netchan_Setup(netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, int challenge) -{ +void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport ) { Com_Memset (chan, 0, sizeof(*chan)); chan->sock = sock; @@ -192,21 +191,17 @@ void Netchan_TransmitNextFragment( netchan_t *chan ) { msg_t send; byte send_buf[MAX_PACKETLEN]; int fragmentLength; - int outgoingSequence; // write the packet header MSG_InitOOB (&send, send_buf, sizeof(send_buf)); // <-- only do the oob here - outgoingSequence = chan->outgoingSequence | FRAGMENT_BIT; - MSG_WriteLong(&send, outgoingSequence); + MSG_WriteLong( &send, chan->outgoingSequence | FRAGMENT_BIT ); // send the qport if we are a client if ( chan->sock == NS_CLIENT ) { MSG_WriteShort( &send, qport->integer ); } - MSG_WriteLong(&send, NETCHAN_GENCHECKSUM(chan->challenge, chan->outgoingSequence)); - // copy the reliable message to the packet first fragmentLength = FRAGMENT_SIZE; if ( chan->unsentFragmentStart + fragmentLength > chan->unsentLength ) { @@ -274,14 +269,12 @@ void Netchan_Transmit( netchan_t *chan, int length, const byte *data ) { MSG_InitOOB (&send, send_buf, sizeof(send_buf)); MSG_WriteLong( &send, chan->outgoingSequence ); + chan->outgoingSequence++; // send the qport if we are a client - if(chan->sock == NS_CLIENT) - MSG_WriteShort(&send, qport->integer); - - MSG_WriteLong(&send, NETCHAN_GENCHECKSUM(chan->challenge, chan->outgoingSequence)); - - chan->outgoingSequence++; + if ( chan->sock == NS_CLIENT ) { + MSG_WriteShort( &send, qport->integer ); + } MSG_WriteData( &send, data, length ); @@ -335,12 +328,6 @@ qboolean Netchan_Process( netchan_t *chan, msg_t *msg ) { qport = MSG_ReadShort( msg ); } - int checksum = MSG_ReadLong(msg); - - // UDP spoofing protection - if(NETCHAN_GENCHECKSUM(chan->challenge, sequence) != checksum) - return qfalse; - // read the fragment information if ( fragmented ) { fragmentStart = MSG_ReadShort( msg ); diff --git a/src/qcommon/q_shared.c b/src/qcommon/q_shared.c index 9f7600b6..b4846799 100644 --- a/src/qcommon/q_shared.c +++ b/src/qcommon/q_shared.c @@ -981,7 +981,7 @@ void Q_ParseNewlines( char *dest, const char *src, int destsize ) *dest++ = '\0'; } -int QDECL Com_sprintf(char *dest, int size, const char *fmt, ...) +void QDECL Com_sprintf(char *dest, int size, const char *fmt, ...) { int len; va_list argptr; @@ -992,8 +992,6 @@ int QDECL Com_sprintf(char *dest, int size, const char *fmt, ...) if(len >= size) Com_Printf("Com_sprintf: Output length %d too short, require %d bytes.\n", size, len); - - return len; } /* diff --git a/src/qcommon/q_shared.h b/src/qcommon/q_shared.h index b4ddc35e..1cedf6a8 100644 --- a/src/qcommon/q_shared.h +++ b/src/qcommon/q_shared.h @@ -741,7 +741,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); int Com_HexStrToInt( const char *str ); -int QDECL Com_sprintf (char *dest, int size, const char *fmt, ...) __attribute__ ((format (printf, 3, 4))); +void 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_SkipCharset( char *s, char *sep ); diff --git a/src/qcommon/qcommon.h b/src/qcommon/qcommon.h index affde995..d09ee299 100644 --- a/src/qcommon/qcommon.h +++ b/src/qcommon/qcommon.h @@ -192,8 +192,7 @@ void NET_Sleep(int msec); #define MAX_DOWNLOAD_WINDOW 8 // max of eight download frames #define MAX_DOWNLOAD_BLKSIZE 2048 // 2048 byte block chunks - -#define NETCHAN_GENCHECKSUM(challenge, sequence) ((challenge) ^ ((sequence) * (challenge))) + /* Netchan handles packet fragmentation and out of order / duplicate suppression @@ -222,12 +221,10 @@ typedef struct { int unsentFragmentStart; int unsentLength; byte unsentBuffer[MAX_MSGLEN]; - - int challenge; } netchan_t; void Netchan_Init( int qport ); -void Netchan_Setup(netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, int challenge); +void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport ); void Netchan_Transmit( netchan_t *chan, int length, const byte *data ); void Netchan_TransmitNextFragment( netchan_t *chan ); @@ -243,7 +240,7 @@ PROTOCOL ============================================================== */ -#define PROTOCOL_VERSION 71 +#define PROTOCOL_VERSION 70 // maintain a list of compatible protocols for demo playing // NOTE: that stuff only works with two digits protocols diff --git a/src/server/server.h b/src/server/server.h index 697d8a30..af3ebe7c 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -205,11 +205,7 @@ typedef struct client_s { // MAX_CHALLENGES is made large to prevent a denial // of service attack that could cycle all of them // out before legitimate users connected -#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 MAX_CHALLENGES 1024 #define AUTHORIZE_TIMEOUT 5000 diff --git a/src/server/sv_client.c b/src/server/sv_client.c index f69155c6..40212b0c 100644 --- a/src/server/sv_client.c +++ b/src/server/sv_client.c @@ -56,36 +56,19 @@ void SV_GetChallenge(netadr_t from) int i; int oldest; int oldestTime; - int oldestClientTime; - int clientChallenge; + const char *clientChallenge = Cmd_Argv(1); challenge_t *challenge; - qboolean wasfound = qfalse; oldest = 0; - oldestClientTime = oldestTime = 0x7fffffff; + oldestTime = 0x7fffffff; // see if we already have a challenge for this ip challenge = &svs.challenges[0]; - clientChallenge = atoi(Cmd_Argv(1)); - - 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; + for (i = 0 ; i < MAX_CHALLENGES ; i++, challenge++) { + if (!challenge->connected && NET_CompareAdr( from, challenge->adr ) ) { break; } - - if(challenge->time < oldestTime) - { + if ( challenge->time < oldestTime ) { oldestTime = challenge->time; oldest = i; } @@ -95,19 +78,20 @@ void SV_GetChallenge(netadr_t from) { // this is the first time this client has asked for a challenge challenge = &svs.challenges[oldest]; - challenge->clientChallenge = clientChallenge; + challenge->clientChallenge = 0; challenge->adr = from; challenge->firstTime = svs.time; + challenge->time = svs.time; challenge->connected = qfalse; } // always generate a new challenge number, so the client cannot circumvent sv_maxping challenge->challenge = ( (rand() << 16) ^ rand() ) ^ svs.time; - challenge->wasrefused = qfalse; + challenge->time = svs.time; challenge->pingTime = svs.time; - NET_OutOfBandPrint( NS_SERVER, challenge->adr, "challengeResponse %i %d", challenge->challenge, clientChallenge); + NET_OutOfBandPrint( NS_SERVER, challenge->adr, "challengeResponse %i %s", challenge->challenge, clientChallenge); } /* @@ -137,12 +121,10 @@ void SV_DirectConnect( netadr_t from ) { Q_strncpyz( userinfo, Cmd_Argv(1), sizeof(userinfo) ); - version = atoi(Info_ValueForKey(userinfo, "protocol")); - if(version != PROTOCOL_VERSION) - { - NET_OutOfBandPrint(NS_SERVER, from, "print\nServer uses protocol version %i " - "(yours is %i).\n", com_protocol->integer, version); - Com_DPrintf(" rejected connect from version %i\n", version); + version = atoi( Info_ValueForKey( userinfo, "protocol" ) ); + if ( version != PROTOCOL_VERSION ) { + NET_OutOfBandPrint( NS_SERVER, from, "print\nServer uses protocol version %i\n", PROTOCOL_VERSION ); + Com_DPrintf (" rejected connect from version %i\n", version); return; } @@ -310,7 +292,7 @@ gotnewcl: newcl->challenge = challenge; // save the address - Netchan_Setup(NS_SERVER, &newcl->netchan, from, qport, challenge); + Netchan_Setup (NS_SERVER, &newcl->netchan , from, qport); // init the netchan queue newcl->netchan_end_queue = &newcl->netchan_start_queue; @@ -331,7 +313,7 @@ gotnewcl: SV_UserinfoChanged( newcl ); // send the connect packet to the client - NET_OutOfBandPrint(NS_SERVER, from, "connectResponse %d", challenge); + NET_OutOfBandPrint( NS_SERVER, from, "connectResponse" ); Com_DPrintf( "Going from CS_FREE to CS_CONNECTED for %s\n", newcl->name ); |