예제 #1
0
파일: cl_main.c 프로젝트: postfix/quake2vr
/*
=======================
CL_SendConnectPacket

We have gotten a challenge from the server, so try and
connect.
======================
*/
void CL_SendConnectPacket (void)
{
	netadr_t	adr;
	int32_t		port;

	if (!NET_StringToAdr (cls.servername, &adr))
	{
		Com_Printf ("Bad server address\n");
		cls.connect_time = 0;
		return;
	}
	if (adr.port == 0)
		adr.port = BigShort (PORT_SERVER);

	port = Cvar_VariableValue ("qport");
	userinfo_modified = false;

	// if in compatibility mode, lie to server about this
	// client's protocol, but exclude localhost for this.
	if (cl_servertrick->value && strcmp(cls.servername, "localhost"))
		Netchan_OutOfBandPrint (NS_CLIENT, adr, "connect %i %i %i \"%s\"\n",
			OLD_PROTOCOL_VERSION, port, cls.challenge, Cvar_Userinfo() );
	else
		Netchan_OutOfBandPrint (NS_CLIENT, adr, "connect %i %i %i \"%s\"\n",
			PROTOCOL_VERSION, port, cls.challenge, Cvar_Userinfo() );
}
예제 #2
0
/* <9a0ba> ../engine/sv_log.c:37 */
void Log_Printf(const char *fmt, ...)
{
	va_list argptr;
	char string[1024];
	time_t ltime;
	tm *today;
	LOGLIST_T *list;

	if (!g_psvs.log.net_log_ && !firstLog && !g_psvs.log.active)
		return;

	time(&ltime);
	today = localtime(&ltime);

	va_start(argptr, fmt);
	Q_snprintf(string,sizeof(string), "L %02i/%02i/%04i - %02i:%02i:%02i: ",
		today->tm_mon + 1,
		today->tm_mday,
		today->tm_year + 1900,
		today->tm_hour,
		today->tm_min,
		today->tm_sec);

	Q_vsnprintf(&string[Q_strlen(string)], sizeof(string) - Q_strlen(string), fmt, argptr);
	va_end(argptr);

#ifdef REHLDS_FLIGHT_REC
	FR_Log("REHLDS_LOG", string);
#endif

	if (g_psvs.log.net_log_ || firstLog != NULL)
	{
		if (g_psvs.log.net_log_)
			Netchan_OutOfBandPrint(NS_SERVER, g_psvs.log.net_address_, "log %s", string);

		for (list = firstLog; list != NULL; list = list->next)
		{
			if (sv_logsecret.value == 0.0f)
				Netchan_OutOfBandPrint(NS_SERVER, list->log.net_address_, "log %s", string);

			else Netchan_OutOfBandPrint(NS_SERVER, list->log.net_address_, "%c%s%s", S2A_LOGKEY, sv_logsecret.string, string);
		}
	}
	if (g_psvs.log.active && (g_psvs.maxclients > 1 || sv_log_singleplayer.value != 0.0f))
	{
		if (mp_logecho.value != 0.0f)
			Con_Printf("%s", string);

		if (g_psvs.log.file)
		{
			if (mp_logfile.value != 0.0f)
				FS_FPrintf((FileHandle_t)g_psvs.log.file, "%s", string);
		}
	}
}
예제 #3
0
/*
* TV_Downstream_GetChallenge
* 
* Returns a challenge number that can be used
* in a subsequent client_connect command.
* We do this to prevent denial of service attacks that
* flood the server with invalid upstream IPs.  With a
* challenge, they must give a valid IP address.
*/
static void TV_Downstream_GetChallenge( const socket_t *socket, const netadr_t *address )
{
	int i;
	int oldest;
	int oldestTime;

	oldest = 0;
	oldestTime = 0x7fffffff;

	// see if we already have a challenge for this ip
	for( i = 0; i < MAX_CHALLENGES; i++ )
	{
		if( NET_CompareBaseAddress( address, &tvs.challenges[i].adr ) )
			break;
		if( tvs.challenges[i].time < oldestTime )
		{
			oldestTime = tvs.challenges[i].time;
			oldest = i;
		}
	}

	if( i == MAX_CHALLENGES )
	{
		// overwrite the oldest
		tvs.challenges[oldest].challenge = rand() & 0x7fff;
		tvs.challenges[oldest].adr = *address;
		tvs.challenges[oldest].time = tvs.realtime;
		i = oldest;
	}

	Netchan_OutOfBandPrint( socket, address, "challenge %i", tvs.challenges[i].challenge );
}
예제 #4
0
/**
 * @brief
 */
static void Cl_SendBroadcast(void) {
	const GList *e = cls.servers;


	while (e) { // update old ping times
		cl_server_info_t *s = (cl_server_info_t *) e->data;

		if (s->source == SERVER_SOURCE_BCAST) {
			s->ping_time = quetoo.ticks;
			s->ping = 999;
		}

		e = e->next;
	}

	net_addr_t addr;
	memset(&addr, 0, sizeof(addr));

	addr.type = NA_BROADCAST;
	addr.port = htons(PORT_SERVER);

	Netchan_OutOfBandPrint(NS_UDP_CLIENT, &addr, "info %i", PROTOCOL_MAJOR);

	cls.broadcast_time = quetoo.ticks;
}
예제 #5
0
/**
 * @brief
 */
void Cl_Ping_f(void) {
	net_addr_t addr;
	cl_server_info_t *server;

	if (Cmd_Argc() != 2) {
		Com_Print("Usage: %s <address>\n", Cmd_Argv(0));
		return;
	}

	server = NULL;

	if (!Net_StringToNetaddr(Cmd_Argv(1), &addr)) {
		Com_Print("Invalid address\n");
		return;
	}

	if (!addr.port) { // use default
		addr.port = (uint16_t) htons(PORT_SERVER);
	}

	server = Cl_ServerForNetaddr(&addr);

	if (!server) { // add it
		server = Cl_AddServer(&addr);
		server->source = SERVER_SOURCE_USER;
	}

	server->ping_time = quetoo.ticks;
	server->ping = 999;

	Com_Print("Pinging %s\n", Net_NetaddrToString(&server->addr));

	Netchan_OutOfBandPrint(NS_UDP_CLIENT, &server->addr, "info %i", PROTOCOL_MAJOR);
}
예제 #6
0
/*
 * We have gotten a challenge from the server, so try and
 * connect.
 */
void
CL_SendConnectPacket(void)
{
	netadr_t adr;
	int port;

	memset(&adr, 0, sizeof(adr));

	if (!NET_StringToAdr(cls.servername, &adr))
	{
		Com_Printf("Bad server address\n");
		cls.connect_time = 0;
		return;
	}

	if (adr.port == 0)
	{
		adr.port = BigShort(PORT_SERVER);
	}

	port = Cvar_VariableValue("qport");

	userinfo_modified = false;

	Netchan_OutOfBandPrint(NS_CLIENT, adr, "connect %i %i %i \"%s\"\n",
			PROTOCOL_VERSION, port, cls.challenge, Cvar_Userinfo());
}
예제 #7
0
/*
* TV_Downstream_MasterHeartbeat
* Send a message to the master every few minutes to
* let it know we are alive, and log information
*/
void TV_Downstream_MasterHeartbeat( void )
{
	int i;
	const socket_t *socket;

	tvs.lobby.last_heartbeat -= tvs.lobby.snapFrameTime;
	if( tvs.lobby.last_heartbeat > 0 )
		return;

	tvs.lobby.last_heartbeat = HEARTBEAT_SECONDS * 1000;

	if( !tv_public->integer )
		return;

	// send to group master
	for( i = 0; i < MAX_MASTERS; i++ )
	{
		if( tv_master_adr[i].type != NA_NOTRANSMIT )
		{
			Com_Printf( "Sending heartbeat to %s\n", NET_AddressToString( &tv_master_adr[i] ) );

			socket = ( tv_master_adr[i].type == NA_IP6 ? &tvs.socket_udp6 : &tvs.socket_udp );

			// warning: "DarkPlaces" is a protocol name here, not a game name. Do not replace it.
			Netchan_OutOfBandPrint( socket, &tv_master_adr[i], "heartbeat %s\n", "DarkPlaces" );
		}
	}
}
예제 #8
0
파일: cl_server.c 프로젝트: darkshade9/aq2w
/*
 * Cl_Ping_f
 */
void Cl_Ping_f(void) {
	net_addr_t addr;
	cl_server_info_t *server;

	if (Cmd_Argc() != 2) {
		Com_Print("Usage: %s <address>\n", Cmd_Argv(0));
		return;
	}

	server = NULL;

	if (!Net_StringToNetaddr(Cmd_Argv(1), &addr)) {
		Com_Print("Invalid address\n");
		return;
	}

	if (!addr.port) // use default
		addr.port = (unsigned short) BigShort(PORT_SERVER);

	server = Cl_ServerForNetaddr(&addr);

	if (!server) { // add it
		server = Cl_AddServer(&addr);
		server->source = SERVER_SOURCE_USER;
	}

	server->ping_time = cls.real_time;
	server->ping = 0;

	Com_Print("Pinging %s\n", Net_NetaddrToString(server->addr));

	Netchan_OutOfBandPrint(NS_CLIENT, server->addr, "info %i", PROTOCOL);
}
예제 #9
0
파일: sv_main.cpp 프로젝트: RkShaRkz/Quake2
/*
=================
cGetChallenge

Returns a challenge number that can be used
in a subsequent client_connect 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.
=================
*/
static void cGetChallenge(int argc, char **argv)
{
	int		i;

	int oldest = 0;
	int oldestTime = 0x7FFFFFFF;

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

	if (i == MAX_CHALLENGES)
	{
		// overwrite the oldest
		svs.challenges[oldest].challenge = rand() & 0x7FFF;
		svs.challenges[oldest].adr = net_from;
		svs.challenges[oldest].time = appMilliseconds();
		i = oldest;
	}

	// send it back
	Netchan_OutOfBandPrint(NS_SERVER, net_from, "challenge %d", svs.challenges[i].challenge);
}
예제 #10
0
파일: sv_main.c 프로젝트: darkshade9/aq2w
/*
 * Svc_Info
 *
 * Responds with short info for broadcast scans.
 */
static void Svc_Info(void) {
	char string[MAX_MSG_SIZE];
	int i, count;
	int prot;

	if (sv_max_clients->integer == 1)
		return; // ignore in single player

	prot = atoi(Cmd_Argv(1));

	if (prot != PROTOCOL)
		snprintf(string, sizeof(string), "%s: wrong protocol version\n", sv_hostname->string);
	else {
		count = 0;

		for (i = 0; i < sv_max_clients->integer; i++) {
			if (svs.clients[i].state >= SV_CLIENT_CONNECTED)
				count++;
		}

		snprintf(string, sizeof(string), "%-63s\\%-31s\\%-31s\\%d\\%d",
				sv_hostname->string, sv.name, Cvar_GetString("g_gameplay"),
				count, sv_max_clients->integer);
	}

	Netchan_OutOfBandPrint(NS_SERVER, net_from, "info\n%s", string);
}
예제 #11
0
파일: sv_oob.c 프로젝트: Racenet/racesow
//================
// SV_MMHeartbeat
// Send matchmaker a heartbeat with status
//================
void SV_MMHeartbeat( void )
{
	static qboolean canhost = qfalse;
	netadr_t address;
	socket_t *socket;

	if( !sv_public->integer )
		return;

	// never go public when not acting as a game server
	if( sv.state > ss_game )
		return;

	if( !SV_MM_Initialized() || SV_MM_IsLocked() )
		return;

	svc.last_mmheartbeat -= svc.snapFrameTime;

	if( svc.last_mmheartbeat > 0 && canhost == SV_MM_CanHost() )
		return;

	if ( !SV_MM_NetAddress( &address ) )
		return;

	svc.last_mmheartbeat = MM_HEARTBEAT_SECONDS * 1000;
	canhost = SV_MM_CanHost();

	socket = ( address.type == NA_IP6 ? &svs.socket_udp6 : &svs.socket_udp );

	Netchan_OutOfBandPrint( socket, &address,
		"heartbeat %s %d %d %s", canhost ? "yes":"no", APP_PROTOCOL_VERSION, SV_MM_GetSlotCount(), SV_MM_Salt() );

	Com_Printf( "Sending heartbeat to matchmaker\n" );
}
예제 #12
0
/*
* SVC_GetChallenge
* 
* Returns a challenge number that can be used
* in a subsequent client_connect 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.
*/
static void SVC_GetChallenge( const socket_t *socket, const netadr_t *address )
{
	int i;
	int oldest;
	int oldestTime;

	oldest = 0;
	oldestTime = 0x7fffffff;

	if( sv_showChallenge->integer )
		Com_Printf( "Challenge Packet %s\n", NET_AddressToString( address ) );

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

	if( i == MAX_CHALLENGES )
	{
		// overwrite the oldest
		svs.challenges[oldest].challenge = rand() & 0x7fff;
		svs.challenges[oldest].adr = *address;
		svs.challenges[oldest].time = Sys_Milliseconds();
		i = oldest;
	}

	Netchan_OutOfBandPrint( socket, address, "challenge %i", svs.challenges[i].challenge );
}
예제 #13
0
/*
================
SVC_Info

Responds with short info for broadcast scans
The second parameter should be the current protocol version number.
================
*/
void SVC_Info(void)
{
    char string[64];
    int i, count;
    int version;

    if (maxclients->value == 1)
        return; // ignore in single player

    version = atoi(Cmd_Argv(1));

    if (version != PROTOCOL_VERSION)
        Com_sprintf(string, sizeof(string), "%s: wrong version\n", hostname->string, sizeof(string));
    else
    {
        count = 0;
        for (i = 0; i < maxclients->value; i++)
            if (svs.clients[i].state >= cs_connected)
                count++;

        Com_sprintf(string, sizeof(string), "%16s %8s %2i/%2i\n", hostname->string, sv.name, count, (int)maxclients->value);
    }

    Netchan_OutOfBandPrint(NS_SERVER, net_from, "info\n%s", string);
}
예제 #14
0
/*
 * @brief Returns a challenge number that can be used in a subsequent client_connect
 * 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 address.
 */
static void Svc_GetChallenge(void) {
	uint16_t i, oldest;
	uint32_t oldest_time;

	oldest = 0;
	oldest_time = 0x7fffffff;

	// see if we already have a challenge for this ip
	for (i = 0; i < MAX_CHALLENGES; i++) {

		if (Net_CompareClientNetaddr(&net_from, &svs.challenges[i].addr))
			break;

		if (svs.challenges[i].time < oldest_time) {
			oldest_time = svs.challenges[i].time;
			oldest = i;
		}
	}

	if (i == MAX_CHALLENGES) {
		// overwrite the oldest
		svs.challenges[oldest].challenge = Random() & 0x7fff;
		svs.challenges[oldest].addr = net_from;
		svs.challenges[oldest].time = quake2world.time;
		i = oldest;
	}

	// send it back
	Netchan_OutOfBandPrint(NS_UDP_SERVER, &net_from, "challenge %i", svs.challenges[i].challenge);
}
예제 #15
0
void Master_Heartbeat (void)
{
	char		*string;
	int			i;

	// pgm post3.19 change, cvar pointer not validated before dereferencing
	if (!dedicated || !dedicated->value)
		return;		// only dedicated servers send heartbeats

	// pgm post3.19 change, cvar pointer not validated before dereferencing
	if (!public_server || !public_server->value)
		return;		// a private dedicated game

	// check for time wraparound
	if (svs.last_heartbeat > svs.realtime)
		svs.last_heartbeat = svs.realtime;

	if (svs.realtime - svs.last_heartbeat < HEARTBEAT_SECONDS*1000)
		return;		// not time to send yet

	svs.last_heartbeat = svs.realtime;

	// send the same string that we would give for a status OOB command
	string = SV_StatusString();

	// send to group master
	for (i=0 ; i<MAX_MASTERS ; i++)
		if (master_adr[i].port)
		{
			Com_Printf ("Sending heartbeat to %s\n", NET_AdrToString (master_adr[i]));
			Netchan_OutOfBandPrint (NS_SERVER, master_adr[i], "heartbeat\n%s", string);
		}
}
예제 #16
0
파일: sv_main.cpp 프로젝트: RkShaRkz/Quake2
/*
================
cInfo

Responds with short info for broadcast scans
The second parameter should be the current protocol version number.
================
*/
static void cInfo(int argc, char **argv)
{
	if (sv_maxclients->integer == 1 || sv.state == ss_demo || sv.attractloop)
		return;					// ignore in single player or demoplay

	int version = atoi(argv[1]);

	if (!version)
	{
		// we should reject this packet -- this is our "info" answer to local client (loopback packet)
		Com_DPrintf("rejected \"info\" answer\n");
		return;
	}

	TString<64> Str;
	if (version != PROTOCOL_VERSION)
		Str.sprintf("%s: wrong version %d\n", hostname->string, version);
	else
	{
		int count = 0;
		for (int i = 0; i < sv_maxclients->integer; i++)
			if (svs.clients[i].state >= cs_connected)
				count++;

		Str.sprintf("%16s %8s %2d/%2d\n", hostname->string, sv.name, count, sv_maxclients->integer);
	}
	Netchan_OutOfBandPrint(NS_SERVER, net_from, "info\n%s", *Str);
}
예제 #17
0
파일: sv_main.c 프로젝트: ZwS/qudos
/*
 * ================= SVC_GetChallenge
 *
 * Returns a challenge number that can be used in a subsequent client_connect
 * 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
SVC_GetChallenge(void)
{
	int		i;
	int		oldest;
	int		oldestTime;

	oldest = 0;
	oldestTime = 0x7fffffff;

	/* see if we already have a challenge for this ip */
	for (i = 0; i < MAX_CHALLENGES; i++) {
		if (NET_CompareBaseAdr(net_from, svs.challenges[i].adr))
			break;
		if (svs.challenges[i].time < oldestTime) {
			oldestTime = svs.challenges[i].time;
			oldest = i;
		}
	}

	if (i == MAX_CHALLENGES) {
		/* overwrite the oldest */
		svs.challenges[oldest].challenge = rand() & 0x7fff;
		svs.challenges[oldest].adr = net_from;
		svs.challenges[oldest].time = curtime;
		i = oldest;
	}
	/* send it back */
	Netchan_OutOfBandPrint(NS_SERVER, net_from, "challenge %i", svs.challenges[i].challenge);
}
예제 #18
0
파일: cl_main.c 프로젝트: Reedych/xash3d
/*
=================
CL_CheckForResend

Resend a connect message if the last one has timed out
=================
*/
void CL_CheckForResend( void )
{
	netadr_t	adr;

	// if the local server is running and we aren't then connect
	if( cls.state == ca_disconnected && SV_Active( ))
	{
		cls.state = ca_connecting;
		Q_strncpy( cls.servername, "localhost", sizeof( cls.servername ));
		// we don't need a challenge on the localhost
		CL_SendConnectPacket();
		return;
	}

	// resend if we haven't gotten a reply yet
	if( cls.demoplayback || cls.state != ca_connecting )
		return;

	if(( host.realtime - cls.connect_time ) < 10.0f )
		return;

	if( !NET_StringToAdr( cls.servername, &adr ))
	{
		MsgDev( D_ERROR, "CL_CheckForResend: bad server address\n" );
		cls.state = ca_disconnected;
		return;
	}

	if( adr.port == 0 ) adr.port = BF_BigShort( PORT_SERVER );
	cls.connect_time = host.realtime; // for retransmit requests

	MsgDev( D_NOTE, "Connecting to %s...\n", cls.servername );
	Netchan_OutOfBandPrint( NS_CLIENT, adr, "getchallenge\n" );
}
예제 #19
0
/*
 * =================
 * Master_Shutdown
 *
 * Informs all masters that this server is going down
 * =================
 */
void Master_Shutdown(void)
{
    int i;

    // pgm post3.19 change, cvar pointer not validated before dereferencing
    if (!dedicated || !dedicated->value)
    {
        return;                 // only dedicated servers send heartbeats
    }
    // pgm post3.19 change, cvar pointer not validated before dereferencing
    if (!public_server || !public_server->value)
    {
        return;                 // a private dedicated game
    }
    // send to group master
    for (i = 0; i < MAX_MASTERS; i++)
    {
        if (master_adr[i].port)
        {
            if (i > 0)
            {
                Com_Printf("Sending heartbeat to %s\n", NET_AdrToString(master_adr[i]));
            }
            Netchan_OutOfBandPrint(NS_SERVER, master_adr[i], "shutdown");
        }
    }
}
예제 #20
0
파일: sv_main.cpp 프로젝트: RkShaRkz/Quake2
static void Master_Heartbeat()
{
	if (!DEDICATED)
		return;		// only dedicated servers send heartbeats

	if (!public_server->integer)
		return;		// a private dedicated game

	// check for time wraparound
	if (svs.last_heartbeat > svs.realtime)
		svs.last_heartbeat = svs.realtime;

	if (svs.realtime - svs.last_heartbeat < HEARTBEAT_SECONDS*1000)
		return;		// not time to send yet

	svs.last_heartbeat = svs.realtime;

	// send the same string that we would give for a status OOB command
	const char *string = SV_StatusString();

	// send to group master
	for (int i = 0; i < MAX_MASTERS; i++)
		if (master_adr[i].port)
		{
			appPrintf("Sending heartbeat to %s\n", NET_AdrToString(&master_adr[i]));
			Netchan_OutOfBandPrint(NS_SERVER, master_adr[i], "heartbeat\n%s", string);
		}
}
예제 #21
0
/*
* SV_MasterHeartbeat
* Send a message to the master every few minutes to
* let it know we are alive, and log information
*/
void SV_MasterHeartbeat( void )
{
	int i;

	svc.lastHeartbeat -= svc.snapFrameTime;
	if( svc.lastHeartbeat > 0 )
		return;

	svc.lastHeartbeat = HEARTBEAT_SECONDS * 1000;

	if( !sv_public->integer )
		return;

	// never go public when not acting as a game server
	if( sv.state > ss_game )
		return;

	// send to group master
	for( i = 0; i < MAX_MASTERS; i++ )
	{
		if( master_adr[i].type != NA_NOTRANSMIT )
		{
			socket_t *socket;

			if( dedicated && dedicated->integer )
				Com_Printf( "Sending heartbeat to %s\n", NET_AddressToString( &master_adr[i] ) );

			socket = ( master_adr[i].type == NA_IP6 ? &svs.socket_udp6 : &svs.socket_udp );

			// warning: "DarkPlaces" is a protocol name here, not a game name. Do not replace it.
			Netchan_OutOfBandPrint( socket, &master_adr[i], "heartbeat DarkPlaces\n" );
		}
	}
}
예제 #22
0
/*
* SVC_SendInfoString
*/
static void SVC_SendInfoString( const socket_t *socket, const netadr_t *address, const char *requestType, const char *responseType, qboolean fullStatus )
{
	char *string;

	if( sv_showInfoQueries->integer )
		Com_Printf( "%s Packet %s\n", requestType, NET_AddressToString( address ) );

	// KoFFiE: When not public and coming from a LAN address
	//         assume broadcast and respond anyway, otherwise ignore
	if( ( ( !sv_public->integer ) && ( !NET_IsLANAddress( address ) ) ) ||
		( sv_maxclients->integer == 1 ) )
	{
		return;
	}

	// ignore when in invalid server state
	if( sv.state < ss_loading || sv.state > ss_game )
		return;

	// don't reply when we are locked for mm
	// if( SV_MM_IsLocked() )
	//	return;

	// send the same string that we would give for a status OOB command
	string = SV_LongInfoString( fullStatus );
	if( string )
		Netchan_OutOfBandPrint( socket, address, "%s\n\\challenge\\%s%s", responseType, Cmd_Argv( 1 ), string );
}
예제 #23
0
파일: sv_main.c 프로젝트: matatk/agrip
/*
=================
SVC_GetChallenge

Returns a challenge number that can be used
in a subsequent client_connect 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 SVC_GetChallenge (void)
{
	int		i;
	int		oldest;
	int		oldestTime;

	oldest = 0;
	oldestTime = 0x7fffffff;

	// see if we already have a challenge for this ip
	for (i = 0 ; i < MAX_CHALLENGES ; i++)
	{
		if (NET_CompareBaseAdr (net_from, svs.challenges[i].adr))
			break;
		if (svs.challenges[i].time < oldestTime)
		{
			oldestTime = svs.challenges[i].time;
			oldest = i;
		}
	}

	if (i == MAX_CHALLENGES)
	{
		// overwrite the oldest
		svs.challenges[oldest].challenge = (rand() << 16) ^ rand();
		svs.challenges[oldest].adr = net_from;
		svs.challenges[oldest].time = svs.realtime;
		i = oldest;
	}

	// send it back
	Netchan_OutOfBandPrint (NS_SERVER, net_from, "%c%i", S2C_CHALLENGE, 
			svs.challenges[i].challenge);
}
예제 #24
0
/*
 * @brief Sends heartbeat messages to master servers every 300s.
 */
void Sv_HeartbeatMasters(void) {
	const char *string;
	int32_t i;

	if (!dedicated->value)
		return; // only dedicated servers report to masters

	if (!sv_public->value)
		return; // a private dedicated game

	if (!svs.initialized) // we're not up yet
		return;

	if (svs.next_heartbeat > quetoo.time)
		return; // not time to send yet

	svs.next_heartbeat = quetoo.time + HEARTBEAT_SECONDS * 1000;

	// send the same string that we would give for a status command
	string = Sv_StatusString();

	// send to each master server
	for (i = 0; i < MAX_MASTERS; i++) {
		if (svs.masters[i].port) {
			Com_Print("Sending heartbeat to %s\n", Net_NetaddrToString(&svs.masters[i]));
			Netchan_OutOfBandPrint(NS_UDP_SERVER, &svs.masters[i], "heartbeat\n%s", string);
		}
	}
}
예제 #25
0
/*
* CL_PingServer_f
*/
void CL_PingServer_f( void )
{
	char *address_string;
	char requestString[64];
	netadr_t adr;
	serverlist_t *pingserver;
	socket_t *socket;

	if( Cmd_Argc() < 2 )
		Com_Printf( "Usage: pingserver [ip:port]\n" );

	address_string = Cmd_Argv( 1 );

	if( !NET_StringToAddress( address_string, &adr ) )
		return;

	pingserver = CL_ServerFindInList( masterList, address_string );
	if( !pingserver )
		pingserver = CL_ServerFindInList( favoritesList, address_string );
	if( !pingserver )
		return;

	// never request a second ping while awaiting for a ping reply
	if( pingserver->pingTimeStamp + SERVER_PINGING_TIMEOUT > Sys_Milliseconds() )
		return;

	pingserver->pingTimeStamp = Sys_Milliseconds();

	Q_snprintfz( requestString, sizeof( requestString ), "info %i %s %s", SERVERBROWSER_PROTOCOL_VERSION,
		filter_allow_full ? "full" : "",
		filter_allow_empty ? "empty" : "" );

	socket = ( adr.type == NA_IP6 ? &cls.socket_udp6 : &cls.socket_udp );
	Netchan_OutOfBandPrint( socket, &adr, requestString );
}
예제 #26
0
/*
* CL_QueryGetInfoMessage
*/
static void CL_QueryGetInfoMessage( const char *cmdname )
{
	netadr_t adr;
	char *requeststring;
	char *server;

	//get what master
	server = Cmd_Argv( 1 );
	if( !server || !( *server ) )
	{
		Com_Printf( "%s: no address provided %s...\n", Cmd_Argv( 0 ), server ? server : "" );
		return;
	}

	requeststring = va( cmdname );

	// send a broadcast packet
	Com_DPrintf( "quering %s...\n", server );

	if( NET_StringToAddress( server, &adr ) )
	{
		socket_t *socket;

		if( NET_GetAddressPort( &adr ) == 0 )
			NET_SetAddressPort( &adr, PORT_SERVER );

		socket = ( adr.type == NA_IP6 ? &cls.socket_udp6 : &cls.socket_udp );
		Netchan_OutOfBandPrint( socket, &adr, requeststring );
	}
	else
	{
		Com_Printf( "Bad address: %s\n", server );
	}
}
예제 #27
0
/*
 * ================
 * SVC_Info
 *
 * Responds with short info for broadcast scans
 * The second parameter should be the current protocol version number.
 * ================
 */
void SVC_Info(void)
{
    char string[64];
    int  i, count;
    int  version;

    if (maxclients->value == 1)
    {
        return;                 // ignore in single player
    }
    version = atoi(Cmd_Argv(1));

    if (version != PROTOCOL_VERSION)
    {           // According to r1ch, this can be used to make servers endlessly ping each other
        //	Com_sprintf (string, sizeof(string), "%s: wrong version\n", hostname->string, sizeof(string));
        return;
    }
    else
    {
        count = 0;
        for (i = 0; i < maxclients->value; i++)
        {
            if (svs.clients[i].state >= cs_connected)
            {
                count++;
            }
        }

        Com_sprintf(string, sizeof(string), "%16s %8s %2i/%2i\n", hostname->string, sv.name, count, (int)maxclients->value);
    }

    Netchan_OutOfBandPrint(NS_SERVER, net_from, "info\n%s", string);
}
예제 #28
0
/*
 * @brief
 */
void Cl_ParseServers(void) {
	cl_server_info_t *server;

	byte *buffptr = net_message.data + 12;
	byte *buffend = buffptr + net_message.size - 12;

	// parse the list
	while (buffptr + 1 < buffend) {
		net_addr_t addr;
		byte ip[4];

		ip[0] = *buffptr++; // parse the address
		ip[1] = *buffptr++;
		ip[2] = *buffptr++;
		ip[3] = *buffptr++;

		uint16_t port = (*buffptr++) << 8; // and the port
		port += *buffptr++;

		char s[32];
		g_snprintf(s, sizeof(s), "%d.%d.%d.%d:%d", ip[0], ip[1], ip[2], ip[3], port);

		Com_Debug("Parsed %s\n", s);

		if (!Net_StringToNetaddr(s, &addr)) { // make sure it's valid
			Com_Warn("Invalid address: %s\n", s);
			break;
		}

		if (!addr.port) // 0's mean we're done
			break;

		server = Cl_ServerForNetaddr(&addr);

		if (!server)
			server = Cl_AddServer(&addr);

		server->source = SERVER_SOURCE_INTERNET;
	}

	net_message.read = net_message.size;

	// then ping them

	GList *e = cls.servers;

	while (e) {
		server = (cl_server_info_t *) e->data;

		if (server->source == SERVER_SOURCE_INTERNET) {
			server->ping_time = cls.real_time;
			server->ping = 0;

			Netchan_OutOfBandPrint(NS_UDP_CLIENT, &server->addr, "info %i", PROTOCOL_MAJOR);
		}

		e = e->next;
	}
}
예제 #29
0
static void M_ServerlistUpdateUDP (int nStart)
{
	netadr_t adr;
	static qboolean didUpdateCheck = false;

	adr.port = htons(UDP_SERVERLIST_PORT);
	NET_StringToAdr(serverlist_udp_source1->string, &adr);
	//Netchan_OutOfBandPrint(NS_CLIENT, adr, "serverlist1 %d %s\n", nStart, g_szRandomServerlistString);
	Netchan_OutOfBandPrint(NS_CLIENT, adr, "serverlist2\n");

	if (!didUpdateCheck && !g_notified_of_new_version)
	{
		 // Not currently implemented on dplogin server, but it may work eventually:
		Netchan_OutOfBandPrint(NS_CLIENT, adr, "updatecheck1 " BUILD_S "\n"); // versioncheck / checkversion / buildcheck
		didUpdateCheck = true;
	}
}
예제 #30
0
파일: cl_server.c 프로젝트: darkshade9/aq2w
/*
 * Cl_ParseServersList
 */
void Cl_ParseServersList(void) {
	byte *buffptr;
	byte *buffend;
	byte ip[4];
	unsigned short port;
	net_addr_t addr;
	cl_server_info_t *server;
	char s[32];

	buffptr = net_message.data + 12;
	buffend = buffptr + net_message.size - 12;

	// parse the list
	while (buffptr + 1 < buffend) {

		ip[0] = *buffptr++; // parse the address
		ip[1] = *buffptr++;
		ip[2] = *buffptr++;
		ip[3] = *buffptr++;

		port = (*buffptr++) << 8; // and the port
		port += *buffptr++;

		snprintf(s, sizeof(s), "%d.%d.%d.%d:%d", ip[0], ip[1], ip[2], ip[3], port);

		if (!Net_StringToNetaddr(s, &addr)) { // make sure it's valid
			Com_Warn("Cl_ParseServersList: Invalid address: %s.\n", s);
			break;
		}

		if (!addr.port) // 0's mean we're done
			break;

		server = Cl_ServerForNetaddr(&addr);

		if (!server)
			server = Cl_AddServer(&addr);

		server->source = SERVER_SOURCE_INTERNET;
	}

	net_message.read = net_message.size;

	// then ping them
	server = cls.servers;

	while (server) {

		if (server->source == SERVER_SOURCE_INTERNET) {
			server->ping_time = cls.real_time;
			server->ping = 0;

			Netchan_OutOfBandPrint(NS_CLIENT, server->addr, "info %i", PROTOCOL);
		}

		server = server->next;
	}
}