Example #1
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 );
}
Example #2
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 );
}
Example #3
0
/**
 * @sa CL_ConnectionlessPacket
 * @sa CL_Frame
 * @sa CL_ParseServerMessage
 * @sa NET_ReadMsg
 * @sa SV_ReadPacket
 */
static void CL_ReadPackets (void)
{
	dbuffer* msg;
	while ((msg = NET_ReadMsg(cls.netStream))) {
		const svc_ops_t cmd = NET_ReadByte(msg);
		if (cmd == svc_oob)
			CL_ConnectionlessPacket(msg);
		else
			CL_ParseServerMessage(cmd, msg);
		delete msg;
	}
}
Example #4
0
File: peer.c Project: deurk/qwfwd
static void FWD_network_update(void)
{
	fd_set rfds;
	struct timeval tv;
	int retval;
	int i1;
	peer_t *p;

	FD_ZERO(&rfds);

	// select on main server socket
	FD_SET(net_socket, &rfds);
	i1 = net_socket + 1;

	for (p = peers; p; p = p->next)
	{
		// select on peers sockets
		FD_SET(p->s, &rfds);
		if (p->s >= i1)
			i1 = p->s + 1;
	}

// if not DLL - read stdin
#ifndef APP_DLL
	#ifndef _WIN32
	// try read stdin only if connected to a terminal.
	if (isatty(STDIN) && isatty(STDOUT))
	{
		FD_SET(STDIN, &rfds);
		if (STDIN >= i1)
			i1 = STDIN + 1;
	}
	#endif // _WIN32
#endif

	/* Sleep for some time, wake up immidiately if there input packet. */
	tv.tv_sec = 0;
	tv.tv_usec = 100000; // 100 ms
	retval = select(i1, &rfds, (fd_set *)0, (fd_set *)0, &tv);

	// read console input.
	// NOTE: we do not do that if we are in DLL mode...
	Sys_ReadSTDIN(&ps, rfds);

	if (retval <= 0)
		return;

	// if we have input packet on main server/proxy socket, then read it
	if(FD_ISSET(net_socket, &rfds))
	{
		qbool connectionless;
		int cnt;

		// read it
		for(;;)
		{
			if (!NET_GetPacket(net_socket, &net_message))
				break;

			// check for bans.
			if (SV_IsBanned(&net_from))
				continue;

			if (net_message.cursize == 1 && net_message.data[0] == A2A_ACK)
			{
				QRY_SV_PingReply();

				continue;
			}

			MSG_BeginReading();
			connectionless = (MSG_ReadLong() == -1);

			if (connectionless)
			{
				if (MSG_BadRead())
					continue;

				if (!SV_ConnectionlessPacket())
					continue; // seems we do not need forward it
			}

			// search in peers
			for (p = peers; p; p = p->next)
			{
				// we have this peer already, so forward/send packet to remote server
				if (NET_CompareAddress(&p->from, &net_from))
					break;
			}

			// peer was not found
			if (!p)
				continue;

			// forward data to the server/proxy
			if (p->ps >= ps_connected)
			{
				cnt = 1; // one packet by default

				// check for "drop" aka client disconnect,
				// first 10 bytes for NON connectionless packet is netchan related shit in QW
				if (p->proto == pr_qw && !connectionless && net_message.cursize > 10 && net_message.data[10] == clc_stringcmd)
				{
					if (!strcmp((char*)net_message.data + 10 + 1, "drop"))
					{
//						Sys_Printf("peer drop detected\n");
						p->ps = ps_drop; // drop peer ASAP
						cnt = 3; // send few packets due to possibile packet lost
					}
				}

				for ( ; cnt > 0; cnt--)
					NET_SendPacket(p->s, net_message.cursize, net_message.data, &p->to);
			}

			time(&p->last);
		}
	}

	// now lets check peers sockets, perhaps we have input packets too
	for (p = peers; p; p = p->next)
	{
		if(FD_ISSET(p->s, &rfds))
		{
			// yeah, we have packet, read it then
			for (;;)
			{
				if (!NET_GetPacket(p->s, &net_message))
					break;

				// check for bans.
				if (SV_IsBanned(&net_from))
					continue;

				// we should check is this packet from remote server, this may be some evil packet from haxors...
				if (!NET_CompareAddress(&p->to, &net_from))
					continue;

				MSG_BeginReading();
				if (MSG_ReadLong() == -1)
				{
					if (MSG_BadRead())
						continue;

					if (!CL_ConnectionlessPacket(p))
						continue; // seems we do not need forward it

					NET_SendPacket(net_socket, net_message.cursize, net_message.data, &p->from);
					continue;
				}

				if (p->ps >= ps_connected)
					NET_SendPacket(net_socket, net_message.cursize, net_message.data, &p->from);

// qqshka: commented out
//				time(&p->last);

			} // for (;;)
		} // if(FD_ISSET(p->s, &rfds))

		if (p->ps == ps_challenge)
		{
			// send challenge time to time
			if (time(NULL) - p->connect > 2)
			{
				p->connect = time(NULL);
				Netchan_OutOfBandPrint(p->s, &p->to, "getchallenge%s", p->proto == pr_qw ? "\n" : "");
			}
		}
	} // for (p = peers; p; p = p->next)
}