summaryrefslogtreecommitdiff
path: root/networksystem/udp_process.cpp
blob: 92d08c51ef9e492c58e16a4bf5cfa5c0cd610b04 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
//===========================================================================//

#include "tier1/utlbuffer.h"
#include "UDP_Socket.h"
#include "NetChannel.h"
#include "sm_protocol.h"
#include "networksystem.h"


//-----------------------------------------------------------------------------
// Allocates memory for packets
//-----------------------------------------------------------------------------
static CUtlMemoryPool s_PacketBufferAlloc( NET_MAX_MESSAGE, 8, CUtlMemoryPool::GROW_SLOW );
DEFINE_FIXEDSIZE_ALLOCATOR( CNetPacket, 32, CUtlMemoryPool::GROW_SLOW );


//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
CNetPacket::CNetPacket()
{
	m_pData = reinterpret_cast<byte*>( s_PacketBufferAlloc.Alloc() );
	m_nRefCount = 1;
}

CNetPacket::~CNetPacket()
{
	s_PacketBufferAlloc.Free( m_pData );
}

void CNetPacket::AddRef()
{
	++m_nRefCount;
}

void CNetPacket::Release()
{
	if ( --m_nRefCount <= 0 )
	{
		delete this;
	}
}
	
bool UDP_ReceiveDatagram( CUDPSocket *pSocket, CNetPacket* pPacket )
{
	Assert( pPacket );

	netadr_t packetFrom;
	CUtlBuffer buf( pPacket->m_pData, NET_MAX_MESSAGE );
	if ( pSocket->RecvFrom( packetFrom, buf ) )
	{
		pPacket->m_From = packetFrom;
		pPacket->m_nSizeInBytes = buf.TellPut();
		return true;
	}
	return false;
}

CNetPacket *UDP_GetPacket( CUDPSocket *pSocket )
{
	CNetPacket *pPacket = new CNetPacket;

	// setup new packet
	pPacket->m_From.SetType( NA_IP );
	pPacket->m_From.Clear();
	pPacket->m_flReceivedTime = g_pNetworkSystemImp->GetTime();
	pPacket->m_pSource = pSocket;	
	pPacket->m_nSizeInBytes = 0;
	pPacket->m_Message.SetDebugName("inpacket.message");

	// then check UDP data 
	if ( !UDP_ReceiveDatagram( pSocket, pPacket ) )
	{
		delete pPacket;
		return NULL;
	}
		
	Assert( pPacket->m_nSizeInBytes ); 
	
	// prepare bitbuffer for reading packet with new size
	pPacket->m_Message.StartReading( pPacket->m_pData, pPacket->m_nSizeInBytes );
	return pPacket;
}

void UDP_ProcessSocket( CUDPSocket *pSocket, IConnectionlessPacketHandler *pHandler, ILookupChannel *pLookup )
{
	CNetPacket *pPacket;
	
	Assert( pSocket );

	// Get datagrams from sockets
	while ( ( pPacket = UDP_GetPacket ( pSocket ) ) != NULL )
	{
		/*
		if ( Filter_ShouldDiscard ( pPacket->m_From ) )	// filterning is done by network layer
		{
			Filter_SendBan( pPacket->m_From );	// tell them we aren't listening...
			continue;
		} 
		*/

		// Find the netchan it came from
		if ( *(unsigned int *)pPacket->m_pData == CONNECTIONLESS_HEADER )
		{
			g_pNetworkSystemImp->EnqueueConnectionlessNetworkPacket( pPacket, pHandler );
		}
		else
		{
			INetChannel *pNetChan = pLookup->FindNetChannel( pPacket->m_From );
			g_pNetworkSystemImp->EnqueueNetworkPacket( pPacket, static_cast<CNetChannel*>( pNetChan ) );
		}
	}
}

void UDP_ProcessConnectionlessPacket( CNetPacket *pPacket, IConnectionlessPacketHandler *pHandler )
{
	// check for connectionless packet (0xffffffff) first
	Assert( *(unsigned int *)pPacket->m_pData == CONNECTIONLESS_HEADER );

	pPacket->m_Message.ReadLong();	// read the -1

	/*
	if ( net_showudp.GetInt() )
	{
		Msg("UDP <- %s: sz=%i OOB '%c'\n", info.m_pPacket->m_From.ToString(), pPacket->m_nSizeInBytes, pPacket->m_pData[4] );
	}
	*/

	pHandler->ProcessConnectionlessPacket( pPacket );
}