SLikeNet  0.1.3
 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"
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;
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 
56 {
61 };
62 
63 typedef int RNS2SendResult;
64 
66 {
76 };
77 
79 {
81  char *data;
82  int length;
84  int ttl;
85 };
86 
88 {
89 
90 
91 
93 
94  int bytesRead;
98 };
99 
101 {
102 public:
103  static RakNetSocket2* AllocRNS2(void);
104  static void DeallocRNS2(RakNetSocket2 *s);
105 };
106 
108 {
109 public:
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 
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:
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:
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;
261  SimpleMutex bufferedSendsMutex;
262 };
263 #else // defined(WINDOWS_STORE_RT)
264 
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
280 };
281 
282 // Every platform except Windows Store 8 can use the Berkley sockets interface
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
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 
327 
328  unsigned RecvFromLoopInt(void);
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__)
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
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