summaryrefslogtreecommitdiff
path: root/src/server/sv_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/sv_client.c')
-rw-r--r--src/server/sv_client.c75
1 files changed, 46 insertions, 29 deletions
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 );