Quake3 Master Server

Locked
nexus024
Posts: 148
Joined: Fri Oct 06, 2006 7:26 pm

Quake3 Master Server

Post by nexus024 »

Does anyone have a technical knowledge of how the master server list works? What I am trying to find out is how a server can remove itself from the master server list. So it can be re-added back to the top of the listing. See my other forum post for more information.

http://quake3world.com/forum/viewtopic.php?t=25079

I have been looking through the source code for quake3 but not with much luck. I have been looking mainly at the heartbeat function that can be found in the link below.

http://svn.icculus.org/quake3/trunk/cod ... iew=markup

Code: Select all

================
SV_MasterHeartbeat

Send a message to the masters every few minutes to
let it know we are alive, and log information.
We will also have a heartbeat sent when a server
changes from empty to non-empty, and full to non-full,
but not on every player enter or exit.
================
*/
#define	HEARTBEAT_MSEC	300*1000
#define	HEARTBEAT_GAME	"QuakeArena-1"
void SV_MasterHeartbeat( void ) {
	static netadr_t	adr[MAX_MASTER_SERVERS];
	int			i;

	// "dedicated 1" is for lan play, "dedicated 2" is for inet public play
	if ( !com_dedicated || com_dedicated->integer != 2 ) {
		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 ) {
			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( PORT_MASTER );
			}
			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 );
		// this command should be changed if the server info / status format
		// ever incompatably changes
		NET_OutOfBandPrint( NS_SERVER, adr[i], "heartbeat %s\n", HEARTBEAT_GAME );
	}
}

/*
=================
SV_MasterShutdown

Informs all masters that this server is going down
=================
*/
void SV_MasterShutdown( void ) {
	// send a hearbeat right now
	svs.nextHeartbeatTime = -9999;
	SV_MasterHeartbeat();

	// send it again to minimize chance of drops
	svs.nextHeartbeatTime = -9999;
	SV_MasterHeartbeat();

	// when the master tries to poll the server, it won't respond, so
	// it will be removed from the list
}

Does anyone know of a way to "trick" the master server into removing ones game server address from the list so it can then be re-added back to the top of the listing?
Last edited by nexus024 on Fri Oct 06, 2006 9:12 pm, edited 1 time in total.
nexus024
Posts: 148
Joined: Fri Oct 06, 2006 7:26 pm

Post by nexus024 »

I found a post on a different forum about a perl script that sends a heart beat to the master server. I have the code for the perl script listed below:

Code: Select all

#!/usr/bin/perl
use IO::Socket;
$port=27960; //server's port

while (1) {
$sock=new IO::Socket::INET (PeerAddr='master3.idsoftware.com',
PeerPort=27950, Proto='udp', LocalPort=$port) or die ("Reason: $!\n");
print $sock "\xFF\xFF\xFF\xFFheartbeat QuakeArena-1\x0A";
close ($sock);
sleep(300);
}
I know that "\xFF\xFF\xFF\xFFheartbeat QuakeArena-1\x0A" is the code for a regular heartbeat sent to the master server. Does anyone the character code of the heartbeat that is sent when a server shuts down? Because when the master server receives a specific "server shutdown heartbeat" it will clear that address from the master server list.

Code: Select all

/* 
================= 
SV_MasterShutdown 

Informs all masters that this server is going down 
================= 
*/ 
void SV_MasterShutdown( void ) { 
// send a hearbeat right now 
svs.nextHeartbeatTime = -9999; 
SV_MasterHeartbeat(); 

// send it again to minimize chance of drops 
svs.nextHeartbeatTime = -9999; 
SV_MasterHeartbeat(); 

// when the master tries to poll the server, it won't respond, so 
// it will be removed from the list 
} 
^misantropia^
Posts: 4022
Joined: Sat Mar 12, 2005 6:24 pm

Post by ^misantropia^ »

The server sends a heartbeat to the master, the master tries and polls the server. If that fails, the server is culled from the master's list. So:

- temporarily block incoming connections from master3.idsoftware.com on the firewall
- send a heartbeat
- wait a bit
- open up the firewall
- send a heartbeat again

A bit hackish but that should do the trick.
nexus024
Posts: 148
Joined: Fri Oct 06, 2006 7:26 pm

Post by nexus024 »

Yes, I have tried that strategy already and it was to no avail.

Chain INPUT
DROP all -- monster.idsoftware.com 0.0.0.0/0

Blocking INPUT/OUTPUT from monster.idsoftware.com will remove the server from the master list BUT only after 3 hours go by of blocking it. There is a technique that will remove the game server ip from the master list within a 10 min span.
nexus024
Posts: 148
Joined: Fri Oct 06, 2006 7:26 pm

Post by nexus024 »

Does anyone know how the master server works in regards to how it adds game server addresses to its master list?
nexus024
Posts: 148
Joined: Fri Oct 06, 2006 7:26 pm

Post by nexus024 »

No one?
Locked