From d899c25c571ed061bba9725cf7b35d492cc6e518 Mon Sep 17 00:00:00 2001 From: Tim Angus Date: Wed, 21 Mar 2007 23:55:51 +0000 Subject: * ioq3-r1052 merge --- src/server/sv_client.c | 75 +++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 29 deletions(-) (limited to 'src/server/sv_client.c') diff --git a/src/server/sv_client.c b/src/server/sv_client.c index e128b579..323ef602 100644 --- a/src/server/sv_client.c +++ b/src/server/sv_client.c @@ -103,6 +103,7 @@ void SV_DirectConnect( netadr_t from ) { int startIndex; intptr_t denied; int count; + char *ip; Com_DPrintf ("SVC_DirectConnect ()\n"); @@ -134,6 +135,19 @@ void SV_DirectConnect( netadr_t from ) { break; } } + + // don't let "ip" overflow userinfo string + if ( NET_IsLocalAddress (from) ) + ip = "localhost"; + else + ip = (char *)NET_AdrToString( from ); + if( ( strlen( ip ) + strlen( userinfo ) + 4 ) >= MAX_INFO_STRING ) { + NET_OutOfBandPrint( NS_SERVER, from, + "print\nUserinfo string length exceeded. " + "Try removing setu cvars from your config.\n" ); + return; + } + Info_SetValueForKey( userinfo, "ip", ip ); // see if the challenge is valid (LAN clients don't need to challenge) if ( !NET_IsLocalAddress (from) ) { @@ -150,8 +164,6 @@ void SV_DirectConnect( netadr_t from ) { NET_OutOfBandPrint( NS_SERVER, from, "print\nNo or bad challenge for address" ); return; } - // force the IP key/value pair so the game can filter based on ip - Info_SetValueForKey( userinfo, "ip", NET_AdrToString( from ) ); ping = svs.time - svs.challenges[i].pingTime; Com_Printf( "Client %i connecting with %i challenge ping\n", i, ping ); @@ -174,9 +186,6 @@ void SV_DirectConnect( netadr_t from ) { return; } } - } else { - // force the "ip" info key to "localhost" - Info_SetValueForKey( userinfo, "ip", "localhost" ); } newcl = &temp; @@ -342,8 +351,6 @@ void SV_DropClient( client_t *drop, const char *reason ) { // tell everyone why they got dropped SV_SendServerCommand( NULL, "print \"%s" S_COLOR_WHITE " %s\n\"", drop->name, reason ); - Com_DPrintf( "Going to CS_ZOMBIE for %s\n", drop->name ); - drop->state = CS_ZOMBIE; // become free in a few seconds if (drop->download) { FS_FCloseFile( drop->download ); @@ -359,6 +366,9 @@ void SV_DropClient( client_t *drop, const char *reason ) { // nuke user info SV_SetUserinfo( drop - svs.clients, "" ); + + Com_DPrintf( "Going to CS_ZOMBIE for %s\n", drop->name ); + drop->state = CS_ZOMBIE; // become free in a few seconds // if this was the last client on the server, send a heartbeat // to the master so it is known the server is empty @@ -524,7 +534,7 @@ Abort a download if in progress */ void SV_StopDownload_f( client_t *cl ) { if (*cl->downloadName) - Com_DPrintf( "clientDownload: %d : file \"%s\" aborted\n", cl - svs.clients, cl->downloadName ); + Com_DPrintf( "clientDownload: %d : file \"%s\" aborted\n", (int) (cl - svs.clients), cl->downloadName ); SV_CloseDownload( cl ); } @@ -555,11 +565,11 @@ void SV_NextDownload_f( client_t *cl ) int block = atoi( Cmd_Argv(1) ); if (block == cl->downloadClientBlock) { - Com_DPrintf( "clientDownload: %d : client acknowledge of block %d\n", cl - svs.clients, block ); + Com_DPrintf( "clientDownload: %d : client acknowledge of block %d\n", (int) (cl - svs.clients), block ); // Find out if we are done. A zero-length block indicates EOF if (cl->downloadBlockSize[cl->downloadClientBlock % MAX_DOWNLOAD_WINDOW] == 0) { - Com_Printf( "clientDownload: %d : file \"%s\" completed\n", cl - svs.clients, cl->downloadName ); + Com_Printf( "clientDownload: %d : file \"%s\" completed\n", (int) (cl - svs.clients), cl->downloadName ); SV_CloseDownload( cl ); return; } @@ -654,11 +664,11 @@ void SV_WriteDownloadToClient( client_t *cl , msg_t *msg ) // cannot auto-download file if(unreferenced) { - Com_Printf("clientDownload: %d : \"%s\" is not referenced and cannot be downloaded.\n", cl - svs.clients, cl->downloadName); + Com_Printf("clientDownload: %d : \"%s\" is not referenced and cannot be downloaded.\n", (int) (cl - svs.clients), cl->downloadName); Com_sprintf(errorMessage, sizeof(errorMessage), "File \"%s\" is not referenced and cannot be downloaded.", cl->downloadName); } else if (idPack) { - Com_Printf("clientDownload: %d : \"%s\" cannot download id pk3 files\n", cl - svs.clients, cl->downloadName); + Com_Printf("clientDownload: %d : \"%s\" cannot download id pk3 files\n", (int) (cl - svs.clients), cl->downloadName); if (missionPack) { Com_sprintf(errorMessage, sizeof(errorMessage), "Cannot autodownload Team Arena file \"%s\"\n" "The Team Arena mission pack can be found in your local game store.", cl->downloadName); @@ -670,7 +680,7 @@ void SV_WriteDownloadToClient( client_t *cl , msg_t *msg ) else if ( !(sv_allowDownload->integer & DLF_ENABLE) || (sv_allowDownload->integer & DLF_NO_UDP) ) { - Com_Printf("clientDownload: %d : \"%s\" download disabled", cl - svs.clients, cl->downloadName); + Com_Printf("clientDownload: %d : \"%s\" download disabled", (int) (cl - svs.clients), cl->downloadName); if (sv_pure->integer) { Com_sprintf(errorMessage, sizeof(errorMessage), "Could not download \"%s\" because autodownloading is disabled on the server.\n\n" "You will need to get this file elsewhere before you " @@ -684,7 +694,7 @@ void SV_WriteDownloadToClient( client_t *cl , msg_t *msg ) } else { // NOTE TTimo this is NOT supposed to happen unless bug in our filesystem scheme? // if the pk3 is referenced, it must have been found somewhere in the filesystem - Com_Printf("clientDownload: %d : \"%s\" file not found on server\n", cl - svs.clients, cl->downloadName); + Com_Printf("clientDownload: %d : \"%s\" file not found on server\n", (int) (cl - svs.clients), cl->downloadName); Com_sprintf(errorMessage, sizeof(errorMessage), "File \"%s\" not found on server for autodownloading.\n", cl->downloadName); } MSG_WriteByte( msg, svc_download ); @@ -696,7 +706,7 @@ void SV_WriteDownloadToClient( client_t *cl , msg_t *msg ) return; } - Com_Printf( "clientDownload: %d : beginning \"%s\"\n", cl - svs.clients, cl->downloadName ); + Com_Printf( "clientDownload: %d : beginning \"%s\"\n", (int) (cl - svs.clients), cl->downloadName ); // Init cl->downloadCurrentBlock = cl->downloadClientBlock = cl->downloadXmitBlock = 0; @@ -805,7 +815,7 @@ void SV_WriteDownloadToClient( client_t *cl , msg_t *msg ) MSG_WriteData( msg, cl->downloadBlocks[curindex], cl->downloadBlockSize[curindex] ); } - Com_DPrintf( "clientDownload: %d : writing block %d\n", cl - svs.clients, cl->downloadXmitBlock ); + Com_DPrintf( "clientDownload: %d : writing block %d\n", (int) (cl - svs.clients), cl->downloadXmitBlock ); // Move on to the next block // It will get sent with next snap shot. The rate will keep us in line. @@ -1009,7 +1019,9 @@ into a more C friendly form. */ void SV_UserinfoChanged( client_t *cl ) { char *val; + char *ip; int i; + int len; // name for C code Q_strncpyz( cl->name, Info_ValueForKey (cl->userinfo, "name"), sizeof(cl->name) ); @@ -1058,18 +1070,23 @@ void SV_UserinfoChanged( client_t *cl ) { // TTimo // maintain the IP information - // this is set in SV_DirectConnect (directly on the server, not transmitted), may be lost when client updates it's userinfo // the banning code relies on this being consistently present - val = Info_ValueForKey (cl->userinfo, "ip"); - if (!val[0]) - { - //Com_DPrintf("Maintain IP in userinfo for '%s'\n", cl->name); - if ( !NET_IsLocalAddress(cl->netchan.remoteAddress) ) - Info_SetValueForKey( cl->userinfo, "ip", NET_AdrToString( cl->netchan.remoteAddress ) ); - else - // force the "ip" info key to "localhost" for local clients - Info_SetValueForKey( cl->userinfo, "ip", "localhost" ); - } + if( NET_IsLocalAddress(cl->netchan.remoteAddress) ) + ip = "localhost"; + else + ip = (char*)NET_AdrToString( cl->netchan.remoteAddress ); + + val = Info_ValueForKey( cl->userinfo, "ip" ); + if( val[0] ) + len = strlen( ip ) - strlen( val ) + strlen( cl->userinfo ); + else + len = strlen( ip ) + 4 + strlen( cl->userinfo ); + + if( len >= MAX_INFO_STRING ) + SV_DropClient( cl, "userinfo string length exceeded" ); + else + Info_SetValueForKey( cl->userinfo, "ip", ip ); + } @@ -1277,7 +1294,7 @@ static void SV_UserMove( client_t *cl, msg_t *msg, qboolean delta ) { if (cl->state == CS_ACTIVE) { // we didn't get a cp yet, don't assume anything and just send the gamestate all over again - Com_DPrintf( "%s: didn't get cp command, resending gamestate\n", cl->name, cl->state ); + Com_DPrintf( "%s: didn't get cp command, resending gamestate\n", cl->name); SV_SendClientGameState( cl ); } return; @@ -1427,7 +1444,7 @@ void SV_ExecuteClientMessage( client_t *cl, msg_t *msg ) { } else if ( c == clc_moveNoDelta ) { SV_UserMove( cl, msg, qfalse ); } else if ( c != clc_EOF ) { - Com_Printf( "WARNING: bad command byte for client %i\n", cl - svs.clients ); + Com_Printf( "WARNING: bad command byte for client %i\n", (int) (cl - svs.clients) ); } // if ( msg->readcount != msg->cursize ) { // Com_Printf( "WARNING: Junk at end of packet for client %i\n", cl - svs.clients ); -- cgit