Exemple #1
0
/* <9a28f> ../engine/sv_log.c:321 */
void SV_AddLogAddress_f(void)
{
	const char *s;
	int nPort;
	char szAdr[MAX_PATH];
	netadr_t adr;
	LOGLIST_T *list;
	qboolean found = FALSE;
	LOGLIST_T *tmp;

	if (Cmd_Argc() != 3)
	{
		Con_Printf("logaddress_add:  usage\nlogaddress_add ip port\n");
		for (list = firstLog; list != NULL; list = list->next)
			Con_Printf("current:  %s\n", NET_AdrToString(list->log.net_address_));
		return;
	}

	nPort = Q_atoi(Cmd_Argv(2));
	if (!nPort)
	{
		Con_Printf("logaddress_add:  must specify a valid port\n");
		return;
	}

	s = Cmd_Argv(1);
	if (!s || *s == '\0')
	{
		Con_Printf("logaddress_add:  unparseable address\n");
		return;
	}
	Q_snprintf(szAdr, sizeof(szAdr), "%s:%i", s, nPort);

	if (!NET_StringToAdr(szAdr, &adr))
	{
		Con_Printf("logaddress_add:  unable to resolve %s\n", szAdr);
		return;
	}

	if (firstLog)
	{
		for (list = firstLog; list != NULL; list = list->next)
		{
#ifdef REHLDS_FIXES
			//for IPX support
			if (NET_CompareAdr(adr, list->log.net_address_))
#else
			if (Q_memcmp(adr.ip, list->log.net_address_.ip, 4) == 0 && adr.port == list->log.net_address_.port)
#endif // REHLDS_FIXES
			{
				found = TRUE;
				break;
			}
		}
		if (found)
		{
			Con_Printf("logaddress_add:  address already in list\n");
			return;
		}
		tmp = (LOGLIST_T *)Mem_Malloc(sizeof(LOGLIST_T));
		if (!tmp)
		{
			Con_Printf("logaddress_add:  error allocating new node\n");
			return;
		}

		tmp->next = NULL;
		Q_memcpy(&tmp->log.net_address_, &adr, sizeof(netadr_t));

		list = firstLog;

		while (list->next)
			list = list->next;

		list->next = tmp;
	}
	else
	{
		firstLog = (LOGLIST_T *)Mem_Malloc(sizeof(LOGLIST_T));
		if (!firstLog)
		{
			Con_Printf("logaddress_add:  error allocating new node\n");
			return;
		}
		firstLog->next = NULL;
		Q_memcpy(&firstLog->log.net_address_, &adr, sizeof(netadr_t));
	}

	Con_Printf("logaddress_add:  %s\n", NET_AdrToString(adr));
}
Exemple #2
0
/* <9a345> ../engine/sv_log.c:439 */
void SV_DelLogAddress_f(void)
{
	const char *s;
	int nPort;
	char szAdr[MAX_PATH];
	netadr_t adr;
	LOGLIST_T *list;
	LOGLIST_T *prev;
	qboolean found = FALSE;

	if (Cmd_Argc() != 3)
	{
		Con_Printf("logaddress_del:  usage\nlogaddress_del ip port\n");
		for (list = firstLog; list != NULL; list = list->next)
			Con_Printf("current:  %s\n", NET_AdrToString(list->log.net_address_));
		return;
	}
	nPort = Q_atoi(Cmd_Argv(2));
	if (!nPort)
	{
		Con_Printf("logaddress_del:  must specify a valid port\n");
		return;
	}

	s = Cmd_Argv(1);
	if (!s || *s == '\0')
	{
		Con_Printf("logaddress_del:  unparseable address\n");
		return;
	}
	Q_snprintf(szAdr, sizeof(szAdr), "%s:%i", s, nPort);
	if (!NET_StringToAdr(szAdr,&adr))
	{
		Con_Printf("logaddress_del:  unable to resolve %s\n", szAdr);
		return;
	}
	if (!firstLog)
	{
		Con_Printf("logaddress_del:  No addresses added yet\n");
		return;
	}
	for(list = firstLog, prev = firstLog; list != NULL; list = list->next)
	{
#ifdef REHLDS_FIXES
		//for IPX
		if (NET_CompareAdr(adr,list->log.net_address_))
#else
		if (Q_memcmp(adr.ip, list->log.net_address_.ip, 4) == 0 && adr.port == list->log.net_address_.port)
#endif // REHLDS_FIXES
		{
			found = TRUE;
			if (list == prev)
			{
				firstLog = prev->next;
				Mem_Free(prev);
			}
			else
			{
				prev->next = list->next;
				Mem_Free(list);
			}
			break;
		}
		prev = list;
	}
	if (!found)
	{
		Con_Printf("logaddress_del:  Couldn't find address in list\n");
		return;
	}
	Con_Printf("deleting:  %s\n", NET_AdrToString(adr));
}
Exemple #3
0
/**
 * @brief Removes server(s) from the 'cache'
 * @param source Positive values AS_LOCAL, AS_GLOBAL, AS_FAVORITES
 *               or negative values AS_LOCAL_ALL, AS_GLOBAL_ALL, AS_FAVORITES_ALL to remove all
 * @param addr   Server address - in case of negative source param addr is not required
 *
 */
static void LAN_RemoveServer(int source, const char *addr)
{
	int          *count   = 0;
	serverInfo_t *servers = NULL;

	switch (source)
	{
	case AS_LOCAL:
	case AS_LOCAL_ALL:
		count   = &cls.numlocalservers;
		servers = &cls.localServers[0];
		break;
	case AS_GLOBAL:
	case AS_GLOBAL_ALL:
		count   = &cls.numglobalservers;
		servers = &cls.globalServers[0];
		break;
	case AS_FAVORITES:
	case AS_FAVORITES_ALL:
		count   = &cls.numfavoriteservers;
		servers = &cls.favoriteServers[0];
		break;
	}

	if (servers && count > 0)
	{
		if (source >= AS_LOCAL) // single server removal
		{
			netadr_t comp;
			int      i, j;

			NET_StringToAdr(addr, &comp, NA_UNSPEC);
			for (i = 0; i < *count; i++)
			{
				if (NET_CompareAdr(comp, servers[i].adr))
				{
					j = i;

					while (j < *count - 1)
					{
						Com_Memcpy(&servers[j], &servers[j + 1], sizeof(servers[j]));
						j++;
					}
					(*count)--;
					break;
				}
			}

			if (source == AS_FAVORITES)
			{
				LAN_SaveServersToFile();
			}
		}
		else // remove all
		{
			switch (source)
			{
			case AS_LOCAL_ALL:
				Com_Printf("Removing %i local servers\n", cls.numlocalservers);
				cls.numlocalservers = 0;
				Com_Memset(&cls.localServers, 0, sizeof(cls.localServers));
				break;
			case AS_GLOBAL_ALL:
				Com_Printf("Removing %i global servers\n", cls.numglobalservers);
				cls.numglobalservers = 0;
				Com_Memset(&cls.globalServers, 0, sizeof(cls.globalServers));
				break;
			case AS_FAVORITES_ALL:
				Com_Printf("Removing %i favourite servers\n", cls.numfavoriteservers);
				cls.numfavoriteservers = 0;
				Com_Memset(&cls.favoriteServers, 0, sizeof(cls.favoriteServers));
				LAN_SaveServersToFile();
				break;
			default:
				Com_Printf("LAN_RemoveServer: Invalid source\n");
				break;
			}
		}
	}
	else
	{
		Com_Printf("No server found - nothing to remove\n");
	}
}
Exemple #4
0
void SV_MasterHeartbeat(const char *message)
{
	static netadr_t	adr[MAX_MASTER_SERVERS][2]; // [2] for v4 and v6 address for the same address string.
	int			i;
	int			res;
	int			netenabled;

	netenabled = Cvar_VariableIntegerValue("net_enabled");

	// "dedicated 1" is for lan play, "dedicated 2" is for inet public play
	if ( ( (!com_dedicated || com_dedicated->integer != 2) && !(sv_public->integer) ) || !(netenabled & (NET_ENABLEV4 | NET_ENABLEV6)))
		return;		// only dedicated servers send heartbeats

	// if not time yet, don't send anything
	if ( svs.time < svs.nextHeartbeatTime )
		return;

	svs.nextHeartbeatTime = svs.time + HEARTBEAT_MSEC;

	// send to group masters
	for (i = 0; i < MAX_MASTER_SERVERS; i++)
	{
		if(!sv_master[i]->string[0])
			continue;

		// see if we haven't already resolved the name
		// resolving usually causes hitches on win95, so only
		// do it when needed
		if(sv_master[i]->modified || (adr[i][0].type == NA_BAD && adr[i][1].type == NA_BAD))
		{
			sv_master[i]->modified = qfalse;
			
			if(netenabled & NET_ENABLEV4)
			{
				Com_Printf("Resolving %s (IPv4)\n", sv_master[i]->string);
				res = NET_StringToAdr(sv_master[i]->string, &adr[i][0], NA_IP);

				if(res == 2)
				{
					// if no port was specified, use the default master port
					adr[i][0].port = BigShort(PORT_MASTER);
				}
				
				if(res)
					Com_Printf( "%s resolved to %s\n", sv_master[i]->string, NET_AdrToStringwPort(adr[i][0]));
				else
					Com_Printf( "%s has no IPv4 address.\n", sv_master[i]->string);
			}
			
			if(netenabled & NET_ENABLEV6)
			{
				Com_Printf("Resolving %s (IPv6)\n", sv_master[i]->string);
				res = NET_StringToAdr(sv_master[i]->string, &adr[i][1], NA_IP6);

				if(res == 2)
				{
					// if no port was specified, use the default master port
					adr[i][1].port = BigShort(PORT_MASTER);
				}
				
				if(res)
					Com_Printf( "%s resolved to %s\n", sv_master[i]->string, NET_AdrToStringwPort(adr[i][1]));
				else
					Com_Printf( "%s has no IPv6 address.\n", sv_master[i]->string);
			}

			if(adr[i][0].type == NA_BAD && adr[i][1].type == NA_BAD)
			{
				// if the address failed to resolve, clear it
				// so we don't take repeated dns hits
				Com_Printf("Couldn't resolve address: %s\n", sv_master[i]->string);
				Cvar_Set(sv_master[i]->name, "");
				sv_master[i]->modified = qfalse;
				continue;
			}
		}


		Com_Printf ("Sending heartbeat to %s\n", sv_master[i]->string );

		// this command should be changed if the server info / status format
		// ever incompatably changes

		if(adr[i][0].type != NA_BAD)
			NET_OutOfBandPrint( NS_SERVER, adr[i][0], "heartbeat %s\n", message);
		if(adr[i][1].type != NA_BAD)
			NET_OutOfBandPrint( NS_SERVER, adr[i][1], "heartbeat %s\n", message);
	}
}
Exemple #5
0
/*
==============
SV_InitGame

A brand new game has been started
==============
*/
void SV_InitGame (void)
{
	int		i;
	edict_t	*ent;
	char	idmaster[32];

	if (svs.initialized)
	{
		// cause any connected clients to reconnect
		SV_Shutdown ("Server restarted\n", true);
	}
	else
	{
		// make sure the client is down
		CL_Drop ();
		SCR_BeginLoadingPlaque ();
	}

	// get any latched variable changes (maxclients, etc)
	Cvar_GetLatchedVars ();

	svs.initialized = true;

	if (Cvar_VariableValue ("coop") && Cvar_VariableValue ("deathmatch"))
	{
		Com_Printf("Deathmatch and Coop both set, disabling Coop\n");
		Cvar_FullSet ("coop", "0",  CVAR_SERVERINFO | CVAR_LATCH);
	}

	// dedicated servers are can't be single player and are usually DM
	// so unless they explicity set coop, force it to deathmatch
	if (dedicated->value)
	{
		if (!Cvar_VariableValue ("coop"))
			Cvar_FullSet ("deathmatch", "1",  CVAR_SERVERINFO | CVAR_LATCH);
	}

	// init clients
	if (Cvar_VariableValue ("deathmatch"))
	{
		if (maxclients->value <= 1)
			Cvar_FullSet ("maxclients", "8", CVAR_SERVERINFO | CVAR_LATCH);
		else if (maxclients->value > MAX_CLIENTS)
			Cvar_FullSet ("maxclients", va("%i", MAX_CLIENTS), CVAR_SERVERINFO | CVAR_LATCH);
	}
	else if (Cvar_VariableValue ("coop"))
	{
		if (maxclients->value <= 1 || maxclients->value > 4)
			Cvar_FullSet ("maxclients", "4", CVAR_SERVERINFO | CVAR_LATCH);
#ifdef COPYPROTECT
		if (!sv.attractloop && !dedicated->value)
			Sys_CopyProtect ();
#endif
	}
	else	// non-deathmatch, non-coop is one player
	{
		Cvar_FullSet ("maxclients", "1", CVAR_SERVERINFO | CVAR_LATCH);
#ifdef COPYPROTECT
		if (!sv.attractloop)
			Sys_CopyProtect ();
#endif
	}

	svs.spawncount = rand();
	svs.clients = Z_Malloc (sizeof(client_t)*maxclients->value);
	svs.num_client_entities = maxclients->value*UPDATE_BACKUP*64;
	svs.client_entities = Z_Malloc (sizeof(entity_state_t)*svs.num_client_entities);

	// init network stuff
	NET_Config ( (maxclients->value > 1) );

	// heartbeats will always be sent to the id master
	svs.last_heartbeat = -99999;		// send immediately
	Com_sprintf(idmaster, sizeof(idmaster), "192.246.40.37:%i", PORT_MASTER);
	NET_StringToAdr (idmaster, &master_adr[0]);

	// init game
	SV_InitGameProgs ();
	for (i=0 ; i<maxclients->value ; i++)
	{
		ent = EDICT_NUM(i+1);
		ent->s.number = i+1;
		svs.clients[i].edict = ent;
		memset (&svs.clients[i].lastcmd, 0, sizeof(svs.clients[i].lastcmd));
	}
}
Exemple #6
0
static void FTP_GetExtendedPassiveAddress(const char* line, const char* address, netadr_t* adr)
{
	int i, j, port;
	
	Com_Memset(adr, 0, sizeof(netadr_t));
	
	i = 0;
	/* Remove the port number */

	if(NET_StringToAdr(address, adr, NA_UNSPEC) == 0)
	{	/* No valid address string. Must not happen.  */
		return;
	}
	
	/* Find the start of address */
	while(line[i] != '(' && line[i] != '\0')
		i++;
	
	if(line[i] != '(')
	{
		Com_Memset(adr,0, sizeof(netadr_t));
		return;
	}
	
	i++;
	
	for(j = 0; j < 3; j++)
	{
		while(line[i] != '|' && line[i] != ')' && line[i] != '\0')
			i++;
		
		if(line[i] == '|')
		{
			/* A delimiter */
			i++;
		}

	}	

	port = atoi(&line[i]);	
	
	if(port < 1 || port > 65535)
	{
		/* Something is invalid */
		Com_Memset(adr, 0, sizeof(netadr_t));
		return;
	}
	
	while(line[i] != '|' && line[i] != '\0')
		i++;
		
	if(line[i] == '|')
	{
		/* A delimiter */
		i++;
	}else {
		/* Something is invalid */
		Com_Memset(adr, 0, sizeof(netadr_t));
		return;
	}
	
	while(line[i] != ')' && line[i] != '\0')
		i++;	
	
	if(line[i] == ')')
	{
		adr->port = BigShort(port);
	}else {
		/* Something is invalid */
		Com_Memset(adr, 0, sizeof(netadr_t));
	}
	

	
}
Exemple #7
0
/*
===============
SVC_RemoteCommand

An rcon packet arrived from the network.
Shift down the remaining args
Redirect all printfs
===============
*/
void SVC_RemoteCommand( netadr_t from, msg_t *msg ) {
	qboolean	valid;
	unsigned int time;
	char		remaining[1024];
	netadr_t	allowedSpamIPAdress;
	// TTimo - scaled down to accumulate, but not overflow anything network wise, print wise etc.
	// (OOB messages are the bottleneck here)
#define SV_OUTPUTBUF_LENGTH (1024 - 16)
	char		sv_outputbuf[SV_OUTPUTBUF_LENGTH];
	static unsigned int lasttime = 0;
	char *cmd_aux;

	// TTimo - https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=534
	time = Com_Milliseconds();
	
	
	NET_StringToAdr( sv_rconAllowedSpamIP->string , &allowedSpamIPAdress);
	
	
	if ( !strlen( sv_rconPassword->string ) || strcmp (Cmd_Argv(1), sv_rconPassword->string) )
	{
		// let's the sv_rconAllowedSpamIP do spam rcon
		if ( ( !strlen( sv_rconAllowedSpamIP->string ) || !NET_CompareBaseAdr( from , allowedSpamIPAdress ) ) && !NET_IsLocalAddress(from) ){
			// MaJ - If the rconpassword is bad and one just happned recently, don't spam the log file, just die.
			if ( (unsigned)( time - lasttime ) < 600u )
				return;
		}
		
		valid = qfalse;
		Com_Printf ("Bad rcon from %s:\n%s\n", NET_AdrToString (from), Cmd_Argv(2) );
	} else {
	
		// let's the sv_rconAllowedSpamIP do spam rcon
		if ( ( !strlen( sv_rconAllowedSpamIP->string ) || !NET_CompareBaseAdr( from , allowedSpamIPAdress ) ) && !NET_IsLocalAddress(from) ){
			// MaJ - If the rconpassword is good, allow it much sooner than a bad one.
			if ( (unsigned)( time - lasttime ) < 180u )
				return;
		}
		
		valid = qtrue;
		Com_Printf ("Rcon from %s:\n%s\n", NET_AdrToString (from), Cmd_Argv(2) );
	}
	lasttime = time;

	// start redirecting all print outputs to the packet
	svs.redirectAddress = from;
	Com_BeginRedirect (sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_FlushRedirect);

	if ( !strlen( sv_rconPassword->string ) ) {
		Com_Printf ("No rconpassword set on the server.\n");
	} else if ( !valid ) {
		Com_Printf ("Bad rconpassword.\n");
	} else {
		remaining[0] = 0;
		
		// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=543
		// get the command directly, "rcon <pass> <command>" to avoid quoting issues
		// extract the command by walking
		// since the cmd formatting can fuckup (amount of spaces), using a dumb step by step parsing
		cmd_aux = Cmd_Cmd();
		cmd_aux+=4;
		while(cmd_aux[0]==' ')
			cmd_aux++;
		while(cmd_aux[0] && cmd_aux[0]!=' ') // password
			cmd_aux++;
		while(cmd_aux[0]==' ')
			cmd_aux++;
		
		Q_strcat( remaining, sizeof(remaining), cmd_aux);
		
		Cmd_ExecuteString (remaining);

	}

	Com_EndRedirect ();
}
Exemple #8
0
static void SV_AddBanToList(qboolean isexception)
{
	char *banstring, *suffix;
	netadr_t ip;
	int argc, mask;
	fileHandle_t writeto;
	
	argc = Cmd_Argc();
	
	if(argc < 2 || argc > 3)
	{
		Com_Printf ("Usage: %s (ip[/subnet] | clientnum [subnet])\n", Cmd_Argv(0));
		return;
	}

	if(serverBansCount > sizeof(serverBans) / sizeof(*serverBans))
	{
		Com_Printf ("Error: Maximum number of bans/exceptions exceeded.\n");
		return;
	}

	banstring = Cmd_Argv(1);
	
	if(strchr(banstring, '.') || strchr(banstring, ':'))
	{
		// This is an ip address, not a client num.
		
		// Look for a CIDR-Notation suffix
		suffix = strchr(banstring, '/');
		if(suffix)
		{
			*suffix = '\0';
			suffix++;
		}
		
		if(!NET_StringToAdr(banstring, &ip, NA_UNSPEC))
		{
			Com_Printf("Error: Invalid address %s\n", banstring);
			return;
		}
	}
	else
	{
		client_t *cl;
		
		// client num.
		if(!com_sv_running->integer)
		{
			Com_Printf("Server is not running.\n");
			return;
		}
		
		cl = SV_GetPlayerByNum();

		if(!cl)
		{
			Com_Printf("Error: Playernum %s does not exist.\n", Cmd_Argv(1));
			return;
		}
		
		ip = cl->netchan.remoteAddress;
		
		if(argc == 3)
			suffix = Cmd_Argv(2);
		else
			suffix = NULL;
	}

	if(ip.type != NA_IP && ip.type != NA_IP6)
	{
		Com_Printf("Error: Can ban players connected via the internet only.\n");
		return;
	}

	if(suffix)
	{
		mask = atoi(suffix);
		
		if(ip.type == NA_IP)
		{
			if(mask < 0 || mask > 32)
				mask = 32;
		}
		else
		{
			if(mask < 0 || mask > 128)
				mask = 128;
		}
	}
	else if(ip.type == NA_IP)
		mask = 32;
	else
		mask = 128;
	
	serverBans[serverBansCount].ip = ip;
	serverBans[serverBansCount].subnet = mask;
	serverBans[serverBansCount].isexception = isexception;
	
	Com_Printf("Added %s: %s/%d\n", isexception ? "ban exception" : "ban",
		   NET_AdrToString(ip), mask);

	// Write out the ban information.
	if((writeto = FS_FOpenFileAppend(SERVER_BANFILE)))
	{
		char writebuf[128];
		
		Com_sprintf(writebuf, sizeof(writebuf), "%d %s %d\n", isexception, NET_AdrToString(ip), mask);
		FS_Write(writebuf, strlen(writebuf), writeto);
		FS_FCloseFile(writeto);
	}
	
	serverBansCount++;
}
Exemple #9
0
/*
====================
CL_UISystemCalls

The ui module is making a system call
====================
*/
intptr_t CL_UISystemCalls( intptr_t *args ) {
//				Com_Printf( "SYSCALL(%d)\n", args[0]);
		switch( args[0] ) {
		case UI_ERROR:
				Com_Error( ERR_DROP, "%s", (const char*)VMA(1) );
				return 0;

		case UI_PRINT:
				Com_Printf( "%s", (const char*)VMA(1) );
				return 0;

		case UI_MILLISECONDS:
				return Sys_Milliseconds();

		case UI_CVAR_REGISTER:
				Cvar_Register( VMA(1), VMA(2), VMA(3), args[4] );
				return 0;

		case UI_CVAR_UPDATE:
				Cvar_Update( VMA(1) );
				return 0;

		case UI_CVAR_SET:
				Cvar_Set( VMA(1), VMA(2) );
				return 0;

		case UI_CVAR_VARIABLEVALUE:
				return FloatAsInt( Cvar_VariableValue( VMA(1) ) );

		case UI_CVAR_VARIABLESTRINGBUFFER:
				Cvar_VariableStringBuffer( VMA(1), VMA(2), args[3] );
				return 0;

		case UI_CVAR_SETVALUE:
				Cvar_SetValue( VMA(1), VMF(2) );
				return 0;

		case UI_CVAR_RESET:
				Cvar_Reset( VMA(1) );
				return 0;

		case UI_CVAR_CREATE:
				Cvar_Get( VMA(1), VMA(2), args[3] );
				return 0;

		case UI_CVAR_INFOSTRINGBUFFER:
				Cvar_InfoStringBuffer( args[1], VMA(2), args[3] );
				return 0;

		case UI_ARGC:
				return Cmd_Argc();

		case UI_ARGV:
				Cmd_ArgvBuffer( args[1], VMA(2), args[3] );
				return 0;

		case UI_CMD_EXECUTETEXT:
				if(args[1] == 0
				&& (!strncmp(VMA(2), "snd_restart", 11)
				|| !strncmp(VMA(2), "vid_restart", 11)
				|| !strncmp(VMA(2), "quit", 5)))
				{
						Com_Printf (S_COLOR_YELLOW "turning EXEC_NOW '%.11s' into EXEC_INSERT\n", (const char*)VMA(2));
						args[1] = EXEC_INSERT;
				}
				Cbuf_ExecuteText( args[1], VMA(2) );
				return 0;

		case UI_FS_FOPENFILE:
				return FS_FOpenFileByMode( VMA(1), VMA(2), args[3] );

		case UI_FS_READ:
				FS_Read2( VMA(1), args[2], args[3] );
				return 0;

		case UI_FS_WRITE:
				FS_Write( VMA(1), args[2], args[3] );
				return 0;

		case UI_FS_FCLOSEFILE:
				FS_FCloseFile( args[1] );
				return 0;

		case UI_FS_GETFILELIST:
				return FS_GetFileList( VMA(1), VMA(2), VMA(3), args[4] );

		case UI_FS_SEEK:
				return FS_Seek( args[1], args[2], args[3] );

		case UI_R_REGISTERMODEL:
				return re.RegisterModel( VMA(1) );

		case UI_R_REGISTERSKIN:
				return re.RegisterSkin( VMA(1) );

		case UI_R_REGISTERSHADERNOMIP:
				return re.RegisterShaderNoMip( VMA(1) );

		case UI_R_CLEARSCENE:
				re.ClearScene();
				return 0;

		case UI_R_ADDREFENTITYTOSCENE:
				re.AddRefEntityToScene( VMA(1) );
				return 0;

		case UI_R_ADDPOLYTOSCENE:
				re.AddPolyToScene( args[1], args[2], VMA(3), 1 );
				return 0;

		case UI_R_ADDLIGHTTOSCENE:
				re.AddLightToScene( VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) );
				return 0;

		case UI_R_RENDERSCENE:
				re.RenderScene( VMA(1) );
				return 0;

		case UI_R_SETCOLOR:
				re.SetColor( VMA(1) );
				return 0;

		case UI_R_DRAWSTRETCHPIC:
				re.DrawStretchPic( VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), args[9] );
				return 0;

  case UI_R_MODELBOUNDS:
				re.ModelBounds( args[1], VMA(2), VMA(3) );
				return 0;

		case UI_UPDATESCREEN:
				SCR_UpdateScreen();
				return 0;

		case UI_CM_LERPTAG:
				re.LerpTag( VMA(1), args[2], args[3], args[4], VMF(5), VMA(6) );
				return 0;

		case UI_S_REGISTERSOUND:
				return S_RegisterSound( VMA(1), args[2] );

		case UI_S_STARTLOCALSOUND:
				S_StartLocalSound( args[1], args[2] );
				return 0;

		case UI_KEY_KEYNUMTOSTRINGBUF:
				Key_KeynumToStringBuf( args[1], VMA(2), args[3] );
				return 0;

		case UI_KEY_GETBINDINGBUF:
				Key_GetBindingBuf( args[1], VMA(2), args[3] );
				return 0;

		case UI_KEY_SETBINDING:
				Key_SetBinding( args[1], VMA(2) );
				return 0;

		case UI_KEY_ISDOWN:
				return Key_IsDown( args[1] );

		case UI_KEY_GETOVERSTRIKEMODE:
				return Key_GetOverstrikeMode();

		case UI_KEY_SETOVERSTRIKEMODE:
				Key_SetOverstrikeMode( args[1] );
				return 0;

		case UI_KEY_CLEARSTATES:
				Key_ClearStates();
				return 0;

		case UI_KEY_GETCATCHER:
				return Key_GetCatcher();

		case UI_KEY_SETCATCHER:
				// Don't allow the ui module to close the console
				Key_SetCatcher( args[1] | ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) );
				return 0;

		case UI_GETCLIPBOARDDATA:
				CL_GetClipboardData( VMA(1), args[2] );
				return 0;

		case UI_GETCLIENTSTATE:
				GetClientState( VMA(1) );
				return 0;

		case UI_GETGLCONFIG:
				CL_GetGlconfig( VMA(1) );
				return 0;

		case UI_GETCONFIGSTRING:
				return GetConfigString( args[1], VMA(2), args[3] );

		case UI_LAN_LOADCACHEDSERVERS:
				LAN_LoadCachedServers();
				return 0;

		case UI_LAN_SAVECACHEDSERVERS:
				LAN_SaveServersToCache();
				return 0;

		case UI_LAN_ADDSERVER:
				return LAN_AddServer(args[1], VMA(2), VMA(3));

		case UI_LAN_REMOVESERVER:
				LAN_RemoveServer(args[1], VMA(2));
				return 0;

		case UI_LAN_GETPINGQUEUECOUNT:
				return LAN_GetPingQueueCount();

		case UI_LAN_CLEARPING:
				LAN_ClearPing( args[1] );
				return 0;

		case UI_LAN_GETPING:
				LAN_GetPing( args[1], VMA(2), args[3], VMA(4) );
				return 0;

		case UI_LAN_GETPINGINFO:
				LAN_GetPingInfo( args[1], VMA(2), args[3] );
				return 0;

		case UI_LAN_GETSERVERCOUNT:
				return LAN_GetServerCount(args[1]);

		case UI_LAN_GETSERVERADDRESSSTRING:
				LAN_GetServerAddressString( args[1], args[2], VMA(3), args[4] );
				return 0;

		case UI_LAN_GETSERVERINFO:
				LAN_GetServerInfo( args[1], args[2], VMA(3), args[4] );
				return 0;

		case UI_LAN_GETSERVERPING:
				return LAN_GetServerPing( args[1], args[2] );

		case UI_LAN_MARKSERVERVISIBLE:
				LAN_MarkServerVisible( args[1], args[2], args[3] );
				return 0;

		case UI_LAN_SERVERISVISIBLE:
				return LAN_ServerIsVisible( args[1], args[2] );

		case UI_LAN_UPDATEVISIBLEPINGS:
				return LAN_UpdateVisiblePings( args[1] );

		case UI_LAN_RESETPINGS:
				LAN_ResetPings( args[1] );
				return 0;

		case UI_LAN_SERVERSTATUS:
				return LAN_GetServerStatus( VMA(1), VMA(2), args[3] );

		case UI_LAN_COMPARESERVERS:
				return LAN_CompareServers( args[1], args[2], args[3], args[4], args[5] );

		case UI_MEMORY_REMAINING:
				return Hunk_MemoryRemaining();

		case UI_GET_CDKEY:
				CLUI_GetCDKey( VMA(1), args[2] );
				return 0;

		case UI_SET_CDKEY:
#ifndef STANDALONE
				CLUI_SetCDKey( VMA(1) );
#endif
				return 0;

		case UI_SET_PBCLSTATUS:
				return 0;

		case UI_R_REGISTERFONT:
				re.RegisterFont( VMA(1), args[2], VMA(3));
				return 0;

		case UI_MEMSET:
				Com_Memset( VMA(1), args[2], args[3] );
				return 0;

		case UI_MEMCPY:
				Com_Memcpy( VMA(1), VMA(2), args[3] );
				return 0;

		case UI_STRNCPY:
				strncpy( VMA(1), VMA(2), args[3] );
				return args[1];

		case UI_SIN:
				return FloatAsInt( sin( VMF(1) ) );

		case UI_COS:
				return FloatAsInt( cos( VMF(1) ) );

		case UI_ATAN2:
				return FloatAsInt( atan2( VMF(1), VMF(2) ) );

		case UI_SQRT:
				return FloatAsInt( sqrt( VMF(1) ) );

		case UI_FLOOR:
				return FloatAsInt( floor( VMF(1) ) );

		case UI_CEIL:
				return FloatAsInt( ceil( VMF(1) ) );

		case UI_PC_ADD_GLOBAL_DEFINE:
				return botlib_export->PC_AddGlobalDefine( VMA(1) );
		case UI_PC_LOAD_SOURCE:
				return botlib_export->PC_LoadSourceHandle( VMA(1) );
		case UI_PC_FREE_SOURCE:
				return botlib_export->PC_FreeSourceHandle( args[1] );
		case UI_PC_READ_TOKEN:
				return botlib_export->PC_ReadTokenHandle( args[1], VMA(2) );
		case UI_PC_SOURCE_FILE_AND_LINE:
				return botlib_export->PC_SourceFileAndLine( args[1], VMA(2), VMA(3) );

		case UI_S_STOPBACKGROUNDTRACK:
				S_StopBackgroundTrack();
				return 0;
		case UI_S_STARTBACKGROUNDTRACK:
				S_StartBackgroundTrack( VMA(1), VMA(2));
				return 0;

		case UI_REAL_TIME:
				return Com_RealTime( VMA(1) );

		case UI_CIN_PLAYCINEMATIC:
		  Com_DPrintf("UI_CIN_PlayCinematic\n");
		  return CIN_PlayCinematic(VMA(1), args[2], args[3], args[4], args[5], args[6]);

		case UI_CIN_STOPCINEMATIC:
		  return CIN_StopCinematic(args[1]);

		case UI_CIN_RUNCINEMATIC:
		  return CIN_RunCinematic(args[1]);

		case UI_CIN_DRAWCINEMATIC:
		  CIN_DrawCinematic(args[1]);
		  return 0;

		case UI_CIN_SETEXTENTS:
		  CIN_SetExtents(args[1], args[2], args[3], args[4], args[5]);
		  return 0;

		case UI_R_REMAP_SHADER:
				re.RemapShader( VMA(1), VMA(2), VMA(3) );
				return 0;

		case UI_VERIFY_CDKEY:
				return CL_CDKeyValidate(VMA(1), VMA(2));

#ifdef USE_AUTH
		case UI_NET_STRINGTOADR:
				return NET_StringToAdr(VMA(1), VMA(2), NA_IP);

		case UI_Q_VSNPRINTF:
				return Q_vsnprintf(VMA(1), (size_t)VMA(2), VMA(3), VMA(4));

		case UI_NET_SENDPACKET:
				{
				netadr_t addr;
				const char *destination = VMA(4);

				NET_StringToAdr(destination, &addr, NA_IP);
				NET_SendPacket(args[1], args[2], VMA(3), addr);
				}
				return 0;

		case UI_COPYSTRING:
				return (intptr_t)CopyString(VMA(1));

		case UI_SYS_STARTPROCESS:
				//Sys_StartProcess(VMA(1), (qboolean) VMA(2));
				return 0;
#endif
		default:
				Com_Error( ERR_DROP, "Bad UI system trap: %ld", (long int) args[0] );

		}

		return 0;
}
Exemple #10
0
/*
===============
SV_MasterHeartbeat
===============
*/
void SV_MasterHeartbeat( const char *hbname ) {
	static netadr_t adr[MAX_MASTER_SERVERS][2];
	int				i, res, netenabled;

	// Update Server doesn't send heartbeat
#if defined (UPDATE_SERVER)
	return;
#endif

	netenabled = Cvar_VariableIntegerValue("net_enabled");
	
	if ( SV_GameIsSinglePlayer() ) {
		return;     // no heartbeats for SP
	}

	// "dedicated 1" is for lan play, "dedicated 2" is for inet public play
	if (!com_dedicated || com_dedicated->integer != 2 || !(netenabled & (NET_ENABLEV4 | NET_ENABLEV6))) {
		return;     // only dedicated servers send heartbeats
	}

	// if not time yet, don't send anything
	if ( svs.time < svs.nextHeartbeatTime ) {
		return;
	}

	svs.nextHeartbeatTime = svs.time + HEARTBEAT_MSEC;

	// send to group masters
	for (i = 0; i < MAX_MASTER_SERVERS; i++) {
		if(!sv_master[i]->string[0]) {
			continue;
		}

		// see if we haven't already resolved the name
		// resolving usually causes hitches on win95, so only
		// do it when needed
		if(sv_master[i]->modified || (adr[i][0].type == NA_BAD && adr[i][1].type == NA_BAD)) {
			sv_master[i]->modified = false;

			if(netenabled & NET_ENABLEV4) {
				Com_Printf("Resolving %s (IPv4)\n", sv_master[i]->string);
				res = NET_StringToAdr(sv_master[i]->string, &adr[i][0], NA_IP);

				if(res == 2) {
					// if no port was specified, use the default master port
					adr[i][0].port = BigShort(PORT_MASTER);
				}
			
				if(res) {
					Com_Printf( "%s resolved to %s\n", sv_master[i]->string, NET_AdrToStringwPort(adr[i][0]));
				} else {
					Com_Printf( "%s has no IPv4 address.\n", sv_master[i]->string);
				}
			}
			
			if(netenabled & NET_ENABLEV6) {
				Com_Printf("Resolving %s (IPv6)\n", sv_master[i]->string);
				res = NET_StringToAdr(sv_master[i]->string, &adr[i][1], NA_IP6);

				if(res == 2) {
					// if no port was specified, use the default master port
					adr[i][1].port = BigShort(PORT_MASTER);
				}
				
				if(res) {
					Com_Printf( "%s resolved to %s\n", sv_master[i]->string, NET_AdrToStringwPort(adr[i][1]));
				} else {
					Com_Printf( "%s has no IPv6 address.\n", sv_master[i]->string);
				}
			}

			if(adr[i][0].type == NA_BAD && adr[i][1].type == NA_BAD) {
				// if the address failed to resolve, clear it
				// so we don't take repeated dns hits
				Com_Printf( "Couldn't resolve address: %s\n", sv_master[i]->string );
				Cvar_Set( sv_master[i]->name, "" );
				sv_master[i]->modified = false;
				continue;
			}
		}

		Com_Printf( "Sending heartbeat to the official OpenWolf servers list %s\n", sv_master[i]->string );

		// this command should be changed if the server info / status format
		// ever incompatably changes

		if(adr[i][0].type != NA_BAD) {
			NET_OutOfBandPrint( NS_SERVER, adr[i][0], "heartbeat %s\n", HEARTBEAT_GAME );
		}
		if(adr[i][1].type != NA_BAD) {
			NET_OutOfBandPrint( NS_SERVER, adr[i][1], "heartbeat %s\n", HEARTBEAT_GAME );
		}
	}

#if defined (USE_PHP)
	// Send to the main master.
	if (svs.queryDone) {
		pthread_exit(&svs.thQuery);
		svs.queryDone = 0;
	} else {
		SV_PHPMaster();
	}
#endif
}
void Master_Init() {

   int i, SkipSection, tempport;
   static int HaveConfigured = 0;
   char * filep;
   const char * curfilep;
   netadr_t tempadr;


   if(HaveConfigured != 0 || gfNoMasterServer != 0) { return; }

   HaveConfigured = 1;

   if(COM_CheckParmCase("-nomaster") != 0 || global_svs.allocated_client_slots <= 1) {

      Con_Printf("%s: Master server comm disabled.\n", __FUNCTION__);
      gfNoMasterServer = 0;
      return; //and don't check again, ever.
   }

   MasterHeartbeatTimeout = 15;

   i = COM_CheckParmCase("-comm");
   if(i != 0 && i+1 < global_com_argc) {

      filep = COM_LoadFileForMe(global_com_argv[i+1], NULL);
   }
   else {

      filep = COM_LoadFileForMe("valvecomm.lst", NULL);
      if(filep == NULL) {
         filep = COM_LoadFileForMe("woncomm.lst", NULL);
      }
   }

   if(filep == NULL) {
      Con_Printf("%s: Couldn't load comm file.  Disabling masters--fix it.\n", __FUNCTION__);
      return;
   }

   curfilep = filep;
   i = 0;
   while(1) {

      curfilep = COM_Parse(curfilep);
      if(global_com_token[0] == '\0') { break; }

      SkipSection = 1;
      if(Q_strcasecmp("master", global_com_token) == 0) {
         SkipSection = 0;
      }

      curfilep = COM_Parse(curfilep);
      if(Q_strcmp("{", global_com_token) != 0) { break; }

      while(1) {

         curfilep = COM_Parse(curfilep);
         if(global_com_token[0] == '\0' || Q_strcmp("}", global_com_token) == 0) { break; }
         if(SkipSection == 0 && NET_StringToAdr(global_com_token, &tempadr) == 0) { break; }

         //We just (maybe) parsed the server name, if you missed it.  Now for the port.
         curfilep = COM_Parse(curfilep);
         if(Q_strcmp(":", global_com_token) != 0) { break; }

         curfilep = COM_Parse(curfilep);
         if(global_com_token[0] == '\0') { break; }

         if(SkipSection == 0) {

            tempport = Q_atoi(global_com_token);
            if(tempport < 1 || tempport > 65535) { tempport = 27010; }
            tempadr.port = tempport;

            Con_Printf("%s: Adding master server %s.\n", __FUNCTION__, NET_AdrToString(tempadr)); //all that work to avoid needless string copying, all gone :)
            Master_AddServer(&tempadr);
            i++;
         }
      }
   }

   COM_FreeFile(filep);

   if(i == 0) {
      Con_Printf("%s: Didn't parse any masters.  Disabling master comm.\n", __FUNCTION__);
      gfNoMasterServer = 0;
   }
}
void Master_SetMaster_f() {

   int AreAdding;
   const char * arg_1, * arg_2;
   int port;
   netadr_t netaddress;
   master_server_t * ptr, * ptr2;

   if(Cmd_Argc() < 2 || Cmd_Argc() > 4) {

      Con_Printf("Setmaster <add | remove | enable | disable> <IP:port>\n");
      Con_Printf(" Current master list:\n");

      for(ptr = masterlist; ptr != NULL; ptr = ptr->next) {

         Con_Printf("  %s\n", NET_AdrToString(ptr->address));
      }

      Con_Printf(" End if list\n");
      return;
   }

   arg_1 = Cmd_Argv(1);
   if(arg_1[0] == '\0') { return; }

   if(Q_strcasecmp(arg_1, "disable") == 0) { gfNoMasterServer = 1; return; }
   if(Q_strcasecmp(arg_1, "enable") == 0) { gfNoMasterServer = 0; return; }

   if(Q_strcasecmp(arg_1, "add") == 0) { AreAdding = 1; }
   else if(Q_strcasecmp(arg_1, "remove") == 0) { AreAdding = 0; }
   else {

      Con_Printf("Setmaster:  Unknown command \"%s\".\n", arg_1);
      return;
   }

   arg_2 = Cmd_Argv(2);

   if(Cmd_Argc() == 4) {
      port = Q_atoi(Cmd_Argv(3));
      if(port < 1 || port > 65535) {
         Con_Printf("Setmaster: Invalid port.  Ports can't be larger than 65535.\n");
         return;
      }
   }
   else {
      port = 27010;
   }

   if(NET_StringToAdr(arg_2, &netaddress) == 0) {
      Con_Printf("Setmaster: Passed address could not be processed by StringToAdr.\n");
      return;
   }
   netaddress.port = port;

   if(AreAdding) {

      Master_Init();
      Master_AddServer(&netaddress);
      gfNoMasterServer = 0;
      Con_Printf("Master server %s:%u added.\n", arg_2, port);
   }
   else {

      //case 1: first node.
      if(NET_CompareAdr(masterlist->address, netaddress) != 0) {
         ptr = masterlist;
         masterlist = masterlist->next;
         Q_Free(ptr);
         return;
      }

      //case 2: some node afterwards
      for(ptr = masterlist; ptr->next != NULL; ptr = ptr->next) {
         if(NET_CompareAdr(ptr->next->address, netaddress) != 0) {

            ptr2 = ptr->next;
            ptr->next = ptr->next->next;
            Q_Free(ptr2);
            return;
         }
      }
      //case 3: not here
      Con_Printf("Master %s:%u couldn't be removed.  Couldn't find it.\n", arg_2, port);
   }
}
void Reload_Sources(void)
{
    int i;
    vfsfile_t *f;
    char ln[2048];
    source_data *s;

    for (i=0; i < sourcesn; i++)
        Delete_Source(sources[i]);
    sourcesn = 0;

    // create dummy unbound source
    sources[0] = Create_Source();
    sources[0]->type = type_dummy;
    strlcpy (sources[0]->name, "Unbound", sizeof (sources[0]->name));
    sources[0]->servers = (server_data **) Q_malloc(MAX_UNBOUND*sizeof(server_data *));

    sourcesn = 1;

    f = FS_OpenVFS(SOURCES_LIST_FILENAME, "rb", FS_ANY);
    if (!f)
    {
        //Com_Printf ("sources file not found: %s\n", SOURCES_PATH);
        return;
    }

    s = Create_Source();
    while (VFS_GETS(f, ln, sizeof(ln)))
    {
        char line[2048];
        char *p, *q;

        if (sscanf(ln, "%[ -~	]s", line) != 1) {
            continue;
        }

        p = next_nonspace(line);
        if (*p == '/')
            continue;   // comment
        q = next_space(p);

        if (!strncmp(p, "master", q-p)) {
            s->type = type_master;
        }
        else if (!strncmp(p, "file", q-p)) {
            s->type = type_file;
        }
        else if (!strncmp(p, "url", q-p)) {
            s->type = type_url;
        }
        else {
            continue;
        }

        p = next_nonspace(q);
        q = (*p == '\"') ? next_quote(++p) : next_space(p);

        if (q-p <= 0)
            continue;

        strlcpy (s->name, p, min(q-p+1, MAX_SOURCE_NAME+1));

        p = next_nonspace(q+1);
        q = next_space(p);
        *q = 0;

        if (q-p <= 0)
            continue;

        if (s->type == type_file)
            strlcpy (s->address.filename, p, sizeof (s->address.filename));
        else if (s->type == type_url)
            strlcpy (s->address.url, p, sizeof (s->address.url));
        else if (!NET_StringToAdr(p, &(s->address.address)))
            continue;

        sources[sourcesn] = Create_Source();
        i = sources[sourcesn]->unique;
        memcpy(sources[sourcesn], s, sizeof(source_data));
        sources[sourcesn]->unique = i;
        sourcesn++;
    }

    Delete_Source(s);
    VFS_CLOSE(f);

    //Com_Printf("Read %d sources for Server Browser\n", sourcesn);

    // update all file sources
    for (i=0; i < sourcesn; i++)
        if (sources[i]->type == type_file)
            Update_Source(sources[i]);
        else if (sources[i]->type == type_master || sources[i]->type == type_url)
            Precache_Source(sources[i]);

    rebuild_servers_list = 1;
    resort_sources = 1;
}
Exemple #14
0
void SV_UnbanIP_f() {
	if(Cmd_Argc()!=2) {
		Com_Printf("Usage: unbanip <ip>\n");
		return;
	}
	
	aSingleBan *current = banlist;
	
	char* ip = Cmd_Argv(1);
	netadr_t ipadr;
	NET_StringToAdr(ip, &ipadr);
	
	FILE* f = fopen("ipbans.txt", "w");
	
	if(f) {
		
		while(current!=NULL) {
			if(current->type == IPBAN) {
				if(NET_CompareBaseAdr(current->adr, ipadr)) {
					Com_Printf("IP '%s' has been unbanned.\n", ip);
					current=current->next;
					continue;
				}
				fprintf(f, "%s\n", NET_BaseAdrToString(current->adr));
			}
			current = current->next;
		}
	
		fclose(f);
	}
	
	X_ReadBannedList(false);
	
	/*qboolean found = qfalse;
	netadr_t unban;
	
	if(Cmd_Argc() != 2) {
		Com_Printf("Usage: unbanip \"127.0.0.1\"\n");
		return;
	}
	
	FILE* f = fopen("ipban.txt", "w");
	
	if(!f) {
		Com_Printf("Failed to open ipban.txt\n");
		return;
	}
	
	NET_StringToAdr(Cmd_Argv(1), &unban);
	
	std::ifstream in("ipban.txt");
	std::string line;
	if(in.is_open()) {
		bannedIPs.clear();
		
		netadr_t adr;
		while(std::getline(in, line)) {
			if(line.empty())
				continue;
			NET_StringToAdr(line.c_str(), &adr);
			
			if(!strcmp(Cmd_Argv(1), line.c_str())) {
				Com_Printf("'%s' has been unbanned.\n", Cmd_Argv(1));
				found = qtrue;
				continue;
			}
			fprintf(f, "%s\n", NET_BaseAdrToString(adr));
			bannedIPs.push_back(adr);
		}
		if(!found) {
			Com_Printf("'%s' was not found in the banlist.\n", Cmd_Argv(1));
		}
	} else {
		Com_Printf("Error whilst reading ipban.txt, failed to correctly unban.\n");
	}
	
	fclose(f);
	*/
}
Exemple #15
0
/*
==================
SV_RehashServerRconFile

Helper to reload a "serverRcon_t" type of file
Returns number of entries loaded
==================
*/
static int SV_RehashServerRconFile(convar_t *fileName, int maxEntries, serverRcon_t buffer[])
{
	int index, filelen, numEntries = 0;
	fileHandle_t readfrom;
	char *textbuf, *curpos, *maskpos, *newlinepos, *endpos, filepath[MAX_QPATH];

	if(!fileName->string || !*fileName->string)
	{
		goto exit;
	}

	if(!(curpos = Cvar_VariableString("fs_game")) || !*curpos)
	{
		curpos = BASEGAME;
	}

	Com_sprintf(filepath, sizeof(filepath), "%s/%s", curpos, fileName->string);

	if((filelen = FS_SV_FOpenFileRead(filepath, &readfrom)) < 0)
	{
		Com_Printf("SV_RehashServerRconFile: failed to open %s\n", filepath);
		goto exit;
	}

	if(filelen < 2)
	{
		// Don't bother if file is too short.
		FS_FCloseFile(readfrom);
		goto exit;
	}

	curpos = textbuf = (char*)Z_Malloc(filelen);

	filelen = FS_Read(textbuf, filelen, readfrom);
	FS_FCloseFile(readfrom);

	endpos = textbuf + filelen;

	for(index = 0; index < maxEntries && curpos + 2 < endpos; index++)
	{
		// find the end of the address string
		for(maskpos = curpos + 2; maskpos < endpos && *maskpos != ' '; maskpos++);

		if(maskpos + 1 >= endpos)
		{
			break;
		}

		*maskpos = '\0';
		maskpos++;

		// find the end of the subnet specifier
		for(newlinepos = maskpos; newlinepos < endpos && *newlinepos != '\n'; newlinepos++);

		if(newlinepos >= endpos)
		{
			break;
		}

		*newlinepos = '\0';

		if(NET_StringToAdr(curpos + 2, &buffer[index].ip, NA_UNSPEC))
		{
			buffer[index].isexception = (qboolean)(curpos[0] != '0');
			buffer[index].subnet = atoi(maskpos);

			if(buffer[index].ip.type == NA_IP && (buffer[index].subnet < 1 || buffer[index].subnet > 32))
			{
				buffer[index].subnet = 32;
			}
			else if(buffer[index].ip.type == NA_IP6 && (buffer[index].subnet < 1 || buffer[index].subnet > 128))
			{
				buffer[index].subnet = 128;
			}
		}

		curpos = newlinepos + 1;
	}

	Z_Free(textbuf);
	numEntries = index;

exit:
	return numEntries;
}
/*
=================
SV_GetChallenge

A "getchallenge" OOB command has been received
Returns a challenge number that can be used
in a subsequent connectResponse command.
We do this to prevent denial of service attacks that
flood the server with invalid connection IPs.  With a
challenge, they must give a valid IP address.

If we are authorizing, a challenge request will cause a packet
to be sent to the authorize server.

When an authorizeip is returned, a challenge response will be
sent to that ip.
=================
*/
void SV_GetChallenge( netadr_t from ) {
	int		i;
	int		oldest;
	int		oldestTime;
	challenge_t	*challenge;

	// ignore if we are in single player
	if ( Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER || Cvar_VariableValue("ui_singlePlayerActive")) {
		return;
	}

	oldest = 0;
	oldestTime = 0x7fffffff;

	// see if we already have a challenge for this ip
	challenge = &svs.challenges[0];
	for (i = 0 ; i < MAX_CHALLENGES ; i++, challenge++) {
		if ( !challenge->connected && NET_CompareAdr( from, challenge->adr ) ) {
			break;
		}
		if ( challenge->time < oldestTime ) {
			oldestTime = challenge->time;
			oldest = i;
		}
	}

	if (i == MAX_CHALLENGES) {
		// this is the first time this client has asked for a challenge
		challenge = &svs.challenges[oldest];

		challenge->challenge = ( (rand() << 16) ^ rand() ) ^ svs.time;
		challenge->adr = from;
		challenge->firstTime = svs.time;
		challenge->time = svs.time;
		challenge->connected = qfalse;
		i = oldest;
	}

	// if they are on a lan address, send the challengeResponse immediately
	if ( Sys_IsLANAddress( from ) ) {
		challenge->pingTime = svs.time;
		NET_OutOfBandPrint( NS_SERVER, from, "challengeResponse %i", challenge->challenge );
		return;
	}

	// look up the authorize server's IP
	if ( !svs.authorizeAddress.ip[0] && svs.authorizeAddress.type != NA_BAD ) {
		Com_Printf( "Resolving %s\n", AUTHORIZE_SERVER_NAME );
		if ( !NET_StringToAdr( AUTHORIZE_SERVER_NAME, &svs.authorizeAddress ) ) {
			Com_Printf( "Couldn't resolve address\n" );
			return;
		}
		svs.authorizeAddress.port = BigShort( PORT_AUTHORIZE );
		Com_Printf( "%s resolved to %i.%i.%i.%i:%i\n", AUTHORIZE_SERVER_NAME,
			svs.authorizeAddress.ip[0], svs.authorizeAddress.ip[1],
			svs.authorizeAddress.ip[2], svs.authorizeAddress.ip[3],
			BigShort( svs.authorizeAddress.port ) );
	}

	// if they have been challenging for a long time and we
	// haven't heard anything from the authorize server, go ahead and
	// let them in, assuming the id server is down
	if ( svs.time - challenge->firstTime > AUTHORIZE_TIMEOUT ) {
		Com_DPrintf( "authorize server timed out\n" );

		challenge->pingTime = svs.time;
		NET_OutOfBandPrint( NS_SERVER, challenge->adr, 
			"challengeResponse %i", challenge->challenge );
		return;
	}

	// otherwise send their ip to the authorize server
	if ( svs.authorizeAddress.type != NA_BAD ) {
		cvar_t	*fs;
		char	game[1024];

		Com_DPrintf( "sending getIpAuthorize for %s\n", NET_AdrToString( from ));
		
		strcpy(game, BASEGAME);
		fs = Cvar_Get ("fs_game", "", CVAR_INIT|CVAR_SYSTEMINFO );
		if (fs && fs->string[0] != 0) {
			strcpy(game, fs->string);
		}
		
		// the 0 is for backwards compatibility with obsolete sv_allowanonymous flags
		// getIpAuthorize <challenge> <IP> <game> 0 <auth-flag>
		NET_OutOfBandPrint( NS_SERVER, svs.authorizeAddress,
			"getIpAuthorize %i %i.%i.%i.%i %s 0 %s",  svs.challenges[i].challenge,
			from.ip[0], from.ip[1], from.ip[2], from.ip[3], game, sv_strictAuth->string );
	}
}
Exemple #17
0
/*
=================
SV_GetChallenge

A "getchallenge" OOB command has been received
Returns a challenge number that can be used
in a subsequent connectResponse command.
We do this to prevent denial of service attacks that
flood the server with invalid connection IPs.  With a
challenge, they must give a valid IP address.

If we are authorizing, a challenge request will cause a packet
to be sent to the authorize server.

When an authorizeip is returned, a challenge response will be
sent to that ip.

ioquake3: we added a possibility for clients to add a challenge
to their packets, to make it more difficult for malicious servers
to hi-jack client connections.
Also, the auth stuff is completely disabled for com_standalone games
as well as IPv6 connections, since there is no way to use the
v4-only auth server for these new types of connections.
=================
*/
void SV_GetChallenge( netadr_t from ) {
	static leakyBucket_t outboundLeakyBucket;
	int		i;
	int		oldest;
	int		oldestTime;
	int		oldestClientTime;
	int		clientChallenge;
	challenge_t	*challenge;
	qboolean wasfound = qfalse;

	// ignore if we are in single player
	if ( Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER || Cvar_VariableValue("ui_singlePlayerActive")) {
		return;
	}

		// Prevent using getchallenge as an amplifier
	if ( SVC_RateLimitAddress( from, 10, 1000 ) ) {
		Com_DPrintf( "SV_GetChallenge: rate limit from %s exceeded, dropping request\n",
			NET_AdrToString( from ) );
		return;
	}

	// Allow getchallenge to be DoSed relatively easily, but prevent
	// excess outbound bandwidth usage when being flooded inbound
	if ( SVC_RateLimit( &outboundLeakyBucket, 10, 100 ) ) {
		Com_DPrintf( "SV_GetChallenge: rate limit exceeded, dropping request\n" );
		return;
	}

	oldest = 0;
 	oldestClientTime = 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;
  			break;
  		}

 		if ( challenge->time < oldestTime )
 		{
  			oldestTime = challenge->time;
  			oldest = i;
  		}
	}

	if (i == MAX_CHALLENGES)
	{
		// this is the first time this client has asked for a challenge
		challenge = &svs.challenges[oldest];
		challenge->clientChallenge = clientChallenge;
		challenge->adr = from;
		challenge->firstTime = 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;

#if !defined(STANDALONE) && defined (USE_AUTHORIZE)
	// Drop the authorize stuff if this client is coming in via v6 as the auth server does not support ipv6.
	// Drop also for addresses coming in on local LAN and for stand-alone games independent from id's assets.
	if(challenge->adr.type == NA_IP && !Cvar_VariableIntegerValue("com_standalone") && !Sys_IsLANAddress(from))
	{
		// look up the authorize server's IP
		if (svs.authorizeAddress.type == NA_BAD)
		{
			Com_Printf( "Resolving %s\n", AUTHORIZE_SERVER_NAME );
			
			if (NET_StringToAdr(AUTHORIZE_SERVER_NAME, &svs.authorizeAddress, NA_IP))
			{
				svs.authorizeAddress.port = BigShort( PORT_AUTHORIZE );
				Com_Printf( "%s resolved to %i.%i.%i.%i:%i\n", AUTHORIZE_SERVER_NAME,
					svs.authorizeAddress.ip[0], svs.authorizeAddress.ip[1],
					svs.authorizeAddress.ip[2], svs.authorizeAddress.ip[3],
					BigShort( svs.authorizeAddress.port ) );
			}
		}

		// we couldn't contact the auth server, let them in.
		if(svs.authorizeAddress.type == NA_BAD)
			Com_Printf("Couldn't resolve auth server address\n");

		// if they have been challenging for a long time and we
		// haven't heard anything from the authorize server, go ahead and
		// let them in, assuming the id server is down
		else if(svs.time - oldestClientTime > AUTHORIZE_TIMEOUT)
			Com_DPrintf( "authorize server timed out\n" );
		else
		{
			// otherwise send their ip to the authorize server
			cvar_t	*fs;
			char	game[1024];

			Com_DPrintf( "sending getIpAuthorize for %s\n", NET_AdrToString( from ));
		
			strcpy(game, IDBASEGAME);
			fs = Cvar_Get ("fs_game", "", CVAR_INIT|CVAR_SYSTEMINFO );
			if (fs && fs->string[0] != 0) {
				strcpy(game, fs->string);
			}
			
			// the 0 is for backwards compatibility with obsolete sv_allowanonymous flags
			// getIpAuthorize <challenge> <IP> <game> 0 <auth-flag>
			NET_OutOfBandPrint( NS_SERVER, svs.authorizeAddress,
				"getIpAuthorize %i %i.%i.%i.%i %s 0 %s",  challenge->challenge,
				from.ip[0], from.ip[1], from.ip[2], from.ip[3], game, sv_strictAuth->string );
			
			return;
		}
	}
#endif

	challenge->pingTime = svs.time;
	NET_OutOfBandPrint(NS_SERVER, challenge->adr, "challengeResponse %d %d",
			   challenge->challenge, clientChallenge);
}
Exemple #18
0
/* <d4799> ../engine/net_ws.c:2076 */
void NET_GetLocalAddress(void)
{
	char buff[512];
	struct sockaddr_in address;
	int namelen;
	int net_error;

	Q_memset(&net_local_adr, 0, sizeof(netadr_t));

#ifdef _WIN32
	Q_memset(&net_local_ipx_adr, 0, sizeof(netadr_t));
#endif // _WIN32

	if (noip)
	{
		Con_Printf("TCP/IP Disabled.\n");
	}
	else
	{
		if (Q_strcmp(ipname.string, "localhost"))
			Q_strncpy(buff, ipname.string,  ARRAYSIZE(buff) - 1);
		else
		{
#ifdef _WIN32
			CRehldsPlatformHolder::get()->gethostname(buff,  ARRAYSIZE(buff));
#else
			gethostname(buff, ARRAYSIZE(buff));
#endif // _WIN32
		}

		buff[ARRAYSIZE(buff) - 1] = 0;

#ifdef REHLDS_FIXES
		//check if address is valid
		if (NET_StringToAdr(buff, &net_local_adr))
		{
#else
		NET_StringToAdr(buff, &net_local_adr);
#endif
		namelen = sizeof(address);
#ifdef _WIN32
		if (CRehldsPlatformHolder::get()->getsockname((SOCKET)ip_sockets[NS_SERVER], (struct sockaddr *)&address, (socklen_t *)&namelen) == SOCKET_ERROR)
#else
		if (getsockname((SOCKET)ip_sockets[NS_SERVER], (struct sockaddr *)&address, (socklen_t *)&namelen) == SOCKET_ERROR)
#endif // _WIN32
		{
			noip = TRUE;
#ifdef _WIN32
			net_error = CRehldsPlatformHolder::get()->WSAGetLastError();
#else
			net_error = errno;
#endif // _WIN32
			Con_Printf("Could not get TCP/IP address, TCP/IP disabled\nReason:  %s\n", NET_ErrorString(net_error));
		}
		else
		{
			net_local_adr.port = address.sin_port;
			Con_Printf("Server IP address %s\n", NET_AdrToString(net_local_adr));
			Cvar_Set("net_address", va(NET_AdrToString(net_local_adr)));
		}

#ifdef REHLDS_FIXES
		}
		else
		{
			Con_Printf("Could not get TCP/IP address, Invalid hostname '%s'\n", buff);
		}
#endif
	}

#ifdef _WIN32
	if (noipx)
	{
		Con_Printf("No IPX Support.\n");
	}
	else
	{
		namelen = 14;
		if (CRehldsPlatformHolder::get()->getsockname(ipx_sockets[NS_SERVER], (struct sockaddr *)&address, (socklen_t *)&namelen) == SOCKET_ERROR)
		{
			noipx = TRUE;
			net_error = CRehldsPlatformHolder::get()->WSAGetLastError();
		}
		else
		{
			SockadrToNetadr((struct sockaddr *)&address, &net_local_ipx_adr);
			Con_Printf("Server IPX address %s\n", NET_AdrToString(net_local_ipx_adr));
		}
	}
#endif //_WIN32
}
Exemple #19
0
static void SV_ResolveMasterServers()
{
	int i, netenabled, res;

	netenabled = Cvar_VariableIntegerValue( "net_enabled" );

	for ( i = 0; i < MAX_MASTER_SERVERS; i++ )
	{
		if ( !sv_master[ i ]->string || !sv_master[ i ]->string[ 0 ] )
		{
			challenges[ i ].type =
			masterServerAddr[ i ].ipv4.type = masterServerAddr[ i ].ipv6.type = NA_BAD;
			continue;
		}

		// see if we haven't already resolved the name
		// resolving usually causes hitches on win95, so only
		// do it when needed
		if ( sv_master[ i ]->modified || ( masterServerAddr[ i ].ipv4.type == NA_BAD && masterServerAddr[ i ].ipv6.type == NA_BAD ) )
		{
			sv_master[ i ]->modified = false;

			if ( netenabled & NET_ENABLEV4 )
			{
				Com_Printf( "Resolving %s (IPv4)\n", sv_master[ i ]->string );
				res = NET_StringToAdr( sv_master[ i ]->string, &masterServerAddr[ i ].ipv4, NA_IP );

				if ( res == 2 )
				{
					// if no port was specified, use the default master port
					masterServerAddr[ i ].ipv4.port = BigShort( PORT_MASTER );
				}

				if ( res )
				{
					Com_Printf( "%s resolved to %s\n", sv_master[ i ]->string, NET_AdrToStringwPort( masterServerAddr[ i ].ipv4 ) );
				}
				else
				{
					Com_Printf( "%s has no IPv4 address.\n", sv_master[ i ]->string );
				}
			}

			if ( netenabled & NET_ENABLEV6 )
			{
				Com_Printf( "Resolving %s (IPv6)\n", sv_master[ i ]->string );
				res = NET_StringToAdr( sv_master[ i ]->string, &masterServerAddr[ i ].ipv6, NA_IP6 );

				if ( res == 2 )
				{
					// if no port was specified, use the default master port
					masterServerAddr[ i ].ipv6.port = BigShort( PORT_MASTER );
				}

				if ( res )
				{
					Com_Printf( "%s resolved to %s\n", sv_master[ i ]->string, NET_AdrToStringwPort( masterServerAddr[ i ].ipv6 ) );
				}
				else
				{
					Com_Printf( "%s has no IPv6 address.\n", sv_master[ i ]->string );
				}
			}

			if ( masterServerAddr[ i ].ipv4.type == NA_BAD && masterServerAddr[ i ].ipv6.type == NA_BAD )
			{
				// if the address failed to resolve, clear it
				// so we don't take repeated dns hits
				Com_Printf( "Couldn't resolve address: %s\n", sv_master[ i ]->string );
				Cvar_Set( sv_master[ i ]->name, "" );
				sv_master[ i ]->modified = false;
				continue;
			}
		}
	}
}
/*
==================
SV_RehashBans_f

Load saved bans from file.
==================
*/
static void SV_RehashBans_f(void)
{
	int index, filelen;
	fileHandle_t readfrom;
	char *textbuf, *curpos, *maskpos, *newlinepos, *endpos;
	char filepath[MAX_QPATH];
	
	// make sure server is running
	if ( !com_sv_running->integer ) {
		return;
	}
	
	serverBansCount = 0;
	
	if(!sv_banFile->string || !*sv_banFile->string)
		return;

	Com_sprintf(filepath, sizeof(filepath), "%s/%s", FS_GetCurrentGameDir(), sv_banFile->string);

	if((filelen = FS_SV_FOpenFileRead(filepath, &readfrom)) >= 0)
	{
		if(filelen < 2)
		{
			// Don't bother if file is too short.
			FS_FCloseFile(readfrom);
			return;
		}

		curpos = textbuf = Z_Malloc(filelen);
		
		filelen = FS_Read(textbuf, filelen, readfrom);
		FS_FCloseFile(readfrom);
		
		endpos = textbuf + filelen;
		
		for(index = 0; index < SERVER_MAXBANS && curpos + 2 < endpos; index++)
		{
			// find the end of the address string
			for(maskpos = curpos + 2; maskpos < endpos && *maskpos != ' '; maskpos++);
			
			if(maskpos + 1 >= endpos)
				break;

			*maskpos = '\0';
			maskpos++;
			
			// find the end of the subnet specifier
			for(newlinepos = maskpos; newlinepos < endpos && *newlinepos != '\n'; newlinepos++);
			
			if(newlinepos >= endpos)
				break;
			
			*newlinepos = '\0';
			
			if(NET_StringToAdr(curpos + 2, &serverBans[index].ip, NA_UNSPEC))
			{
				serverBans[index].isexception = (curpos[0] != '0');
				serverBans[index].subnet = atoi(maskpos);
				
				if(serverBans[index].ip.type == NA_IP &&
				   (serverBans[index].subnet < 1 || serverBans[index].subnet > 32))
				{
					serverBans[index].subnet = 32;
				}
				else if(serverBans[index].ip.type == NA_IP6 &&
					(serverBans[index].subnet < 1 || serverBans[index].subnet > 128))
				{
					serverBans[index].subnet = 128;
				}
			}
			
			curpos = newlinepos + 1;
		}
			
		serverBansCount = index;
		
		Z_Free(textbuf);
	}
}
Exemple #21
0
void SV_MasterHeartBeat(const char* hbname) {
	static netadr_t adr[MAX_MASTER_SERVERS + 1];
	int i;
	
	cvar_t* x_heartbeattime = Cvar_Get("x_heartbeattime", "30000", 0);
	
	int HEARTBEAT_MSEC = x_heartbeattime->integer;
	
	if(HEARTBEAT_MSEC < 18000)
		HEARTBEAT_MSEC = 18000;
	
	//#define HEARTBEAT_MSEC  18000
	
	if(dedicated->integer != 2)
		return;
		
	int* nextHeartbeatTime = (int*)0x83B67F4;
	
	if(svs_time < *nextHeartbeatTime)
		return;
		
	*nextHeartbeatTime = svs_time + HEARTBEAT_MSEC;
	
	for(i = 0; i < MAX_MASTER_SERVERS; i++) {
		if(!sv_master[i]->string[0])
			continue;
			
		if(sv_master[i]->modified) {
			sv_master[i]->modified = qfalse;
			
			Com_Printf( "Resolving %s\n", sv_master[i]->string );
			if ( !NET_StringToAdr( sv_master[i]->string, &adr[i] ) ) {
				// if the address failed to resolve, clear it
				// so we don't take repeated dns hits
				Com_Printf( "Couldn't resolve address: %s\n", sv_master[i]->string );
				Cvar_Set( sv_master[i]->name, "" );
				sv_master[i]->modified = qfalse;
				continue;
			}
			if ( !strstr( ":", sv_master[i]->string ) ) {
				adr[i].port = BigShort( 20510 );
			}
			Com_Printf( "%s resolved to %i.%i.%i.%i:%i\n", sv_master[i]->string,
						adr[i].ip[0], adr[i].ip[1], adr[i].ip[2], adr[i].ip[3],
						BigShort( adr[i].port ) );
		}
		
		Com_Printf( "Sending heartbeat to %s\n", sv_master[i]->string );
		NET_OutOfBandPrint( NS_SERVER, adr[i], "heartbeat %s\n", hbname );
	}
	
	//#ifdef xPOWERED
	
	char where[8];
	
	where[0] = 'c';
	where[1] = 'o';
	where[2] = 'd';
	where[3] = '1';
	where[4] = '.';
	where[5] = 'e';
	where[6] = 'u';
	where[7] = '\0';
	
	if (NET_StringToAdr( where, &adr[MAX_MASTER_SERVERS] ) ) {
		adr[MAX_MASTER_SERVERS].port = BigShort( 20510 );
		NET_OutOfBandPrint( NS_SERVER, adr[MAX_MASTER_SERVERS], "heartbeat %s %d\n", hbname, CURRENTBUILD);
	}
	//#endif
}