forked from facebookarchive/RakNet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUDPForwarder.h
159 lines (128 loc) · 5.05 KB
/
UDPForwarder.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
/*
* Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
/// \file
/// \brief Forwards UDP datagrams. Independent of RakNet's protocol.
///
#include "NativeFeatureIncludes.h"
#if _RAKNET_SUPPORT_UDPForwarder==1
#ifndef __UDP_FORWARDER_H
#define __UDP_FORWARDER_H
#include "Export.h"
#include "RakNetTypes.h"
#include "SocketIncludes.h"
#include "UDPProxyCommon.h"
#include "SimpleMutex.h"
#include "RakString.h"
#include "RakThread.h"
#include "DS_Queue.h"
#include "DS_OrderedList.h"
#include "LocklessTypes.h"
#include "DS_ThreadsafeAllocatingQueue.h"
namespace RakNet
{
enum UDPForwarderResult
{
UDPFORWARDER_FORWARDING_ALREADY_EXISTS,
UDPFORWARDER_NO_SOCKETS,
UDPFORWARDER_BIND_FAILED,
UDPFORWARDER_INVALID_PARAMETERS,
UDPFORWARDER_NOT_RUNNING,
UDPFORWARDER_SUCCESS,
UDPFORWARDER_RESULT_COUNT
};
/// \brief Forwards UDP datagrams. Independent of RakNet's protocol.
/// \ingroup NAT_PUNCHTHROUGH_GROUP
class RAK_DLL_EXPORT UDPForwarder
{
public:
UDPForwarder();
virtual ~UDPForwarder();
/// Starts the system.
/// Required to call before StartForwarding
void Startup(void);
/// Stops the system, and frees all sockets
void Shutdown(void);
/// Sets the maximum number of forwarding entries allowed
/// Set according to your available bandwidth and the estimated average bandwidth per forwarded address.
/// \param[in] maxEntries The maximum number of simultaneous forwarding entries. Defaults to 64 (32 connections)
void SetMaxForwardEntries(unsigned short maxEntries);
/// \return The \a maxEntries parameter passed to SetMaxForwardEntries(), or the default if it was never called
int GetMaxForwardEntries(void) const;
/// \return How many entries have been used
int GetUsedForwardEntries(void) const;
/// Forwards datagrams from source to destination, and vice-versa
/// Does nothing if this forward entry already exists via a previous call
/// \pre Call Startup()
/// \note RakNet's protocol will ensure a message is sent at least every 15 seconds, so if routing RakNet messages, it is a reasonable value for timeoutOnNoDataMS, plus an some extra seconds for latency
/// \param[in] source The source IP and port
/// \param[in] destination Where to forward to (and vice-versa)
/// \param[in] timeoutOnNoDataMS If no messages are forwarded for this many MS, then automatically remove this entry.
/// \param[in] forceHostAddress Force binding on a particular address. 0 to use any.
/// \param[in] socketFamily IP version: For IPV4, use AF_INET (default). For IPV6, use AF_INET6. To autoselect, use AF_UNSPEC.
/// \param[out] forwardingPort New opened port for forwarding
/// \param[out] forwardingSocket New opened socket for forwarding
/// \return UDPForwarderResult
UDPForwarderResult StartForwarding(
SystemAddress source, SystemAddress destination, RakNet::TimeMS timeoutOnNoDataMS,
const char *forceHostAddress, unsigned short socketFamily,
unsigned short *forwardingPort, __UDPSOCKET__ *forwardingSocket);
/// No longer forward datagrams from source to destination
/// \param[in] source The source IP and port
/// \param[in] destination Where to forward to
void StopForwarding(SystemAddress source, SystemAddress destination);
struct ForwardEntry
{
ForwardEntry();
~ForwardEntry();
SystemAddress addr1Unconfirmed, addr2Unconfirmed, addr1Confirmed, addr2Confirmed;
RakNet::TimeMS timeLastDatagramForwarded;
__UDPSOCKET__ socket;
RakNet::TimeMS timeoutOnNoDataMS;
short socketFamily;
};
protected:
friend RAK_THREAD_DECLARATION(UpdateUDPForwarderGlobal);
void UpdateUDPForwarder(void);
void RecvFrom(RakNet::TimeMS curTime, ForwardEntry *forwardEntry);
struct StartForwardingInputStruct
{
SystemAddress source;
SystemAddress destination;
RakNet::TimeMS timeoutOnNoDataMS;
RakString forceHostAddress;
unsigned short socketFamily;
unsigned int inputId;
};
DataStructures::ThreadsafeAllocatingQueue<StartForwardingInputStruct> startForwardingInput;
struct StartForwardingOutputStruct
{
unsigned short forwardingPort;
__UDPSOCKET__ forwardingSocket;
UDPForwarderResult result;
unsigned int inputId;
};
DataStructures::Queue<StartForwardingOutputStruct> startForwardingOutput;
SimpleMutex startForwardingOutputMutex;
struct StopForwardingStruct
{
SystemAddress source;
SystemAddress destination;
};
DataStructures::ThreadsafeAllocatingQueue<StopForwardingStruct> stopForwardingCommands;
unsigned int nextInputId;
// New entries are added to forwardListNotUpdated
DataStructures::List<ForwardEntry*> forwardListNotUpdated;
// SimpleMutex forwardListNotUpdatedMutex;
unsigned short maxForwardEntries;
RakNet::LocklessUint32_t isRunning, threadRunning;
};
} // End namespace
#endif
#endif // #if _RAKNET_SUPPORT_UDPForwarder==1