SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
socket2.h
Go to the documentation of this file.
1 /*
2 * Original work: Copyright (c) 2014, Oculus VR, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7 * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8 *
9 *
10 * Modified work: Copyright (c) 2016-2017, SLikeSoft UG (haftungsbeschränkt)
11 *
12 * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13 * license found in the license.txt file in the root directory of this source tree.
14 */
15
16 #ifndef __RAKNET_SOCKET_2_H
17 #define __RAKNET_SOCKET_2_H
18
19 #include "types.h"
20 #include "MTUSize.h"
21 #include "LocklessTypes.h"
22 #include "thread.h"
23 #include "DS_ThreadsafeAllocatingQueue.h"
24 #include "Export.h"
25
26 // For CFSocket
27 // https://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFSocketRef/Reference/reference.html
28 // Reason: http://sourceforge.net/p/open-dis/discussion/683284/thread/0929d6a0
29 #if defined(__APPLE__)
30 #import <CoreFoundation/CoreFoundation.h>
31 #include <sys/socket.h>
32 #include <netinet/in.h>
33 #endif
34
35 // #define TEST_NATIVE_CLIENT_ON_WINDOWS
36
37 #ifdef TEST_NATIVE_CLIENT_ON_WINDOWS
38 #define __native_client__
39 typedef int PP_Resource;
40 #endif
41
42 namespace SLNet
43 {
44
45 class RakNetSocket2;
46 struct RNS2_BerkleyBindParameters;
47 struct RNS2_SendParameters;
48 #ifdef WIN32
49 typedef SOCKET RNS2Socket;
50 #else
51 // #low determine whether we cannot use SOCKET on all platforms...
52 typedef int RNS2Socket;
53 #endif
54
55 enum RNS2BindResult
56 {
57 BR_SUCCESS,
58 BR_REQUIRES_RAKNET_SUPPORT_IPV6_DEFINE,
59 BR_FAILED_TO_BIND_SOCKET,
60 BR_FAILED_SEND_TEST,
61 };
62
63 typedef int RNS2SendResult;
64
65 enum RNS2Type
66 {
67 RNS2T_WINDOWS_STORE_8,
68 RNS2T_PS3,
69 RNS2T_PS4,
70 RNS2T_CHROME,
71 RNS2T_VITA,
72 RNS2T_XBOX_360,
73 RNS2T_XBOX_720,
74 RNS2T_WINDOWS,
75 RNS2T_LINUX
76 };
77
78 struct RNS2_SendParameters
79 {
80 RNS2_SendParameters() {ttl=0;}
81 char *data;
82 int length;
83 SystemAddress systemAddress;
84 int ttl;
85 };
86
87 struct RNS2RecvStruct
88 {
89
90
91
92 char data[MAXIMUM_MTU_SIZE];
93
94 int bytesRead;
95 SystemAddress systemAddress;
96 SLNet::TimeUS timeRead;
97 RakNetSocket2 *socket;
98 };
99
100 class RakNetSocket2Allocator
101 {
102 public:
103 static RakNetSocket2* AllocRNS2(void);
104 static void DeallocRNS2(RakNetSocket2 *s);
105 };
106
107 class RAK_DLL_EXPORT RNS2EventHandler
108 {
109 public:
110 RNS2EventHandler() {}
111 virtual ~RNS2EventHandler() {}
112
113 // bufferedPackets.Push(recvFromStruct);
114 // quitAndDataEvents.SetEvent();
115 virtual void OnRNS2Recv(RNS2RecvStruct *recvStruct)=0;
116 virtual void DeallocRNS2RecvStruct(RNS2RecvStruct *s, const char *file, unsigned int line)=0;
117 virtual RNS2RecvStruct *AllocRNS2RecvStruct(const char *file, unsigned int line)=0;
118
119 // recvFromStruct=bufferedPackets.Allocate( _FILE_AND_LINE_ );
120 // DataStructures::ThreadsafeAllocatingQueue<RNS2RecvStruct> bufferedPackets;
121 };
122
123 class RakNetSocket2
124 {
125 public:
126 RakNetSocket2();
127 virtual ~RakNetSocket2();
128
129 // In order for the handler to trigger, some platforms must call PollRecvFrom, some platforms this create an internal thread.
130 void SetRecvEventHandler(RNS2EventHandler *_eventHandler);
131 virtual RNS2SendResult Send( RNS2_SendParameters *sendParameters, const char *file, unsigned int line )=0;
132 RNS2Type GetSocketType(void) const;
133 void SetSocketType(RNS2Type t);
134 bool IsBerkleySocket(void) const;
135 SystemAddress GetBoundAddress(void) const;
136 unsigned int GetUserConnectionSocketIndex(void) const;
137 void SetUserConnectionSocketIndex(unsigned int i);
138 RNS2EventHandler * GetEventHandler(void) const;
139
140 // ----------- STATICS ------------
141 static void GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
142 static void DomainNameToIP( const char *domainName, char ip[65] );
143
144 protected:
145 RNS2EventHandler *eventHandler;
146 RNS2Type socketType;
147 SystemAddress boundAddress;
148 unsigned int userConnectionSocketIndex;
149 };
150
151 #if defined(WINDOWS_STORE_RT)
152
153 ref class ListenerContext;
154
155 // #include <collection.h>
156 //#include <map>
157 #include "DS_List.h"
158 class RNS2_WindowsStore8 : public RakNetSocket2
159 {
160 public:
161 RNS2_WindowsStore8();
162 ~RNS2_WindowsStore8();
163
164 virtual RNS2SendResult Send( RNS2_SendParameters *sendParameters, const char *file, unsigned int line );
165 RNS2BindResult Bind( Platform::String ^localServiceName );
166 // ----------- STATICS ------------
167 static void GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
168 static void DomainNameToIP( const char *domainName, char ip[65] );
169
170 static int WinRTInet_Addr(const char * cp);
171
172 static int WinRTSetSockOpt(Windows::Networking::Sockets::DatagramSocket ^s,
173 int level,
174 int optname,
175 const char * optval,
176 socklen_t optlen);
177
178 static int WinRTIOCTLSocket(Windows::Networking::Sockets::DatagramSocket ^s,
179 long cmd,
180 unsigned long *argp);
181
182 static int WinRTGetSockName(Windows::Networking::Sockets::DatagramSocket ^s,
183 struct sockaddr *name,
184 socklen_t* namelen);
185
186 static RNS2_WindowsStore8 *GetRNS2FromDatagramSocket(Windows::Networking::Sockets::DatagramSocket^ s);
187 protected:
188 static DataStructures::List<RNS2_WindowsStore8*> rns2List;
189 static SimpleMutex rns2ListMutex;
190
191 Windows::Networking::Sockets::DatagramSocket^ listener;
192 // Platform::Collections::Map<Windows::Storage::Streams::IOutputStream> ^outputStreamMap;
193 // Platform::Collections::Map<String^, int>^ m;
194 //std::map<> m;
195 ListenerContext^ listenerContext;
196 };
197 #elif defined(__native_client__)
198 struct NativeClientBindParameters
199 {
200 _PP_Instance_ nativeClientInstance;
201 unsigned short port;
202 const char *forceHostAddress;
203 bool is_ipv6;
204 RNS2EventHandler *eventHandler;
205 };
206 class RNS2_NativeClient;
207 struct RNS2_SendParameters_NativeClient : public RNS2_SendParameters
208 {
209 RNS2_NativeClient *socket2;
210 };
211 class RNS2_NativeClient : public RakNetSocket2
212 {
213 public:
214 RNS2_NativeClient();
215 virtual ~RNS2_NativeClient();
216 RNS2BindResult Bind( NativeClientBindParameters *bindParameters, const char *file, unsigned int line );
217 RNS2SendResult Send( RNS2_SendParameters *sendParameters, const char *file, unsigned int line );
218 const NativeClientBindParameters *GetBindings(void) const;
219
220 // ----------- STATICS ------------
221 static bool IsPortInUse(unsigned short port, const char *hostAddress, unsigned short addressFamily, int type );
222 static void GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
223
224 // RNS2_NativeClient doesn't automatically call recvfrom in a thread - user must call Update() from the main thread
225 // This causes buffered sends to send, until send is asynch pending
226 // It causes recvfrom events to trigger the callback, and push a message to the event handler
227 //
228 // Example:
229 //
230 // DataStructures::List< SLNet::RakNetSocket2* > sockets;
231 // rakPeerInterface->GetSockets(sockets);
232 // for (unsigned int i=0; i < sockets.Size(); i++)
233 // {
234 // ((RNS2_NativeClient*)sockets[i])->Update();
235 // }
236
237 void Update(void);
238 protected:
239 void ProcessBufferedSend(void);
240 static void SendImmediate(RNS2_SendParameters_NativeClient *sp);
241 static void DeallocSP(RNS2_SendParameters_NativeClient *sp);
242 static RNS2_SendParameters_NativeClient* CloneSP(RNS2_SendParameters *sp, RNS2_NativeClient *socket2, const char *file, unsigned int line);
243 static void onRecvFrom(void* pData, int32_t dataSize);
244 void IssueReceiveCall(void);
245 static void onSocketBound(void* pData, int32_t dataSize);
246 static void onSendTo(void* pData, int32_t dataSize);
247 void BufferSend( RNS2_SendParameters *sendParameters, const char *file, unsigned int line );
248 PP_Resource rns2Socket;
249 NativeClientBindParameters binding;
250 bool sendInProgress;
251 SimpleMutex sendInProgressMutex;
252
253 enum BindState
254 {
255 BS_UNBOUND,
256 BS_IN_PROGRESS,
257 BS_BOUND,
258 BS_FAILED
259 } bindState;
260 DataStructures::Queue<RNS2_SendParameters_NativeClient*> bufferedSends;
261 SimpleMutex bufferedSendsMutex;
262 };
263 #else // defined(WINDOWS_STORE_RT)
264
265 struct RNS2_BerkleyBindParameters
266 {
267 // Input parameters
268 unsigned short port;
269 char *hostAddress;
270 unsigned short addressFamily; // AF_INET or AF_INET6
271 int type; // SOCK_DGRAM
272 int protocol; // 0
273 bool nonBlockingSocket;
274 int setBroadcast;
275 int setIPHdrIncl;
276 int doNotFragment;
277 int pollingThreadPriority;
278 RNS2EventHandler *eventHandler;
279 unsigned short remotePortRakNetWasStartedOn_PS3_PS4_PSP2;
280 };
281
282 // Every platform except Windows Store 8 can use the Berkley sockets interface
283 class IRNS2_Berkley : public RakNetSocket2
284 {
285 public:
286 // ----------- STATICS ------------
287 // For addressFamily, use AF_INET
288 // For type, use SOCK_DGRAM
289 static bool IsPortInUse(unsigned short port, const char *hostAddress, unsigned short addressFamily, int type );
290
291 // ----------- MEMBERS ------------
292 virtual RNS2BindResult Bind( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line )=0;
293 };
294 // Every platform that uses Berkley sockets, except native client, can compile some common functions
295 class RNS2_Berkley : public IRNS2_Berkley
296 {
297 public:
298 RNS2_Berkley();
299 virtual ~RNS2_Berkley();
300 int CreateRecvPollingThread(int threadPriority);
301 void SignalStopRecvPollingThread(void);
302 void BlockOnStopRecvPollingThread(void);
303 const RNS2_BerkleyBindParameters *GetBindings(void) const;
304 RNS2Socket GetSocket(void) const;
305 void SetDoNotFragment( int opt );
306
307 protected:
308 // Used by other classes
309 RNS2BindResult BindShared( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line );
310 RNS2BindResult BindSharedIPV4( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line );
311 RNS2BindResult BindSharedIPV4And6( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line );
312
313 static void GetSystemAddressIPV4 ( RNS2Socket rns2Socket, SystemAddress *systemAddressOut );
314 static void GetSystemAddressIPV4And6 ( RNS2Socket rns2Socket, SystemAddress *systemAddressOut );
315
316 // Internal
317 void SetNonBlockingSocket(unsigned long nonblocking);
318 void SetSocketOptions(void);
319 void SetBroadcastSocket(int broadcast);
320 void SetIPHdrIncl(int ipHdrIncl);
321 void RecvFromBlocking(RNS2RecvStruct *recvFromStruct);
322 void RecvFromBlockingIPV4(RNS2RecvStruct *recvFromStruct);
323 void RecvFromBlockingIPV4And6(RNS2RecvStruct *recvFromStruct);
324
325 RNS2Socket rns2Socket;
326 RNS2_BerkleyBindParameters binding;
327
328 unsigned RecvFromLoopInt(void);
329 SLNet::LocklessUint32_t isRecvFromLoopThreadActive;
330 volatile bool endThreads;
331 // Constructor not called!
332
333 #if defined(__APPLE__)
334 // http://sourceforge.net/p/open-dis/discussion/683284/thread/0929d6a0
335 CFSocketRef _cfSocket;
336 #endif
337
338 static RAK_THREAD_DECLARATION(RecvFromLoop);
339 };
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357 #if defined(_WIN32) || defined(__GNUC__) || defined(__GCCXML__) || defined(__S3E__)
358 class RNS2_Windows_Linux_360
359 {
360 public:
361 protected:
362 static RNS2SendResult Send_Windows_Linux_360NoVDP( RNS2Socket rns2Socket, RNS2_SendParameters *sendParameters, const char *file, unsigned int line );
363 };
364 #endif
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410 #if defined(_WIN32)
411
412 class RAK_DLL_EXPORT SocketLayerOverride
413 {
414 public:
415 SocketLayerOverride() {}
416 virtual ~SocketLayerOverride() {}
417
419 virtual int RakNetSendTo( const char *data, int length, const SystemAddress &systemAddress )=0;
420
422 // Return -1 to use RakNet's normal recvfrom, 0 to abort RakNet's normal recvfrom, and positive to return data
423 virtual int RakNetRecvFrom( char dataOut[ MAXIMUM_MTU_SIZE ], SystemAddress *senderOut, bool calledFromMainThread )=0;
424 };
425
426 class RNS2_Windows : public RNS2_Berkley, public RNS2_Windows_Linux_360
427 {
428 public:
429 RNS2_Windows();
430 virtual ~RNS2_Windows();
431 RNS2BindResult Bind( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line );
432 RNS2SendResult Send( RNS2_SendParameters *sendParameters, const char *file, unsigned int line );
433 void SetSocketLayerOverride(SocketLayerOverride *_slo);
434 SocketLayerOverride* GetSocketLayerOverride(void);
435 // ----------- STATICS ------------
436 static void GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
437 protected:
438 static void GetMyIPIPV4( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
439 static void GetMyIPIPV4And6( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
440 SocketLayerOverride *slo;
441 };
442
443 #else
444 class RNS2_Linux : public RNS2_Berkley, public RNS2_Windows_Linux_360
445 {
446 public:
447 RNS2BindResult Bind( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line );
448 RNS2SendResult Send( RNS2_SendParameters *sendParameters, const char *file, unsigned int line );
449
450 // ----------- STATICS ------------
451 static void GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
452 protected:
453 static void GetMyIPIPV4( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
454 static void GetMyIPIPV4And6( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
455 };
456
457 #endif // Linux
458
459 #endif // #elif !defined(WINDOWS_STORE_RT)
460
461 } // namespace SLNet
462
463 #endif // __RAKNET_SOCKET_2_H