1 /*
2 ===========================================================================
3 Copyright (C) 1999-2005 Id Software, Inc.
4 
5 This file is part of Quake III Arena source code.
6 
7 Quake III Arena source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11 
12 Quake III Arena source code is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Quake III Arena source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 ===========================================================================
21 */
22 
23 #include "server.h"
24 
25 #ifdef USE_VOIP
26 cvar_t *sv_voip;
27 #endif
28 
29 serverStatic_t	svs;				// persistant server info
30 server_t		sv;					// local server
31 vm_t			*gvm = NULL;				// game virtual machine
32 
33 cvar_t	*sv_fps = NULL;			// time rate for running non-clients
34 cvar_t	*sv_timeout;			// seconds without any message
35 cvar_t	*sv_zombietime;			// seconds to sink messages after disconnect
36 cvar_t	*sv_rconPassword;		// password for remote server commands
37 cvar_t	*sv_privatePassword;		// password for the privateClient slots
38 cvar_t	*sv_allowDownload;
39 cvar_t	*sv_maxclients;
40 
41 cvar_t	*sv_privateClients;		// number of clients reserved for password
42 cvar_t	*sv_hostname;
43 cvar_t	*sv_master[MAX_MASTER_SERVERS];	// master server ip address
44 cvar_t	*sv_reconnectlimit;		// minimum seconds between connect messages
45 cvar_t	*sv_showloss;			// report when usercmds are lost
46 cvar_t	*sv_padPackets;			// add nop bytes to messages
47 cvar_t	*sv_killserver;			// menu system can set to 1 to shut server down
48 cvar_t	*sv_mapname;
49 cvar_t	*sv_mapChecksum;
50 cvar_t	*sv_serverid;
51 cvar_t	*sv_minRate;
52 cvar_t	*sv_maxRate;
53 cvar_t	*sv_minPing;
54 cvar_t	*sv_maxPing;
55 cvar_t	*sv_gametype;
56 cvar_t	*sv_dorestart;
57 cvar_t	*sv_pure;
58 cvar_t	*sv_floodProtect;
59 cvar_t	*sv_lanForceRate; // dedicated 1 (LAN) server forces local client rates to 99999 (bug #491)
60 cvar_t	*sv_public;
61 cvar_t	*sv_banFile;
62 cvar_t  *sv_heartbeat;			// Heartbeat string that is sent to the master
63 cvar_t  *sv_flatline;			// If the master server supports it we can send a flatline
64 					// when server is killed
65 
66 serverBan_t serverBans[SERVER_MAXBANS];
67 int serverBansCount = 0;
68 
69 /*
70 =============================================================================
71 
72 EVENT MESSAGES
73 
74 =============================================================================
75 */
76 
77 /*
78 ===============
79 SV_ExpandNewlines
80 
81 Converts newlines to "\n" so a line prints nicer
82 ===============
83 */
SV_ExpandNewlines(char * in)84 static char	*SV_ExpandNewlines( char *in ) {
85 	static	char	string[1024];
86 	int		l;
87 
88 	l = 0;
89 	while ( *in && l < sizeof(string) - 3 ) {
90 		if ( *in == '\n' ) {
91 			string[l++] = '\\';
92 			string[l++] = 'n';
93 		} else {
94 			string[l++] = *in;
95 		}
96 		in++;
97 	}
98 	string[l] = 0;
99 
100 	return string;
101 }
102 
103 /*
104 ======================
105 SV_ReplacePendingServerCommands
106 
107 FIXME: This is ugly
108 ======================
109 */
110 #if 0 // unused
111 static int SV_ReplacePendingServerCommands( client_t *client, const char *cmd ) {
112 	int i, index, csnum1, csnum2;
113 
114 	for ( i = client->reliableSent+1; i <= client->reliableSequence; i++ ) {
115 		index = i & ( MAX_RELIABLE_COMMANDS - 1 );
116 		//
117 		if ( !Q_strncmp(cmd, client->reliableCommands[ index ], strlen("cs")) ) {
118 			sscanf(cmd, "cs %i", &csnum1);
119 			sscanf(client->reliableCommands[ index ], "cs %i", &csnum2);
120 			if ( csnum1 == csnum2 ) {
121 				Q_strncpyz( client->reliableCommands[ index ], cmd, sizeof( client->reliableCommands[ index ] ) );
122 				/*
123 				if ( client->netchan.remoteAddress.type != NA_BOT ) {
124 					Com_Printf( "WARNING: client %i removed double pending config string %i: %s\n", client-svs.clients, csnum1, cmd );
125 				}
126 				*/
127 				return qtrue;
128 			}
129 		}
130 	}
131 	return qfalse;
132 }
133 #endif
134 
135 /*
136 ======================
137 SV_AddServerCommand
138 
139 The given command will be transmitted to the client, and is guaranteed to
140 not have future snapshot_t executed before it is executed
141 ======================
142 */
SV_AddServerCommand(client_t * client,const char * cmd)143 void SV_AddServerCommand( client_t *client, const char *cmd ) {
144 	int		index, i;
145 
146 	// this is very ugly but it's also a waste to for instance send multiple config string updates
147 	// for the same config string index in one snapshot
148 //	if ( SV_ReplacePendingServerCommands( client, cmd ) ) {
149 //		return;
150 //	}
151 
152 	// do not send commands until the gamestate has been sent
153 	if( client->state < CS_PRIMED )
154 		return;
155 
156 	client->reliableSequence++;
157 	// if we would be losing an old command that hasn't been acknowledged,
158 	// we must drop the connection
159 	// we check == instead of >= so a broadcast print added by SV_DropClient()
160 	// doesn't cause a recursive drop client
161 	if ( client->reliableSequence - client->reliableAcknowledge == MAX_RELIABLE_COMMANDS + 1 ) {
162 		Com_Printf( "===== pending server commands =====\n" );
163 		for ( i = client->reliableAcknowledge + 1 ; i <= client->reliableSequence ; i++ ) {
164 			Com_Printf( "cmd %5d: %s\n", i, client->reliableCommands[ i & (MAX_RELIABLE_COMMANDS-1) ] );
165 		}
166 		Com_Printf( "cmd %5d: %s\n", i, cmd );
167 		SV_DropClient( client, "Server command overflow" );
168 		return;
169 	}
170 	index = client->reliableSequence & ( MAX_RELIABLE_COMMANDS - 1 );
171 	Q_strncpyz( client->reliableCommands[ index ], cmd, sizeof( client->reliableCommands[ index ] ) );
172 }
173 
174 
175 /*
176 =================
177 SV_SendServerCommand
178 
179 Sends a reliable command string to be interpreted by
180 the client game module: "cp", "print", "chat", etc
181 A NULL client will broadcast to all clients
182 =================
183 */
SV_SendServerCommand(client_t * cl,const char * fmt,...)184 void QDECL SV_SendServerCommand(client_t *cl, const char *fmt, ...) {
185 	va_list		argptr;
186 	byte		message[MAX_MSGLEN];
187 	client_t	*client;
188 	int			j;
189 
190 	va_start (argptr,fmt);
191 	Q_vsnprintf ((char *)message, sizeof(message), fmt,argptr);
192 	va_end (argptr);
193 
194 	// Fix to http://aluigi.altervista.org/adv/q3msgboom-adv.txt
195 	// The actual cause of the bug is probably further downstream
196 	// and should maybe be addressed later, but this certainly
197 	// fixes the problem for now
198 	if ( strlen ((char *)message) > 1022 ) {
199 		return;
200 	}
201 
202 	if ( cl != NULL ) {
203 		SV_AddServerCommand( cl, (char *)message );
204 		return;
205 	}
206 
207 	// hack to echo broadcast prints to console
208 	if ( com_dedicated->integer && !strncmp( (char *)message, "print", 5) ) {
209 		Com_Printf ("broadcast: %s\n", SV_ExpandNewlines((char *)message) );
210 	}
211 
212 	// send the data to all relevent clients
213 	for (j = 0, client = svs.clients; j < sv_maxclients->integer ; j++, client++) {
214 		SV_AddServerCommand( client, (char *)message );
215 	}
216 }
217 
218 
219 /*
220 ==============================================================================
221 
222 MASTER SERVER FUNCTIONS
223 
224 ==============================================================================
225 */
226 
227 /*
228 ================
229 SV_MasterHeartbeat
230 
231 Send a message to the masters every few minutes to
232 let it know we are alive, and log information.
233 We will also have a heartbeat sent when a server
234 changes from empty to non-empty, and full to non-full,
235 but not on every player enter or exit.
236 ================
237 */
238 #define	HEARTBEAT_MSEC	300*1000
SV_MasterHeartbeat(const char * message)239 void SV_MasterHeartbeat(const char *message)
240 {
241 	static netadr_t	adr[MAX_MASTER_SERVERS][2]; // [2] for v4 and v6 address for the same address string.
242 	int			i;
243 	int			res;
244 	int			netenabled;
245 
246 	netenabled = Cvar_VariableIntegerValue("net_enabled");
247 
248 	// "dedicated 1" is for lan play, "dedicated 2" is for inet public play
249 	if ( ( (!com_dedicated || com_dedicated->integer != 2) && !(sv_public->integer) ) || !(netenabled & (NET_ENABLEV4 | NET_ENABLEV6)))
250 		return;		// only dedicated servers send heartbeats
251 
252 	// if not time yet, don't send anything
253 	if ( svs.time < svs.nextHeartbeatTime )
254 		return;
255 
256 	svs.nextHeartbeatTime = svs.time + HEARTBEAT_MSEC;
257 
258 	// send to group masters
259 	for (i = 0; i < MAX_MASTER_SERVERS; i++)
260 	{
261 		if(!sv_master[i]->string[0])
262 			continue;
263 
264 		// see if we haven't already resolved the name
265 		// resolving usually causes hitches on win95, so only
266 		// do it when needed
267 		if(sv_master[i]->modified || (adr[i][0].type == NA_BAD && adr[i][1].type == NA_BAD))
268 		{
269 			sv_master[i]->modified = qfalse;
270 
271 			if(netenabled & NET_ENABLEV4)
272 			{
273 				Com_Printf("Resolving %s (IPv4)\n", sv_master[i]->string);
274 				res = NET_StringToAdr(sv_master[i]->string, &adr[i][0], NA_IP);
275 
276 				if(res == 2)
277 				{
278 					// if no port was specified, use the default master port
279 					adr[i][0].port = BigShort(PORT_MASTER);
280 				}
281 
282 				if(res)
283 					Com_Printf( "%s resolved to %s\n", sv_master[i]->string, NET_AdrToStringwPort(adr[i][0]));
284 				else
285 					Com_Printf( "%s has no IPv4 address.\n", sv_master[i]->string);
286 			}
287 
288 			if(netenabled & NET_ENABLEV6)
289 			{
290 				Com_Printf("Resolving %s (IPv6)\n", sv_master[i]->string);
291 				res = NET_StringToAdr(sv_master[i]->string, &adr[i][1], NA_IP6);
292 
293 				if(res == 2)
294 				{
295 					// if no port was specified, use the default master port
296 					adr[i][1].port = BigShort(PORT_MASTER);
297 				}
298 
299 				if(res)
300 					Com_Printf( "%s resolved to %s\n", sv_master[i]->string, NET_AdrToStringwPort(adr[i][1]));
301 				else
302 					Com_Printf( "%s has no IPv6 address.\n", sv_master[i]->string);
303 			}
304 
305 			if(adr[i][0].type == NA_BAD && adr[i][1].type == NA_BAD)
306 			{
307 				// if the address failed to resolve, clear it
308 				// so we don't take repeated dns hits
309 				Com_Printf("Couldn't resolve address: %s\n", sv_master[i]->string);
310 				Cvar_Set(sv_master[i]->name, "");
311 				sv_master[i]->modified = qfalse;
312 				continue;
313 			}
314 		}
315 
316 
317 		Com_Printf ("Sending heartbeat to %s\n", sv_master[i]->string );
318 
319 		// this command should be changed if the server info / status format
320 		// ever incompatably changes
321 
322 		if(adr[i][0].type != NA_BAD)
323 			NET_OutOfBandPrint( NS_SERVER, adr[i][0], "heartbeat %s\n", message);
324 		if(adr[i][1].type != NA_BAD)
325 			NET_OutOfBandPrint( NS_SERVER, adr[i][1], "heartbeat %s\n", message);
326 	}
327 }
328 
329 /*
330 =================
331 SV_MasterShutdown
332 
333 Informs all masters that this server is going down
334 =================
335 */
SV_MasterShutdown(void)336 void SV_MasterShutdown( void ) {
337 	// send a hearbeat right now
338 	svs.nextHeartbeatTime = -9999;
339 	SV_MasterHeartbeat(sv_flatline->string);
340 
341 	// send it again to minimize chance of drops
342 	svs.nextHeartbeatTime = -9999;
343 	SV_MasterHeartbeat(sv_flatline->string);
344 
345 	// when the master tries to poll the server, it won't respond, so
346 	// it will be removed from the list
347 }
348 
349 
350 /*
351 ==============================================================================
352 
353 CONNECTIONLESS COMMANDS
354 
355 ==============================================================================
356 */
357 
358 typedef struct leakyBucket_s leakyBucket_t;
359 struct leakyBucket_s {
360 	netadrtype_t	type;
361 
362 	union {
363 		byte	_4[4];
364 		byte	_6[16];
365 	} ipv;
366 
367 	int						lastTime;
368 	signed char		burst;
369 
370 	long					hash;
371 
372 	leakyBucket_t *prev, *next;
373 };
374 
375 // This is deliberately quite large to make it more of an effort to DoS
376 #define MAX_BUCKETS			16384
377 #define MAX_HASHES			1024
378 
379 static leakyBucket_t buckets[ MAX_BUCKETS ];
380 static leakyBucket_t *bucketHashes[ MAX_HASHES ];
381 
382 /*
383 ================
384 SVC_HashForAddress
385 ================
386 */
SVC_HashForAddress(netadr_t address)387 static long SVC_HashForAddress( netadr_t address ) {
388 	byte 		*ip = NULL;
389 	size_t	size = 0;
390 	int			i;
391 	long		hash = 0;
392 
393 	switch ( address.type ) {
394 		case NA_IP:  ip = address.ip;  size = 4; break;
395 		case NA_IP6: ip = address.ip6; size = 16; break;
396 		default: break;
397 	}
398 
399 	for ( i = 0; i < size; i++ ) {
400 		hash += (long)( ip[ i ] ) * ( i + 119 );
401 	}
402 
403 	hash = ( hash ^ ( hash >> 10 ) ^ ( hash >> 20 ) );
404 	hash &= ( MAX_HASHES - 1 );
405 
406 	return hash;
407 }
408 
409 /*
410 ================
411 SVC_BucketForAddress
412 
413 Find or allocate a bucket for an address
414 ================
415 */
SVC_BucketForAddress(netadr_t address,int burst,int period)416 static leakyBucket_t *SVC_BucketForAddress( netadr_t address, int burst, int period ) {
417 	leakyBucket_t	*bucket = NULL;
418 	int						i;
419 	long					hash = SVC_HashForAddress( address );
420 	int						now = Sys_Milliseconds();
421 
422 	for ( bucket = bucketHashes[ hash ]; bucket; bucket = bucket->next ) {
423 		switch ( bucket->type ) {
424 			case NA_IP:
425 				if ( memcmp( bucket->ipv._4, address.ip, 4 ) == 0 ) {
426 					return bucket;
427 				}
428 				break;
429 
430 			case NA_IP6:
431 				if ( memcmp( bucket->ipv._6, address.ip6, 16 ) == 0 ) {
432 					return bucket;
433 				}
434 				break;
435 
436 			default:
437 				break;
438 		}
439 	}
440 
441 	for ( i = 0; i < MAX_BUCKETS; i++ ) {
442 		int interval;
443 
444 		bucket = &buckets[ i ];
445 		interval = now - bucket->lastTime;
446 
447 		// Reclaim expired buckets
448 		if ( bucket->lastTime > 0 && ( interval > ( burst * period ) ||
449 					interval < 0 ) ) {
450 			if ( bucket->prev != NULL ) {
451 				bucket->prev->next = bucket->next;
452 			} else {
453 				bucketHashes[ bucket->hash ] = bucket->next;
454 			}
455 
456 			if ( bucket->next != NULL ) {
457 				bucket->next->prev = bucket->prev;
458 			}
459 
460 			Com_Memset( bucket, 0, sizeof( leakyBucket_t ) );
461 		}
462 
463 		if ( bucket->type == NA_BAD ) {
464 			bucket->type = address.type;
465 			switch ( address.type ) {
466 				case NA_IP:  Com_Memcpy( bucket->ipv._4, address.ip, 4 );   break;
467 				case NA_IP6: Com_Memcpy( bucket->ipv._6, address.ip6, 16 ); break;
468 				default: break;
469 			}
470 
471 			bucket->lastTime = now;
472 			bucket->burst = 0;
473 			bucket->hash = hash;
474 
475 			// Add to the head of the relevant hash chain
476 			bucket->next = bucketHashes[ hash ];
477 			if ( bucketHashes[ hash ] != NULL ) {
478 				bucketHashes[ hash ]->prev = bucket;
479 			}
480 
481 			bucket->prev = NULL;
482 			bucketHashes[ hash ] = bucket;
483 
484 			return bucket;
485 		}
486 	}
487 
488 	// Couldn't allocate a bucket for this address
489 	return NULL;
490 }
491 
492 /*
493 ================
494 SVC_RateLimit
495 ================
496 */
SVC_RateLimit(leakyBucket_t * bucket,int burst,int period)497 static qboolean SVC_RateLimit( leakyBucket_t *bucket, int burst, int period ) {
498 	if ( bucket != NULL ) {
499 		int now = Sys_Milliseconds();
500 		int interval = now - bucket->lastTime;
501 		int expired = interval / period;
502 		int expiredRemainder = interval % period;
503 
504 		if ( expired > bucket->burst ) {
505 			bucket->burst = 0;
506 			bucket->lastTime = now;
507 		} else {
508 			bucket->burst -= expired;
509 			bucket->lastTime = now - expiredRemainder;
510 		}
511 
512 		if ( bucket->burst < burst ) {
513 			bucket->burst++;
514 
515 			return qfalse;
516 		}
517 	}
518 
519 	return qtrue;
520 }
521 
522 /*
523 ================
524 SVC_RateLimitAddress
525 
526 Rate limit for a particular address
527 ================
528 */
SVC_RateLimitAddress(netadr_t from,int burst,int period)529 static qboolean SVC_RateLimitAddress( netadr_t from, int burst, int period ) {
530 	leakyBucket_t *bucket = SVC_BucketForAddress( from, burst, period );
531 
532 	return SVC_RateLimit( bucket, burst, period );
533 }
534 
535 /*
536 ================
537 SVC_Status
538 
539 Responds with all the info that qplug or qspy can see about the server
540 and all connected players.  Used for getting detailed information after
541 the simple info query.
542 ================
543 */
SVC_Status(netadr_t from)544 static void SVC_Status( netadr_t from ) {
545 	char	player[1024];
546 	char	status[MAX_MSGLEN];
547 	int		i;
548 	client_t	*cl;
549 	playerState_t	*ps;
550 	int		statusLength;
551 	int		playerLength;
552 	char	infostring[MAX_INFO_STRING];
553 	static leakyBucket_t bucket;
554 
555 	// ignore if we are in single player
556 	if ( Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER ) {
557 		return;
558 	}
559 
560 	// Prevent using getstatus as an amplifier
561 	if ( SVC_RateLimitAddress( from, 10, 1000 ) ) {
562 		Com_DPrintf( "SVC_Status: rate limit from %s exceeded, dropping request\n",
563 			NET_AdrToString( from ) );
564 		return;
565 	}
566 
567 	// Allow getstatus to be DoSed relatively easily, but prevent
568 	// excess outbound bandwidth usage when being flooded inbound
569 	if ( SVC_RateLimit( &bucket, 10, 100 ) ) {
570 		Com_DPrintf( "SVC_Status: rate limit exceeded, dropping request\n" );
571 		return;
572 	}
573 
574 	strcpy( infostring, Cvar_InfoString( CVAR_SERVERINFO ) );
575 
576 	// echo back the parameter to status. so master servers can use it as a challenge
577 	// to prevent timed spoofed reply packets that add ghost servers
578 	Info_SetValueForKey( infostring, "challenge", Cmd_Argv(1) );
579 
580 	status[0] = 0;
581 	statusLength = 0;
582 
583 	for (i=0 ; i < sv_maxclients->integer ; i++) {
584 		cl = &svs.clients[i];
585 		if ( cl->state >= CS_CONNECTED ) {
586 			ps = SV_GameClientNum( i );
587 			Com_sprintf (player, sizeof(player), "%i %i \"%s\"\n",
588 				ps->persistant[PERS_SCORE], cl->ping, cl->name);
589 			playerLength = strlen(player);
590 			if (statusLength + playerLength >= sizeof(status) ) {
591 				break;		// can't hold any more
592 			}
593 			strcpy (status + statusLength, player);
594 			statusLength += playerLength;
595 		}
596 	}
597 
598 	NET_OutOfBandPrint( NS_SERVER, from, "statusResponse\n%s\n%s", infostring, status );
599 }
600 
601 /*
602 ================
603 SVC_Info
604 
605 Responds with a short info message that should be enough to determine
606 if a user is interested in a server to do a full status
607 ================
608 */
SVC_Info(netadr_t from)609 void SVC_Info( netadr_t from ) {
610 	int		i, count, humans;
611 	char	*gamedir;
612 	char	infostring[MAX_INFO_STRING];
613 
614 	// ignore if we are in single player
615 	if ( Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER || Cvar_VariableValue("ui_singlePlayerActive")) {
616 		return;
617 	}
618 
619 	/*
620 	 * Check whether Cmd_Argv(1) has a sane length. This was not done in the original Quake3 version which led
621 	 * to the Infostring bug discovered by Luigi Auriemma. See http://aluigi.altervista.org/ for the advisory.
622 	 */
623 
624 	// A maximum challenge length of 128 should be more than plenty.
625 	if(strlen(Cmd_Argv(1)) > 128)
626 		return;
627 
628 	// don't count privateclients
629 	count = 0;
630 	humans = 0;
631 	for ( i = sv_privateClients->integer ; i < sv_maxclients->integer ; i++ ) {
632 		if ( svs.clients[i].state >= CS_CONNECTED ) {
633 			count++;
634 			if (svs.clients[i].netchan.remoteAddress.type != NA_BOT) {
635 				humans++;
636 			}
637 		}
638 	}
639 
640 	infostring[0] = 0;
641 
642 	// echo back the parameter to status. so servers can use it as a challenge
643 	// to prevent timed spoofed reply packets that add ghost servers
644 	Info_SetValueForKey( infostring, "challenge", Cmd_Argv(1) );
645 
646 	Info_SetValueForKey( infostring, "protocol", va("%i", com_protocol->integer) );
647 	Info_SetValueForKey( infostring, "hostname", sv_hostname->string );
648 	Info_SetValueForKey( infostring, "mapname", sv_mapname->string );
649 	Info_SetValueForKey( infostring, "clients", va("%i", count) );
650 	Info_SetValueForKey( infostring, "sv_maxclients",
651 		va("%i", sv_maxclients->integer - sv_privateClients->integer ) );
652 	Info_SetValueForKey( infostring, "gametype", va("%i", sv_gametype->integer ) );
653 	Info_SetValueForKey( infostring, "pure", va("%i", sv_pure->integer ) );
654 	//Sago's things:
655 	Info_SetValueForKey( infostring, "g_needpass", va("%i", (int)Cvar_VariableValue("g_needpass") ) );
656 	Info_SetValueForKey( infostring, "g_humanplayers", va("%i", humans ) );
657 	//Sago's end
658 
659 #ifdef USE_VOIP
660 	if (sv_voip->integer) {
661 		Info_SetValueForKey( infostring, "voip", va("%i", sv_voip->integer ) );
662 	}
663 #endif
664 
665 	if( sv_minPing->integer ) {
666 		Info_SetValueForKey( infostring, "minPing", va("%i", sv_minPing->integer) );
667 	}
668 	if( sv_maxPing->integer ) {
669 		Info_SetValueForKey( infostring, "maxPing", va("%i", sv_maxPing->integer) );
670 	}
671 	gamedir = Cvar_VariableString( "fs_game" );
672 	if( *gamedir ) {
673 		Info_SetValueForKey( infostring, "game", gamedir );
674 	}
675 
676 	NET_OutOfBandPrint( NS_SERVER, from, "infoResponse\n%s", infostring );
677 }
678 
679 /*
680 ================
681 SVC_FlushRedirect
682 
683 ================
684 */
SV_FlushRedirect(char * outputbuf)685 static void SV_FlushRedirect( char *outputbuf ) {
686 	NET_OutOfBandPrint( NS_SERVER, svs.redirectAddress, "print\n%s", outputbuf );
687 }
688 
689 /*
690 ===============
691 SVC_RemoteCommand
692 
693 An rcon packet arrived from the network.
694 Shift down the remaining args
695 Redirect all printfs
696 ===============
697 */
SVC_RemoteCommand(netadr_t from,msg_t * msg)698 static void SVC_RemoteCommand( netadr_t from, msg_t *msg ) {
699 	qboolean	valid;
700 	char		remaining[1024];
701 	// TTimo - scaled down to accumulate, but not overflow anything network wise, print wise etc.
702 	// (OOB messages are the bottleneck here)
703 #define SV_OUTPUTBUF_LENGTH (1024 - 16)
704 	char		sv_outputbuf[SV_OUTPUTBUF_LENGTH];
705 	char *cmd_aux;
706 
707 	// Prevent using rcon as an amplifier and make dictionary attacks impractical
708 	if ( SVC_RateLimitAddress( from, 10, 1000 ) ) {
709 		Com_DPrintf( "SVC_RemoteCommand: rate limit from %s exceeded, dropping request\n",
710 			NET_AdrToString( from ) );
711 		return;
712 	}
713 
714 	if ( !strlen( sv_rconPassword->string ) ||
715 		strcmp (Cmd_Argv(1), sv_rconPassword->string) ) {
716 		static leakyBucket_t bucket;
717 
718 		// Make DoS via rcon impractical
719 		if ( SVC_RateLimit( &bucket, 10, 1000 ) ) {
720 			Com_DPrintf( "SVC_RemoteCommand: rate limit exceeded, dropping request\n" );
721 			return;
722 		}
723 
724 		valid = qfalse;
725 		Com_Printf ("Bad rcon from %s: %s\n", NET_AdrToString (from), Cmd_ArgsFrom(2) );
726 	} else {
727 		valid = qtrue;
728 		Com_Printf ("Rcon from %s: %s\n", NET_AdrToString (from), Cmd_ArgsFrom(2) );
729 	}
730 
731 	// start redirecting all print outputs to the packet
732 	svs.redirectAddress = from;
733 	Com_BeginRedirect (sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_FlushRedirect);
734 
735 	if ( !strlen( sv_rconPassword->string ) ) {
736 		Com_Printf ("No rconpassword set on the server.\n");
737 	} else if ( !valid ) {
738 		Com_Printf ("Bad rconpassword.\n");
739 	} else {
740 		remaining[0] = 0;
741 
742 		// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=543
743 		// get the command directly, "rcon <pass> <command>" to avoid quoting issues
744 		// extract the command by walking
745 		// since the cmd formatting can fuckup (amount of spaces), using a dumb step by step parsing
746 		cmd_aux = Cmd_Cmd();
747 		cmd_aux+=4;
748 		while(cmd_aux[0]==' ')
749 			cmd_aux++;
750 		while(cmd_aux[0] && cmd_aux[0]!=' ') // password
751 			cmd_aux++;
752 		while(cmd_aux[0]==' ')
753 			cmd_aux++;
754 
755 		Q_strcat( remaining, sizeof(remaining), cmd_aux);
756 
757 		Cmd_ExecuteString (remaining);
758 
759 	}
760 
761 	Com_EndRedirect ();
762 }
763 
764 /*
765 =================
766 SV_ConnectionlessPacket
767 
768 A connectionless packet has four leading 0xff
769 characters to distinguish it from a game channel.
770 Clients that are in the game can still send
771 connectionless packets.
772 =================
773 */
SV_ConnectionlessPacket(netadr_t from,msg_t * msg)774 static void SV_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
775 	char	*s;
776 	char	*c;
777 
778 	MSG_BeginReadingOOB( msg );
779 	MSG_ReadLong( msg );		// skip the -1 marker
780 
781 	if (!Q_strncmp("connect", (char *) &msg->data[4], 7)) {
782 		Huff_Decompress(msg, 12);
783 	}
784 
785 	s = MSG_ReadStringLine( msg );
786 	Cmd_TokenizeString( s );
787 
788 	c = Cmd_Argv(0);
789 	Com_DPrintf ("SV packet %s : %s\n", NET_AdrToString(from), c);
790 
791 	if (!Q_stricmp(c, "getstatus")) {
792 		SVC_Status( from );
793   } else if (!Q_stricmp(c, "getinfo")) {
794 		SVC_Info( from );
795 	} else if (!Q_stricmp(c, "getchallenge")) {
796 		SV_GetChallenge(from);
797 	} else if (!Q_stricmp(c, "connect")) {
798 		SV_DirectConnect( from );
799 #ifndef STANDALONE
800 	} else if (!Q_stricmp(c, "ipAuthorize")) {
801 		SV_AuthorizeIpPacket( from );
802 #endif
803 	} else if (!Q_stricmp(c, "rcon")) {
804 		SVC_RemoteCommand( from, msg );
805 	} else if (!Q_stricmp(c, "disconnect")) {
806 		// if a client starts up a local server, we may see some spurious
807 		// server disconnect messages when their new server sees our final
808 		// sequenced messages to the old client
809 	} else {
810 		Com_DPrintf ("bad connectionless packet from %s:\n%s\n",
811 			NET_AdrToString (from), s);
812 	}
813 }
814 
815 //============================================================================
816 
817 /*
818 =================
819 SV_PacketEvent
820 =================
821 */
SV_PacketEvent(netadr_t from,msg_t * msg)822 void SV_PacketEvent( netadr_t from, msg_t *msg ) {
823 	int			i;
824 	client_t	*cl;
825 	int			qport;
826 
827 	// check for connectionless packet (0xffffffff) first
828 	if ( msg->cursize >= 4 && *(int *)msg->data == -1) {
829 		SV_ConnectionlessPacket( from, msg );
830 		return;
831 	}
832 
833 	// read the qport out of the message so we can fix up
834 	// stupid address translating routers
835 	MSG_BeginReadingOOB( msg );
836 	MSG_ReadLong( msg );				// sequence number
837 	qport = MSG_ReadShort( msg ) & 0xffff;
838 
839 	// find which client the message is from
840 	for (i=0, cl=svs.clients ; i < sv_maxclients->integer ; i++,cl++) {
841 		if (cl->state == CS_FREE) {
842 			continue;
843 		}
844 		if ( !NET_CompareBaseAdr( from, cl->netchan.remoteAddress ) ) {
845 			continue;
846 		}
847 		// it is possible to have multiple clients from a single IP
848 		// address, so they are differentiated by the qport variable
849 		if (cl->netchan.qport != qport) {
850 			continue;
851 		}
852 
853 		// the IP port can't be used to differentiate them, because
854 		// some address translating routers periodically change UDP
855 		// port assignments
856 		if (cl->netchan.remoteAddress.port != from.port) {
857 			Com_Printf( "SV_PacketEvent: fixing up a translated port\n" );
858 			cl->netchan.remoteAddress.port = from.port;
859 		}
860 
861 		// make sure it is a valid, in sequence packet
862 		if (SV_Netchan_Process(cl, msg)) {
863 			// zombie clients still need to do the Netchan_Process
864 			// to make sure they don't need to retransmit the final
865 			// reliable message, but they don't do any other processing
866 			if (cl->state != CS_ZOMBIE) {
867 				cl->lastPacketTime = svs.time;	// don't timeout
868 				SV_ExecuteClientMessage( cl, msg );
869 			}
870 		}
871 		return;
872 	}
873 
874 	// if we received a sequenced packet from an address we don't recognize,
875 	// send an out of band disconnect packet to it
876 	NET_OutOfBandPrint( NS_SERVER, from, "disconnect" );
877 }
878 
879 
880 /*
881 ===================
882 SV_CalcPings
883 
884 Updates the cl->ping variables
885 ===================
886 */
SV_CalcPings(void)887 static void SV_CalcPings( void ) {
888 	int			i, j;
889 	client_t	*cl;
890 	int			total, count;
891 	int			delta;
892 	playerState_t	*ps;
893 
894 	for (i=0 ; i < sv_maxclients->integer ; i++) {
895 		cl = &svs.clients[i];
896 		if ( cl->state != CS_ACTIVE ) {
897 			cl->ping = 999;
898 			continue;
899 		}
900 		if ( !cl->gentity ) {
901 			cl->ping = 999;
902 			continue;
903 		}
904 		if ( cl->gentity->r.svFlags & SVF_BOT ) {
905 			cl->ping = 0;
906 			continue;
907 		}
908 
909 		total = 0;
910 		count = 0;
911 		for ( j = 0 ; j < PACKET_BACKUP ; j++ ) {
912 			if ( cl->frames[j].messageAcked <= 0 ) {
913 				continue;
914 			}
915 			delta = cl->frames[j].messageAcked - cl->frames[j].messageSent;
916 			count++;
917 			total += delta;
918 		}
919 		if (!count) {
920 			cl->ping = 999;
921 		} else {
922 			cl->ping = total/count;
923 			if ( cl->ping > 999 ) {
924 				cl->ping = 999;
925 			}
926 		}
927 
928 		// let the game dll know about the ping
929 		ps = SV_GameClientNum( i );
930 		ps->ping = cl->ping;
931 	}
932 }
933 
934 /*
935 ==================
936 SV_CheckTimeouts
937 
938 If a packet has not been received from a client for timeout->integer
939 seconds, drop the conneciton.  Server time is used instead of
940 realtime to avoid dropping the local client while debugging.
941 
942 When a client is normally dropped, the client_t goes into a zombie state
943 for a few seconds to make sure any final reliable message gets resent
944 if necessary
945 ==================
946 */
SV_CheckTimeouts(void)947 static void SV_CheckTimeouts( void ) {
948 	int		i;
949 	client_t	*cl;
950 	int			droppoint;
951 	int			zombiepoint;
952 
953 	droppoint = svs.time - 1000 * sv_timeout->integer;
954 	zombiepoint = svs.time - 1000 * sv_zombietime->integer;
955 
956 	for (i=0,cl=svs.clients ; i < sv_maxclients->integer ; i++,cl++) {
957 		// message times may be wrong across a changelevel
958 		if (cl->lastPacketTime > svs.time) {
959 			cl->lastPacketTime = svs.time;
960 		}
961 
962 		if (cl->state == CS_ZOMBIE
963 		&& cl->lastPacketTime < zombiepoint) {
964 			// using the client id cause the cl->name is empty at this point
965 			Com_DPrintf( "Going from CS_ZOMBIE to CS_FREE for client %d\n", i );
966 			cl->state = CS_FREE;	// can now be reused
967 			continue;
968 		}
969 		if ( cl->state >= CS_CONNECTED && cl->lastPacketTime < droppoint) {
970 			// wait several frames so a debugger session doesn't
971 			// cause a timeout
972 			if ( ++cl->timeoutCount > 5 ) {
973 				SV_DropClient (cl, "timed out");
974 				cl->state = CS_FREE;	// don't bother with zombie state
975 			}
976 		} else {
977 			cl->timeoutCount = 0;
978 		}
979 	}
980 }
981 
982 
983 /*
984 ==================
985 SV_CheckPaused
986 ==================
987 */
SV_CheckPaused(void)988 static qboolean SV_CheckPaused( void ) {
989 	int		count;
990 	client_t	*cl;
991 	int		i;
992 
993 	if ( !cl_paused->integer ) {
994 		return qfalse;
995 	}
996 
997 	// only pause if there is just a single client connected
998 	count = 0;
999 	for (i=0,cl=svs.clients ; i < sv_maxclients->integer ; i++,cl++) {
1000 		if ( cl->state >= CS_CONNECTED && cl->netchan.remoteAddress.type != NA_BOT ) {
1001 			count++;
1002 		}
1003 	}
1004 
1005 	if ( count > 1 ) {
1006 		// don't pause
1007 		if (sv_paused->integer)
1008 			Cvar_Set("sv_paused", "0");
1009 		return qfalse;
1010 	}
1011 
1012 	if (!sv_paused->integer)
1013 		Cvar_Set("sv_paused", "1");
1014 	return qtrue;
1015 }
1016 
1017 /*
1018 ==================
1019 SV_FrameMsec
1020 Return time in millseconds until processing of the next server frame.
1021 ==================
1022 */
SV_FrameMsec()1023 int SV_FrameMsec()
1024 {
1025 	if(sv_fps)
1026 	{
1027 		int frameMsec;
1028 
1029 		frameMsec = 1000.0f / sv_fps->value;
1030 
1031 		if(frameMsec < sv.timeResidual)
1032 			return 0;
1033 		else
1034 			return frameMsec - sv.timeResidual;
1035 	}
1036 	else
1037 		return 1;
1038 }
1039 
1040 /*
1041 ==================
1042 SV_Frame
1043 
1044 Player movement occurs as a result of packet events, which
1045 happen before SV_Frame is called
1046 ==================
1047 */
SV_Frame(int msec)1048 void SV_Frame( int msec ) {
1049 	int		frameMsec;
1050 	int		startTime;
1051 
1052 	// the menu kills the server with this cvar
1053 	if ( sv_killserver->integer ) {
1054 		SV_Shutdown ("Server was killed");
1055 		Cvar_Set( "sv_killserver", "0" );
1056 		return;
1057 	}
1058 
1059 	if (!com_sv_running->integer)
1060 	{
1061 		// Running as a server, but no map loaded
1062 #ifdef DEDICATED
1063 		// Block until something interesting happens
1064 		Sys_Sleep(-1);
1065 #endif
1066 
1067 		return;
1068 	}
1069 
1070 	// allow pause if only the local client is connected
1071 	if ( SV_CheckPaused() ) {
1072 		return;
1073 	}
1074 
1075 	// if it isn't time for the next frame, do nothing
1076 	if ( sv_fps->integer < 1 ) {
1077 		Cvar_Set( "sv_fps", "10" );
1078 	}
1079 
1080 	frameMsec = 1000 / sv_fps->integer * com_timescale->value;
1081 	// don't let it scale below 1ms
1082 	if(frameMsec < 1)
1083 	{
1084 		Cvar_Set("timescale", va("%f", sv_fps->integer / 1000.0f));
1085 		frameMsec = 1;
1086 	}
1087 
1088 	sv.timeResidual += msec;
1089 
1090 	if (!com_dedicated->integer) SV_BotFrame (sv.time + sv.timeResidual);
1091 
1092 	// if time is about to hit the 32nd bit, kick all clients
1093 	// and clear sv.time, rather
1094 	// than checking for negative time wraparound everywhere.
1095 	// 2giga-milliseconds = 23 days, so it won't be too often
1096 	if ( svs.time > 0x70000000 ) {
1097 		SV_Shutdown( "Restarting server due to time wrapping" );
1098 		Cbuf_AddText( va( "map %s\n", Cvar_VariableString( "mapname" ) ) );
1099 		return;
1100 	}
1101 	// this can happen considerably earlier when lots of clients play and the map doesn't change
1102 	if ( svs.nextSnapshotEntities >= 0x7FFFFFFE - svs.numSnapshotEntities ) {
1103 		SV_Shutdown( "Restarting server due to numSnapshotEntities wrapping" );
1104 		Cbuf_AddText( va( "map %s\n", Cvar_VariableString( "mapname" ) ) );
1105 		return;
1106 	}
1107 
1108 	if( sv.restartTime && sv.time >= sv.restartTime ) {
1109 		sv.restartTime = 0;
1110 		Cbuf_AddText( "map_restart 0\n" );
1111 		return;
1112 	}
1113 
1114 	// update infostrings if anything has been changed
1115 	if ( cvar_modifiedFlags & CVAR_SERVERINFO ) {
1116 		SV_SetConfigstring( CS_SERVERINFO, Cvar_InfoString( CVAR_SERVERINFO ) );
1117 		cvar_modifiedFlags &= ~CVAR_SERVERINFO;
1118 	}
1119 	if ( cvar_modifiedFlags & CVAR_SYSTEMINFO ) {
1120 		SV_SetConfigstring( CS_SYSTEMINFO, Cvar_InfoString_Big( CVAR_SYSTEMINFO ) );
1121 		cvar_modifiedFlags &= ~CVAR_SYSTEMINFO;
1122 	}
1123 
1124 	if ( com_speeds->integer ) {
1125 		startTime = Sys_Milliseconds ();
1126 	} else {
1127 		startTime = 0;	// quite a compiler warning
1128 	}
1129 
1130 	// update ping based on the all received frames
1131 	SV_CalcPings();
1132 
1133 	if (com_dedicated->integer) SV_BotFrame (sv.time);
1134 
1135 	// run the game simulation in chunks
1136 	while ( sv.timeResidual >= frameMsec ) {
1137 		sv.timeResidual -= frameMsec;
1138 		svs.time += frameMsec;
1139 		sv.time += frameMsec;
1140 
1141 		// let everything in the world think and move
1142 		VM_Call (gvm, GAME_RUN_FRAME, sv.time);
1143 	}
1144 
1145 	if ( com_speeds->integer ) {
1146 		time_game = Sys_Milliseconds () - startTime;
1147 	}
1148 
1149 	// check timeouts
1150 	SV_CheckTimeouts();
1151 
1152 	// send messages back to the clients
1153 	SV_SendClientMessages();
1154 
1155 	// send a heartbeat to the master if needed
1156 	SV_MasterHeartbeat(sv_heartbeat->string);
1157 }
1158 
1159 //============================================================================
1160 
1161