forked from sears2424/Source-PlusPlus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathiphelpers.h
162 lines (114 loc) · 4.33 KB
/
iphelpers.h
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
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef IPHELPERS_H
#define IPHELPERS_H
#include "ichannel.h"
// Loops that poll sockets should Sleep for this amount of time between iterations
// so they don't hog all the CPU.
#define LOOP_POLL_INTERVAL 5
// Useful for putting the arguments into a printf statement.
#define EXPAND_ADDR( x ) (x).ip[0], (x).ip[1], (x).ip[2], (x).ip[3], (x).port
// This is a simple wrapper layer for UDP sockets.
class CIPAddr
{
public:
CIPAddr();
CIPAddr( const int inputIP[4], const int inputPort );
CIPAddr( int ip0, int ip1, int ip2, int ip3, int ipPort );
void Init( int ip0, int ip1, int ip2, int ip3, int ipPort );
bool operator==( const CIPAddr &o ) const;
bool operator!=( const CIPAddr &o ) const;
// Setup to send to the local machine on the specified port.
void SetupLocal( int inPort );
public:
unsigned char ip[4];
unsigned short port;
};
// The chunk walker provides an easy way to copy data out of the chunks as though it were a
// single contiguous chunk of memory.s
class CChunkWalker
{
public:
CChunkWalker( void const * const *pChunks, const int *pChunkLengths, int nChunks );
int GetTotalLength() const;
void CopyTo( void *pOut, int nBytes );
private:
void const * const *m_pChunks;
const int *m_pChunkLengths;
int m_nChunks;
int m_iCurChunk;
int m_iCurChunkPos;
int m_TotalLength;
};
// This class makes loop that wait on something look nicer. ALL loops using this class
// should follow this pattern, or they can wind up with unforeseen delays that add a whole
// lot of lag.
//
// CWaitTimer waitTimer( 5.0 );
// while ( 1 )
// {
// do your thing here like Recv() from a socket.
//
// if ( waitTimer.ShouldKeepWaiting() )
// Sleep() for some time interval like 5ms so you don't hog the CPU
// else
// BREAK HERE
// }
class CWaitTimer
{
public:
CWaitTimer( double flSeconds );
bool ShouldKeepWaiting();
private:
unsigned long m_StartTime;
unsigned long m_WaitMS;
};
// Helper function to get time in milliseconds.
unsigned long SampleMilliseconds();
class ISocket
{
public:
// Call this when you're done.
virtual void Release() = 0;
// Bind the socket so you can send and receive with it.
// If you bind to port 0, then the system will select the port for you.
virtual bool Bind( const CIPAddr *pAddr ) = 0;
virtual bool BindToAny( const unsigned short port ) = 0;
// Broadcast some data.
virtual bool Broadcast( const void *pData, const int len, const unsigned short port ) = 0;
// Send a packet.
virtual bool SendTo( const CIPAddr *pAddr, const void *pData, const int len ) = 0;
virtual bool SendChunksTo( const CIPAddr *pAddr, void const * const *pChunks, const int *pChunkLengths, int nChunks ) = 0;
// Receive a packet. Returns the length received or -1 if no data came in.
// If pFrom is set, then it is filled in with the sender's IP address.
virtual int RecvFrom( void *pData, int maxDataLen, CIPAddr *pFrom ) = 0;
// How long has it been since we successfully received a packet?
virtual double GetRecvTimeout() = 0;
};
// Create a connectionless socket that you can send packets out of.
ISocket* CreateIPSocket();
// This sets up the socket to receive multicast data on the specified group.
// By default, localInterface is INADDR_ANY, but if you want to specify a specific interface
// the data should come in through, you can.
ISocket* CreateMulticastListenSocket(
const CIPAddr &addr,
const CIPAddr &localInterface = CIPAddr()
);
// Setup a CIPAddr from the string. The string can be a dotted IP address or
// a hostname, and it can be followed by a colon and a port number like "1.2.3.4:3443"
// or "myhostname.valvesoftware.com:2342".
//
// Note: if the string does not contain a port, then pOut->port will be left alone.
bool ConvertStringToIPAddr( const char *pStr, CIPAddr *pOut );
// Do a DNS lookup on the IP.
// You can optionally get a service name back too.
bool ConvertIPAddrToString( const CIPAddr *pIn, char *pOut, int outLen );
void IP_GetLastErrorString( char *pStr, int maxLen );
void SockAddrToIPAddr( const struct sockaddr_in *pIn, CIPAddr *pOut );
void IPAddrToSockAddr( const CIPAddr *pIn, struct sockaddr_in *pOut );
#endif