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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
// Should move to common/networksystem
#ifndef NETCHANNEL_H
#define NETCHANNEL_H
#ifdef _WIN32
#pragma once
#endif
#include "tier1/bitbuf.h"
#include "tier1/netadr.h"
#include "sm_Protocol.h"
#include "tier1/utlvector.h"
#include "networksystem/inetworksystem.h"
#include "tier1/mempool.h"
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class CUDPSocket;
class CUtlBuffer;
class CNetPacket;
class CNetChannel;
class INetChannel;
// 0 == regular, 1 == file stream
enum
{
FRAG_NORMAL_STREAM = 0,
FRAG_FILE_STREAM,
MAX_STREAMS
};
#define NET_MAX_DATAGRAM_PAYLOAD 1400
#define NET_MAX_PAYLOAD_BITS 11 // 2^NET_MAX_PALYLOAD_BITS > NET_MAX_PAYLOAD
#define DEFAULT_RATE 10000
#define SIGNON_TIME_OUT 120.0f
#define CONNECTION_PROBLEM_TIME 15.0f
#define MAX_RATE 50000
#define MIN_RATE 100
#define FRAGMENT_BITS 8
#define FRAGMENT_SIZE (1<<FRAGMENT_BITS)
#define MAX_FILE_SIZE_BITS 26
#define MAX_FILE_SIZE ((1<<MAX_FILE_SIZE_BITS)-1) // maximum transferable size is 64MB
#define NET_MAX_PAYLOAD 4000
#define NET_MAX_MESSAGE 4096
#define MIN_ROUTEABLE_PACKET 16
#define MAX_ROUTEABLE_PACKET 1400 // Ethernet 1518 - ( CRC + IP + UDP header)
#define UDP_HEADER_SIZE 28
// each channel packet has 1 byte of FLAG bits
#define PACKET_FLAG_RELIABLE (1<<0) // packet contains subchannel stream data
#define PACKET_FLAG_CHOKED (1<<1) // packet was choked by sender
// shared commands used by all streams, handled by stream layer, TODO
abstract_class INetworkMessageHandler
{
public:
virtual void OnConnectionClosing( INetChannel *channel, char const *reason ) = 0;
virtual void OnConnectionStarted( INetChannel *channel ) = 0;
virtual void OnPacketStarted( int inseq, int outseq ) = 0;
virtual void OnPacketFinished() = 0;
protected:
virtual ~INetworkMessageHandler() {}
};
class INetChannelHandler
{
public:
virtual ~INetChannelHandler( void ) {};
virtual void ConnectionStart(INetChannel *chan) = 0; // called first time network channel is established
virtual void ConnectionClosing(const char *reason) = 0; // network channel is being closed by remote site
virtual void ConnectionCrashed(const char *reason) = 0; // network error occured
virtual void PacketStart(int incoming_sequence, int outgoing_acknowledged) = 0; // called each time a new packet arrived
virtual void PacketEnd( void ) = 0; // all messages has been parsed
virtual void FileRequested(const char *fileName, unsigned int transferID) = 0; // other side request a file for download
virtual void FileReceived(const char *fileName, unsigned int transferID) = 0; // we received a file
virtual void FileDenied(const char *fileName, unsigned int transferID) = 0; // a file request was denied by other side
};
// server to client
class CNetPacket
{
DECLARE_FIXEDSIZE_ALLOCATOR( CNetPacket );
public:
CNetPacket();
~CNetPacket();
void AddRef();
void Release();
public:
netadr_t m_From; // sender IP
CUDPSocket *m_pSource; // received source
float m_flReceivedTime; // received time
unsigned char *m_pData; // pointer to raw packet data
bf_read m_Message; // easy bitbuf data access
int m_nSizeInBytes; // size in bytes
private:
int m_nRefCount;// Reference count
};
abstract_class IConnectionlessPacketHandler
{
public:
virtual bool ProcessConnectionlessPacket( CNetPacket *packet ) = 0; // process a connectionless packet
protected:
virtual ~IConnectionlessPacketHandler( void ) {};
};
abstract_class ILookupChannel
{
public:
virtual INetChannel *FindNetChannel( const netadr_t& from ) = 0;
};
// FIXME: Make an INetChannel
class CNetChannel : public INetChannel
{
public:
explicit CNetChannel();
~CNetChannel();
// Methods of INetChannel
virtual ConnectionStatus_t GetConnectionState( );
virtual const netadr_t &GetRemoteAddress( void ) const;
void Setup( bool serverSide, const netadr_t *remote_address, CUDPSocket *sendSocket, char const *name, INetworkMessageHandler *handler );
void Reset();
void Clear();
void Shutdown( const char *reason );
CUDPSocket *GetSocket();
void SetDataRate( float rate );
void SetTimeout( float seconds );
bool StartProcessingPacket( CNetPacket *packet );
bool ProcessPacket( CNetPacket *packet );
void EndProcessingPacket( CNetPacket *packet );
bool CanSendPacket( void ) const;
void SetChoked( void ); // choke a packet
bool HasPendingReliableData( void );
// Queues data for sending:
// send a net message
bool AddNetMsg( INetworkMessage *msg, bool bForceReliable = false );
// send a chunk of data
bool AddData( bf_write &msg, bool bReliable = true );
// Puts data onto the wire:
int SendDatagram( bf_write *data ); // Adds data to unreliable payload and then calls transmits the data
bool Transmit( bool onlyReliable = false ); // send data from buffers (calls SendDataGram( NULL ) )
bool IsOverflowed( void ) const;
bool IsTimedOut( void ) const;
bool IsTimingOut() const;
// Info:
const char *GetName( void ) const;
const char *GetAddress( void ) const;
float GetTimeConnected( void ) const;
float GetTimeSinceLastReceived( void ) const;
int GetDataRate( void ) const;
float GetLatency( int flow ) const;
float GetAvgLatency( int flow ) const;
float GetAvgLoss( int flow ) const;
float GetAvgData( int flow ) const;
float GetAvgChoke( int flow ) const;
float GetAvgPackets( int flow ) const;
int GetTotalData( int flow ) const;
void SetConnectionState( ConnectionStatus_t state );
private:
int ProcessPacketHeader( bf_read &buf );
bool ProcessControlMessage( int cmd, bf_read &buf );
bool ProcessMessages( bf_read &buf );
ConnectionStatus_t m_ConnectionState;
// last send outgoing sequence number
int m_nOutSequenceNr;
// last received incoming sequnec number
int m_nInSequenceNr;
// last received acknowledge outgoing sequnce number
int m_nOutSequenceNrAck;
// state of outgoing reliable data (0/1) flip flop used for loss detection
int m_nOutReliableState;
// state of incoming reliable data
int m_nInReliableState;
int m_nChokedPackets; //number of choked packets
int m_PacketDrop;
// Reliable data buffer, send wich each packet (or put in waiting list)
bf_write m_StreamReliable;
byte m_ReliableDataBuffer[8 * 1024]; // In SP, we don't need much reliable buffer, so save the memory (this is mostly for xbox).
CUtlVector<byte> m_ReliableDataBufferMP;
// unreliable message buffer, cleared wich each packet
bf_write m_StreamUnreliable;
byte m_UnreliableDataBuffer[NET_MAX_DATAGRAM_PAYLOAD];
// don't use any vars below this (only in net_ws.cpp)
CUDPSocket *m_pSocket; // NS_SERVER or NS_CLIENT index, depending on channel.
int m_StreamSocket; // TCP socket handle
unsigned int m_MaxReliablePayloadSize; // max size of reliable payload in a single packet
// Address this channel is talking to.
netadr_t remote_address;
// For timeouts. Time last message was received.
float last_received;
// Time when channel was connected.
float connect_time;
// Bandwidth choke
// Bytes per second
int m_Rate;
// If realtime > cleartime, free to send next packet
float m_fClearTime;
float m_Timeout; // in seconds
char m_Name[32]; // channel name
// packet history
// netflow_t m_DataFlow[ MAX_FLOWS ];
INetworkMessageHandler *m_MessageHandler; // who registers and processes messages
};
#endif // NETCHANNEL_H
|