static void CL_SetServerInfoByAddress(netadr_t from, const char *info, int ping) {
	int i;

	for (i = 0; i < MAX_OTHER_SERVERS; i++) {
		if (NET_CompareAdr(from, cls.localServers[i].adr)) {
			CL_SetServerInfo(&cls.localServers[i], info, ping);
		}
	}

	for (i = 0; i < MAX_OTHER_SERVERS; i++) {
		if (NET_CompareAdr(from, cls.mplayerServers[i].adr)) {
			CL_SetServerInfo(&cls.mplayerServers[i], info, ping);
		}
	}

	for (i = 0; i < MAX_GLOBAL_SERVERS; i++) {
		if (NET_CompareAdr(from, cls.globalServers[i].adr)) {
			CL_SetServerInfo(&cls.globalServers[i], info, ping);
		}
	}

	for (i = 0; i < MAX_OTHER_SERVERS; i++) {
		if (NET_CompareAdr(from, cls.favoriteServers[i].adr)) {
			CL_SetServerInfo(&cls.favoriteServers[i], info, ping);
		}
	}

}
Exemple #2
0
int LAN_AddFavAddr( const char *address ) {
	if ( cls.numfavoriteservers < MAX_OTHER_SERVERS ) {
		netadr_t adr;
		if ( !NET_StringToAdr( address, &adr ) ) {
			return 2;
		}
		if ( adr.type == NA_BAD ) {
			return 3;
		}

		for ( int i = 0; i < cls.numfavoriteservers; i++ ) {
			if ( NET_CompareAdr( cls.favoriteServers[i].adr, adr ) ) {
				return 0;
			}
		}
		cls.favoriteServers[cls.numfavoriteservers].adr = adr;
		Q_strncpyz( cls.favoriteServers[cls.numfavoriteservers].hostName, address,
			sizeof(cls.favoriteServers[cls.numfavoriteservers].hostName) );
		cls.favoriteServers[cls.numfavoriteservers].visible = qtrue;
		cls.numfavoriteservers++;
		return 1;
	}

	return -1;
}
void Master_AddServer(netadr_t *adr) {

   master_server_t *ptr;


   Master_Init();
   ptr = masterlist;

   //Is it already listed?
   while(ptr != NULL) {
      if(NET_CompareAdr(ptr->address, *adr) != 0) {
         return;
      }
      ptr = ptr->next;
   }

   //Not found, make a new entry.
   ptr = (master_server_t *)Q_Malloc(sizeof(master_server_t));
   if(ptr == NULL) { //malloc failure.  Just back away and let some other function handle it...
      return;
   }

   ptr->address = *adr;
   ptr->last_heartbeat = -15;
   ptr->next = masterlist;
   masterlist = ptr;
}
Exemple #4
0
/*
=======================
LAN_ServerIsInFavoriteList
=======================
*/
qboolean LAN_ServerIsInFavoriteList( int source, int n ) {
	int i;
	serverInfo_t *server = NULL;

	switch ( source ) {
	case AS_LOCAL:
		if ( n >= 0 && n < MAX_OTHER_SERVERS ) {
			server = &cls.localServers[n];
		}
		break;
	case AS_GLOBAL:
		if ( n >= 0 && n < MAX_GLOBAL_SERVERS ) {
			server = &cls.globalServers[n];
		}
		break;
	case AS_FAVORITES:
		if ( n >= 0 && n < MAX_OTHER_SERVERS ) {
			return qtrue;
		}
		break;
	}

	if ( !server ) {
		return qfalse;
	}

	for ( i = 0; i < cls.numfavoriteservers; i++ ) {
		if ( NET_CompareAdr( cls.favoriteServers[i].adr, server->adr ) ) {
			return qtrue;
		}
	}

	return qfalse;
}
Exemple #5
0
bool operator==(const netadr_t &a, const netadr_t &b) {
	if (a.type != b.type) {
		return false;
	}

	return NET_CompareAdr(&a, &b);
}
Exemple #6
0
/*
====================
LAN_RemoveServer
====================
*/
static void LAN_RemoveServer(int source, const char *addr) {
	int *count, i;
	serverInfo_t *servers = NULL;
	count = NULL;
	switch (source) {
		case AS_LOCAL :
			count = &cls.numlocalservers;
			servers = &cls.localServers[0];
			break;
		case AS_MPLAYER:
		case AS_GLOBAL :
			count = &cls.numglobalservers;
			servers = &cls.globalServers[0];
			break;
		case AS_FAVORITES :
			count = &cls.numfavoriteservers;
			servers = &cls.favoriteServers[0];
			break;
	}
	if (servers) {
		netadr_t comp;
		NET_StringToAdr( addr, &comp );
		for (i = 0; i < *count; i++) {
			if (NET_CompareAdr( comp, servers[i].adr)) {
				int j = i;
				while (j < *count - 1) {
					Com_Memcpy(&servers[j], &servers[j+1], sizeof(servers[j]));
					j++;
				}
				(*count)--;
				break;
			}
		}
	}
}
Exemple #7
0
/*
===================
CL_UpdateInfoPacket
===================
*/
void CL_UpdateInfoPacket(netadr_t from)
{
	if (autoupdate.autoupdateServer.type == NA_BAD)
	{
		Com_DPrintf("CL_UpdateInfoPacket: Update server has bad address\n");
		return;
	}

	Com_DPrintf("Update server resolved to %s\n",
	            NET_AdrToString(autoupdate.autoupdateServer));

	if (!NET_CompareAdr(from, autoupdate.autoupdateServer))
	{
		// TODO: when the updater is server-side as well, write this message to the Attack log
		Com_DPrintf("CL_UpdateInfoPacket: Ignoring packet from %s, because the update server is located at %s\n",
		            NET_AdrToString(from), NET_AdrToString(autoupdate.autoupdateServer));
		return;
	}

	Cvar_Set("com_updateavailable", Cmd_Argv(1));

	if (!Q_stricmp(com_updateavailable->string, "1"))
	{
		Cvar_Set("com_updatefiles", Cmd_Argv(2));
#ifdef FEATURE_AUTOUPDATE
		VM_Call(uivm, UI_SET_ACTIVE_MENU, UIMENU_WM_AUTOUPDATE);
#endif /* FEATURE_AUTOUPDATE */
	}
}
static void CL_SetServerInfoByAddress(netadr_t from, const char *info, int ping) {
	int i;

	int count;
	serverInfo_t *server = NULL;

	switch (cls.pingUpdateSource)
	{
	case 0:
		server = &cls.historyServers[0];
		count = cls.numhistoryservers;
		break;
	case 1:
		server = &cls.globalServers[0];
		count = cls.numglobalservers;
		break;
	case 2:
		server = &cls.favoriteServers[0];
		count = cls.numfavoriteservers;
		break;
	}

	for (i = 0; i < count; i++) {
		if (NET_CompareAdr(from, server[i].adr)) {
			CL_SetServerInfo(&server[i], info, ping);
		}
	}
}
Exemple #9
0
//===========================================================================
// GameConsoleCommand
//===========================================================================
void PR2_GameConsoleCommand(void)
{
	int     old_other, old_self;
	client_t	*cl;
	int			i;

	if( sv_vm )
	{
		old_self = pr_global_struct->self;
		old_other = pr_global_struct->other;
		pr_global_struct->other = 0; //sv_cmd = SV_CMD_CONSOLE;
		pr_global_struct->self = 0;

		for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++)
		{
			if (!cl->state)
				continue;
			if ( cl->isBot )
				continue;

			if (NET_CompareAdr(cl->netchan.remote_address, net_from))
			{
				pr_global_struct->self = EDICT_TO_PROG(cl->edict);
				break;
			}
		}
		VM_Call(sv_vm, GAME_CONSOLE_COMMAND, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
		pr_global_struct->self = old_self;
		pr_global_struct->other = old_other;
	}
}
Exemple #10
0
/*
===================
CL_GetServerStatus
===================
*/
serverStatus_t *CL_GetServerStatus( netadr_t from ) {
	serverStatus_t *serverStatus;
	int i, oldest, oldestTime;

	serverStatus = NULL;
	for (i = 0; i < MAX_SERVERSTATUSREQUESTS; i++) {
		if ( NET_CompareAdr( from, cl_serverStatusList[i].address ) ) {
			return &cl_serverStatusList[i];
		}
	}
	for (i = 0; i < MAX_SERVERSTATUSREQUESTS; i++) {
		if ( cl_serverStatusList[i].retrieved ) {
			return &cl_serverStatusList[i];
		}
	}
	oldest = -1;
	oldestTime = 0;
	for (i = 0; i < MAX_SERVERSTATUSREQUESTS; i++) {
		if (oldest == -1 || cl_serverStatusList[i].startTime < oldestTime) {
			oldest = i;
			oldestTime = cl_serverStatusList[i].startTime;
		}
	}
	if (oldest != -1) {
		return &cl_serverStatusList[oldest];
	}
	serverStatusCount++;
	return &cl_serverStatusList[serverStatusCount & (MAX_SERVERSTATUSREQUESTS-1)];
}
Exemple #11
0
/*
=================
CL_PacketEvent

A packet has arrived from the main event loop
=================
*/
void CL_PacketEvent( netadr_t from, msg_t *msg ) {
	clc.lastPacketTime = cls.realtime;

	if ( msg->cursize >= 4 && *(int *)msg->data == -1 ) {
		CL_ConnectionlessPacket( from, msg );
		return;
	}

	if ( cls.state < CA_CONNECTED ) {
		return;		// can't be a valid sequenced packet
	}

	if ( msg->cursize < 8 ) {
		Com_Printf ("%s: Runt packet\n",NET_AdrToString( from ));
		return;
	}

	//
	// packet from server
	//
	if ( !NET_CompareAdr( from, clc.netchan.remoteAddress ) ) {
		Com_DPrintf ("%s:sequenced packet without connection\n"
			,NET_AdrToString( from ) );
		// FIXME: send a client disconnect?
		return;
	}

	if (!Netchan_Process( &clc.netchan, msg) ) {
		return;		// out of order, duplicated, etc
	}

	clc.lastPacketTime = cls.realtime;
	CL_ParseServerMessage( msg );
}
Exemple #12
0
void OnPacketTV()
{
	if(NET_CompareAdr(net_from, net_server))
	{
		buf_t out = net_message;
		// if this is a server connect message, keep a copy for other clients
		int t = net_message.ReadLong();
		if(t == CHALLENGE)
		{
			std::cout << "first client connected" << std::endl;
			challenge_message = net_message;
		}
		else if(t == 0)
		{
			first_message = net_message;
			buf_t tmp;
			tr.Go(net_message, tmp);
		}
		else
		{
			out.clear();
			out.WriteLong(t);
			tr.Go(net_message, out);
		}
		// replicate server packet to all connected clients
		for(int i = 0; i < spectators.size(); i++)
		{
			NET_SendPacket(out.cursize, out.data, spectators[i]);
		}
	}
	else
	{
		// is this an existing client?
		for(int i = 0; i < spectators.size(); i++)
		{
			if(NET_CompareAdr(net_from, spectators[i]))
			{
				OnClientTV(i);
				return;
			}
		}

		// must be a new client
		OnNewClientTV();
	}
}
Exemple #13
0
/*
=================
CL_ReadNetMessage
=================
*/
void CL_ReadNetMessage( void )
{
	size_t	curSize;

	while( CL_GetMessage( net_message_buffer, &curSize ))
	{
		BF_Init( &net_message, "ServerData", net_message_buffer, curSize );

		// check for connectionless packet (0xffffffff) first
		if( BF_GetMaxBytes( &net_message ) >= 4 && *(int *)net_message.pData == -1 )
		{
			CL_ConnectionlessPacket( net_from, &net_message );
			continue;
		}

		// can't be a valid sequenced packet	
		if( cls.state < ca_connected ) continue;

		if( BF_GetMaxBytes( &net_message ) < 8 )
		{
			MsgDev( D_WARN, "%s: runt packet\n", NET_AdrToString( net_from ));
			continue;
		}

		// packet from server
		if( !cls.demoplayback && !NET_CompareAdr( net_from, cls.netchan.remote_address ))
		{
			MsgDev( D_ERROR, "CL_ReadPackets: %s:sequenced packet without connection\n", NET_AdrToString( net_from ));
			continue;
		}

		if( !cls.demoplayback && !Netchan_Process( &cls.netchan, &net_message ))
			continue;	// wasn't accepted for some reason

		CL_ParseServerMessage( &net_message );
	}

	// check for fragmentation/reassembly related packets.
	if( cls.state != ca_disconnected && Netchan_IncomingReady( &cls.netchan ))
	{
		// the header is different lengths for reliable and unreliable messages
		int headerBytes = BF_GetNumBytesRead( &net_message );

		// process the incoming buffer(s)
		if( Netchan_CopyNormalFragments( &cls.netchan, &net_message ))
		{
			CL_ParseServerMessage( &net_message );
		}
		
		if( Netchan_CopyFileFragments( &cls.netchan, &net_message ))
		{
			// remove from resource request stuff.
			CL_ProcessFile( true, cls.netchan.incomingfilename );
		}
	}

	Netchan_UpdateProgress( &cls.netchan );
}
void CL_ServerInfoPacket( netadr_t from, msg_t *msg )
{
	int		i, type;
	//->char	info[1024];
	char*	str;
	char	*infoString;
	//->int		prot;

	infoString = MSG_ReadString( msg );
	//infoString = msg->data;

	// if this isn't the correct protocol version, ignore it
	/*prot = atoi( Info_ValueForKey( infoString, "protocol" ) );
	if ( prot != 144 ) {
		Com_DPrintf( "Different protocol info packet: %s\n", infoString );
		return;
	}*/

	const char* challenge = Info_ValueForKey(infoString, "challenge");
	if (challenge && !_strnicmp("_join", challenge, 5))
	{
		CL_JoinResponse(from, infoString);
	}

	// iterate servers waiting for ping response
	for (i=0; i<MAX_PINGREQUESTS; i++)
	{
		if ( cl_pinglist[i].adr.port && !cl_pinglist[i].time && NET_CompareAdr( from, cl_pinglist[i].adr ) )
		{
			// calc ping time
			cl_pinglist[i].time = timeGetTime() - cl_pinglist[i].start + 1;
			//Com_Printf( 0, "ping time %dms from %s\n", cl_pinglist[i].time, NET_AdrToString( from ) );

			// save of info
			strncpy( cl_pinglist[i].info, infoString, sizeof( cl_pinglist[i].info ) );

			// tack on the net type
			// NOTE: make sure these types are in sync with the netnames strings in the UI
			switch (from.type)
			{
			case NA_BROADCAST:
			case NA_IP:
				str = "udp";
				type = 1;
				break;

			default:
				str = "???";
				type = 0;
				break;
			}
			Info_SetValueForKey( cl_pinglist[i].info, "nettype", va("%d", type) );
			CL_SetServerInfoByAddress(from, infoString, cl_pinglist[i].time);

			return;
		}
	}
}
Exemple #15
0
/*
===================
CL_ServerStatus
===================
*/
int CL_ServerStatus( char *serverAddress, char *serverStatusString, int maxLen ) {
	int i;
	netadr_t	to;
	serverStatus_t *serverStatus;

	// if no server address then reset all server status requests
	if ( !serverAddress ) {
		for (i = 0; i < MAX_SERVERSTATUSREQUESTS; i++) {
			cl_serverStatusList[i].address.port = 0;
			cl_serverStatusList[i].retrieved = qtrue;
		}
		return qfalse;
	}
	// get the address
	if ( !NET_StringToAdr( serverAddress, &to ) ) {
		return qfalse;
	}
	serverStatus = CL_GetServerStatus( to );
	// if no server status string then reset the server status request for this address
	if ( !serverStatusString ) {
		serverStatus->retrieved = qtrue;
		return qfalse;
	}

	// if this server status request has the same address
	if ( NET_CompareAdr( to, serverStatus->address) ) {
		// if we recieved an response for this server status request
		if (!serverStatus->pending) {
			Q_strncpyz(serverStatusString, serverStatus->string, maxLen);
			serverStatus->retrieved = qtrue;
			serverStatus->startTime = 0;
			return qtrue;
		}
		// resend the request regularly
		else if ( serverStatus->startTime < Com_Milliseconds() - cl_serverStatusResendTime->integer ) {
			serverStatus->print = qfalse;
			serverStatus->pending = qtrue;
			serverStatus->retrieved = qfalse;
			serverStatus->time = 0;
			serverStatus->startTime = Com_Milliseconds();
			NET_OutOfBandPrint( NS_CLIENT, to, "getstatus" );
			return qfalse;
		}
	}
	// if retrieved
	else if ( serverStatus->retrieved ) {
		serverStatus->address = to;
		serverStatus->print = qfalse;
		serverStatus->pending = qtrue;
		serverStatus->retrieved = qfalse;
		serverStatus->startTime = Com_Milliseconds();
		serverStatus->time = 0;
		NET_OutOfBandPrint( NS_CLIENT, to, "getstatus" );
		return qfalse;
	}
	return qfalse;
}
Exemple #16
0
qbool NET_SendTCPPacket_SV (netsrc_t netsrc, int length, void *data, netadr_t to)
{
	svtcpstream_t *st;

	if (netsrc != NS_SERVER)
		return false;

	for (st = svs.tcpstreams; st; st = st->next)
	{
		if (st->socketnum == INVALID_SOCKET)
			continue;

		if (NET_CompareAdr(to, st->remoteaddr))
		{
			int sent;
			unsigned short slen = BigShort((unsigned short)length);

			if (st->outlen + length + sizeof(slen) >= sizeof(st->outbuffer))
			{
				// not enough space, we overflowed
				break; // well, quake should resist to some packet lost.. so we just drop that packet.
			}

			// put data in buffer
			memmove(st->outbuffer + st->outlen, (char*)&slen, sizeof(slen));
			st->outlen += sizeof(slen);
			memmove(st->outbuffer + st->outlen, data, length);
			st->outlen += length;

			sent = send(st->socketnum, st->outbuffer, st->outlen, 0);

			if (sent == 0)
			{
				// think it's OK
			}
			else if (sent > 0) //we put some data through
			{ //move up the buffer
				st->outlen -= sent;
				memmove(st->outbuffer, st->outbuffer + sent, st->outlen);
			}
			else
			{ //error of some kind. would block or something
				if (qerrno != EWOULDBLOCK && qerrno != EAGAIN)
				{
					st->drop = true; // something cricial, drop than
				}
			}

			break;
		}
	}

	// 'st' will be not zero, if we found 'to' in 'svs.tcpstreams'.
	// That does not mean we actualy send packet, since there case of overflow, but who cares,
	// all is matter that we found such 'to' and tried to send packet.
	return !!st;
}
/*
=================
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;
	}*/

	// 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;
	}
}
/*
=====================
SV_DropClient

Called when the player is totally leaving the server, either willingly
or unwillingly.  This is NOT called if the entire server is quiting
or crashing -- SV_FinalMessage() will handle that
=====================
*/
void SV_DropClient( client_t *drop, const char *reason ) {
	int		i;
	challenge_t	*challenge;

	if ( drop->state == CS_ZOMBIE ) {
		return;		// already dropped
	}

	// see if we already have a challenge for this ip
	challenge = &svs.challenges[0];

	for (i = 0 ; i < MAX_CHALLENGES ; i++, challenge++) {
		if ( NET_CompareAdr( drop->netchan.remoteAddress, challenge->adr ) ) {
			challenge->connected = qfalse;
			break;
		}
	}

	// Kill any download
	SV_CloseDownload( drop );

	// tell everyone why they got dropped
	SV_SendServerCommand( NULL, "print \"%s" S_COLOR_WHITE " %s\n\"", drop->name, reason );


	if (drop->download)	{
		FS_FCloseFile( drop->download );
		drop->download = 0;
	}

	// call the prog function for removing a client
	// this will remove the body, among other things
	VM_Call( gvm, GAME_CLIENT_DISCONNECT, drop - svs.clients );

	// add the disconnect command
	SV_SendServerCommand( drop, "disconnect \"%s\"", reason);

	// nuke user info
	SV_SetUserinfo( drop - svs.clients, "" );
	
	Com_DPrintf( "Going to CS_ZOMBIE for %s\n", drop->name );
	drop->state = CS_ZOMBIE;		// become free in a few seconds

	// if this was the last client on the server, send a heartbeat
	// to the master so it is known the server is empty
	// send a heartbeat now so the master will get up to date info
	// if there is already a slot for this ip, reuse it
	for (i=0 ; i < sv_maxclients->integer ; i++ ) {
		if ( svs.clients[i].state >= CS_CONNECTED ) {
			break;
		}
	}
	if ( i == sv_maxclients->integer ) {
		SV_Heartbeat_f();
	}
}
/*
=================
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/openjk: 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.
=================
*/
void SV_GetChallenge( netadr_t from ) {
	int		i;
	int		oldest;
	int		oldestTime;
	int		clientChallenge;
	challenge_t	*challenge;

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

	oldest = 0;
	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))
		{
			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->adr = from;
		challenge->firstTime = svs.time;
		challenge->time = svs.time;
		challenge->connected = qfalse;
	}

	// always generate a new challenge number, so the client cannot circumvent sv_maxping
	challenge->challenge = ( (rand() << 16) ^ rand() ) ^ svs.time;
	challenge->wasrefused = qfalse;

	challenge->pingTime = svs.time;
	NET_OutOfBandPrint( NS_SERVER, challenge->adr, "challengeResponse %i %i", challenge->challenge, clientChallenge );
}
Exemple #20
0
void SV_BanProcess(client_t* cl, int type, const char* reason) {
	const char* file = (type == IPBAN) ? "ipbans.txt" : "guidbans.txt";
	FILE* f = fopen(file, "a");
	
	if(!f) {
		Com_Printf("Could not open '%s'.\n", file);
		return;
	}
	
	challenge_t* challenge;
	char ip[16];
    sprintf(ip, "%d.%d.%d.%d", cl->remoteAddress.ip[0], cl->remoteAddress.ip[1], cl->remoteAddress.ip[2], cl->remoteAddress.ip[3]);
	int guid = 0;
	
	challenge = &challenges[0];
	for (int j = 0 ; j < MAX_CHALLENGES ; j++, challenge++ ) {
		if (NET_CompareAdr( cl->remoteAddress, challenge->adr ) ) {
			guid = x_challenges[j].guid;
			break;
		}
	}
	
	int k;
	
	aSingleBan* cur = banlist;
	
	while(cur!=NULL) {
		if((cur->guid == guid && guid != 0 && cur->type == GUIDBAN) || (cur->type == IPBAN && NET_CompareBaseAdr(cl->remoteAddress, cur->adr))) {
			Com_Printf("%s has already been banned.\n", cl->name);
			fclose(f);
			return;
		}
		cur=cur->next;
	}
	
	if(!guid && type==GUIDBAN) {
		Com_Printf("ERROR: You are trying to ban someone with a GUID of zero.\n");
		return;
	}
	
	aSingleBan* add = bl_push();
	add->type = type;
	
	if(type==IPBAN) {
		add->adr = cl->remoteAddress;
		fprintf(f, "%s\n", ip);
	} else if(type == GUIDBAN) {
		fprintf(f, "%d\n", guid);
		add->guid = guid;
	}
	
	fclose(f);
	
	SV_DropClient(cl, va("Banned: [Reason %s]", reason));
}
Exemple #21
0
/*
====================
LAN_AddServer
====================
*/
static int LAN_AddServer(int source, const char *name, const char *address) {
	int max, *count, i;
	netadr_t adr;
	serverInfo_t *servers = NULL;
	max = MAX_OTHER_SERVERS;
	count = 0;

	switch (source) {
		case AS_LOCAL :
			count = &cls.numlocalservers;
			servers = &cls.localServers[0];
			break;
		case AS_MPLAYER :
			count = &cls.nummplayerservers;
			servers = &cls.mplayerServers[0];
			break;
		case AS_GLOBAL :
			max = MAX_GLOBAL_SERVERS;
			count = &cls.numglobalservers;
			servers = &cls.globalServers[0];
			break;
		case AS_FAVORITES :
			count = &cls.numfavoriteservers;
			servers = &cls.favoriteServers[0];
/*			if (!name || !*name)
			{
				name = "?";
			}
*/
			break;
	}
	if (servers && *count < max) {
		NET_StringToAdr( address, &adr );
		if (adr.type == NA_BAD)
		{
			return -1;
		}
		for ( i = 0; i < *count; i++ ) {
			if (NET_CompareAdr(servers[i].adr, adr)) {
				break;
			}
		}
		if (i >= *count) {
			servers[*count].adr = adr;
			Q_strncpyz(servers[*count].hostName, name, sizeof(servers[*count].hostName));
			servers[*count].visible = qtrue;
			(*count)++;
			return 1;
		}
		return 0;
	}
	return -1;
}
Exemple #22
0
/**
 * @brief LAN_AddServer
 * @param[in] source
 * @param[in] name
 * @param[in] address
 * @return
 */
static int LAN_AddServer(int source, const char *name, const char *address)
{
    int          max = MAX_OTHER_SERVERS, *count = 0;
    netadr_t     adr;
    serverInfo_t *servers = NULL;

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

    if (servers && *count < max)
    {
        int i;

        NET_StringToAdr(address, &adr, NA_UNSPEC);
        for (i = 0; i < *count; i++)
        {
            if (NET_CompareAdr(servers[i].adr, adr))
            {
                break;
            }
        }
        if (i >= *count)
        {
            servers[*count].adr = adr;
            Q_strncpyz(servers[*count].hostName, name, sizeof(servers[*count].hostName));
            servers[*count].visible = qtrue;
            (*count)++;

            if (source == AS_FAVORITES)
            {
                LAN_SaveServersToFile();
            }

            return 1;
        }
        return 0;
    }
    return -1;
}
Exemple #23
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.
=================
*/
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;
	}
	*/
	if (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;
	}
}
Exemple #24
0
/*
==================
SV_TempBanIsBanned
==================
*/
qboolean SV_TempBanIsBanned(netadr_t address)
{
	int i;

	for(i = 0; i < MAX_TEMPBAN_ADDRESSES; i++) {
		if(svs.tempBanAddresses[i].endtime && svs.tempBanAddresses[i].endtime > svs.time) {
			if(NET_CompareAdr(address, svs.tempBanAddresses[i].adr)) {
				return qtrue;
			}
		}
	}

	return qfalse;
}
void SVC_Heartbeat() {

   master_server_t * ptr;

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

      if(NET_CompareAdr(global_net_from, ptr->address) != 0) {

         ptr->ChallengeRequest = MSG_ReadLong();
         Master_RequestHeartbeat(ptr);
         return;
      }
   }
}
Exemple #26
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.
=================
*/
void SV_GetChallenge( netadr_t from ) {
	int		i;
	int		oldest;
	int		oldestTime;
	int		oldestClientTime;
	int		clientChallenge;
	challenge_t	*challenge;
	qboolean wasfound = qfalse;

	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->connected = qfalse;
	}

	// always generate a new challenge number, so the client cannot circumvent sv_maxping
	challenge->challenge = ((rand() << 16) ^ rand()) ^ svs.time;
	challenge->wasrefused = qfalse;
	challenge->time = svs.time;
	challenge->pingTime = svs.time;
	NET_OutOfBandPrint(NS_SERVER, challenge->adr, "challengeResponse %i %i", challenge->challenge, clientChallenge);
}
Exemple #27
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 address.
=================
*/
void SV_GetChallenge( netadr_t from )
{
	int         i;
	int         oldest;
	int         oldestTime;
	challenge_t *challenge;

	oldest = 0;
	oldestTime = 0x7fffffff;

	// see if we already have a challenge for this IP address
	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->firstPing = 0;
		challenge->time = svs.time;
		challenge->connected = false;
		i = oldest;
	}

	challenge->pingTime = svs.time;

	NET_OutOfBandPrint( netsrc_t::NS_SERVER, from, "challengeResponse %i", challenge->challenge );

	return;
}
Exemple #28
0
/*
==================
SV_Incognito_f

Pretend that you disconnect, but really go to spec.
==================
*/
static void SV_Incognito_f(void) {
	client_t	*cl;
	int		i;
	char		cmd[64];

	// Make sure server is running.
	if (!com_sv_running->integer) {
		Com_Printf("Server is not running.\n");
		return;
	}

	if (!in_redirect) {
		Com_Printf("The incognito command can only be run through rcon\n");
		return;
	}

	if (Cmd_Argc() != 1) {
		Com_Printf("No arguments expected for incognito command\n");
		return;
	}

	// Find the person connected to server who issued the incognito command.
	for (i = 0, cl = svs.clients;; i++, cl++) {
		if (i == sv_maxclients->integer) {
			cl = NULL;
			break;
		}
		if (cl->state >= CS_ACTIVE && NET_CompareAdr(cl->netchan.remoteAddress, svs.redirectAddress)) {
			break; // found
		}
	}

	if (cl != NULL) {
		sv.incognitoJoinSpec = qtrue;
		Com_sprintf(cmd, sizeof(cmd), "forceteam %i spectator\n", i);
		Cmd_ExecuteString(cmd);
		sv.incognitoJoinSpec = qfalse;
		SV_SendServerCommand(NULL, "print \"%s" S_COLOR_WHITE " disconnected\n\"", cl->name); // color OK
		Com_sprintf(cmd, sizeof(cmd), "sendclientcommand all cs %i \"\"\n", 548 + i);
		Cmd_ExecuteString(cmd);
	}
	else {
		Com_Printf("Must be connected to server for incognito to work\n");
	}

}
Exemple #29
0
qboolean CL_UpdatePacketEvent(netadr_t from)
{
#ifdef FEATURE_AUTOUPDATE
	static qboolean autoupdateRedirected = qfalse;

	// Update server doesn't understand netchan packets
	if (NET_CompareAdr(autoupdate.autoupdateServer, from)
	    && autoupdate.updateStarted && !autoupdateRedirected)
	{
		autoupdateRedirected = qtrue;
		CL_InitDownloads();
		return qtrue;
	}
#endif /* FEATURE_AUTOUPDATE */

	return qfalse;
}
Exemple #30
0
//
// SV_ValidToken
//
bool SV_IsValidToken(DWORD token)
{
	QWORD now = I_GetTime();

	for(size_t i = 0; i < connect_tokens.size(); i++)
	{
		if(connect_tokens[i].id == token
		&& NET_CompareAdr(connect_tokens[i].from, net_from)
		&& now - connect_tokens[i].issued < MAX_TOKEN_AGE)
		{
			// extend token life and confirm
			connect_tokens[i].issued = now;
			return true;
		}
	}
	
	return false;
}