RakNetSocket2.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. /*
  2. * 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. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. #ifndef __RAKNET_SOCKET_2_H
  11. #define __RAKNET_SOCKET_2_H
  12. #include "RakNetTypes.h"
  13. #include "MTUSize.h"
  14. #include "LocklessTypes.h"
  15. #include "RakThread.h"
  16. #include "DS_ThreadsafeAllocatingQueue.h"
  17. #include "Export.h"
  18. // For CFSocket
  19. // https://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFSocketRef/Reference/reference.html
  20. // Reason: http://sourceforge.net/p/open-dis/discussion/683284/thread/0929d6a0
  21. #if defined(__APPLE__)
  22. #import <CoreFoundation/CoreFoundation.h>
  23. #include <sys/socket.h>
  24. #include <netinet/in.h>
  25. #endif
  26. // #define TEST_NATIVE_CLIENT_ON_WINDOWS
  27. #ifdef TEST_NATIVE_CLIENT_ON_WINDOWS
  28. #define __native_client__
  29. typedef int PP_Resource;
  30. #endif
  31. namespace RakNet
  32. {
  33. class RakNetSocket2;
  34. struct RNS2_BerkleyBindParameters;
  35. struct RNS2_SendParameters;
  36. typedef int RNS2Socket;
  37. enum RNS2BindResult
  38. {
  39. BR_SUCCESS,
  40. BR_REQUIRES_RAKNET_SUPPORT_IPV6_DEFINE,
  41. BR_FAILED_TO_BIND_SOCKET,
  42. BR_FAILED_SEND_TEST,
  43. };
  44. typedef int RNS2SendResult;
  45. enum RNS2Type
  46. {
  47. RNS2T_WINDOWS_STORE_8,
  48. RNS2T_PS3,
  49. RNS2T_PS4,
  50. RNS2T_CHROME,
  51. RNS2T_VITA,
  52. RNS2T_XBOX_360,
  53. RNS2T_XBOX_720,
  54. RNS2T_WINDOWS,
  55. RNS2T_LINUX
  56. };
  57. struct RNS2_SendParameters
  58. {
  59. RNS2_SendParameters() {ttl=0;}
  60. char *data;
  61. int length;
  62. SystemAddress systemAddress;
  63. int ttl;
  64. };
  65. struct RNS2RecvStruct
  66. {
  67. char data[MAXIMUM_MTU_SIZE];
  68. int bytesRead;
  69. SystemAddress systemAddress;
  70. RakNet::TimeUS timeRead;
  71. RakNetSocket2 *socket;
  72. };
  73. class RakNetSocket2Allocator
  74. {
  75. public:
  76. static RakNetSocket2* AllocRNS2(void);
  77. static void DeallocRNS2(RakNetSocket2 *s);
  78. };
  79. class RAK_DLL_EXPORT RNS2EventHandler
  80. {
  81. public:
  82. RNS2EventHandler() {}
  83. virtual ~RNS2EventHandler() {}
  84. // bufferedPackets.Push(recvFromStruct);
  85. // quitAndDataEvents.SetEvent();
  86. virtual void OnRNS2Recv(RNS2RecvStruct *recvStruct)=0;
  87. virtual void DeallocRNS2RecvStruct(RNS2RecvStruct *s, const char *file, unsigned int line)=0;
  88. virtual RNS2RecvStruct *AllocRNS2RecvStruct(const char *file, unsigned int line)=0;
  89. // recvFromStruct=bufferedPackets.Allocate( _FILE_AND_LINE_ );
  90. // DataStructures::ThreadsafeAllocatingQueue<RNS2RecvStruct> bufferedPackets;
  91. };
  92. class RakNetSocket2
  93. {
  94. public:
  95. RakNetSocket2();
  96. virtual ~RakNetSocket2();
  97. // In order for the handler to trigger, some platforms must call PollRecvFrom, some platforms this create an internal thread.
  98. void SetRecvEventHandler(RNS2EventHandler *_eventHandler);
  99. virtual RNS2SendResult Send( RNS2_SendParameters *sendParameters, const char *file, unsigned int line )=0;
  100. RNS2Type GetSocketType(void) const;
  101. void SetSocketType(RNS2Type t);
  102. bool IsBerkleySocket(void) const;
  103. SystemAddress GetBoundAddress(void) const;
  104. unsigned int GetUserConnectionSocketIndex(void) const;
  105. void SetUserConnectionSocketIndex(unsigned int i);
  106. RNS2EventHandler * GetEventHandler(void) const;
  107. // ----------- STATICS ------------
  108. static void GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
  109. static void DomainNameToIP( const char *domainName, char ip[65] );
  110. protected:
  111. RNS2EventHandler *eventHandler;
  112. RNS2Type socketType;
  113. SystemAddress boundAddress;
  114. unsigned int userConnectionSocketIndex;
  115. };
  116. #if defined(WINDOWS_STORE_RT)
  117. ref class ListenerContext;
  118. // #include <collection.h>
  119. //#include <map>
  120. #include "DS_List.h"
  121. class RNS2_WindowsStore8 : public RakNetSocket2
  122. {
  123. public:
  124. RNS2_WindowsStore8();
  125. ~RNS2_WindowsStore8();
  126. virtual RNS2SendResult Send( RNS2_SendParameters *sendParameters, const char *file, unsigned int line );
  127. RNS2BindResult Bind( Platform::String ^localServiceName );
  128. // ----------- STATICS ------------
  129. static void GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
  130. static void DomainNameToIP( const char *domainName, char ip[65] );
  131. static int WinRTInet_Addr(const char * cp);
  132. static int WinRTSetSockOpt(Windows::Networking::Sockets::DatagramSocket ^s,
  133. int level,
  134. int optname,
  135. const char * optval,
  136. socklen_t optlen);
  137. static int WinRTIOCTLSocket(Windows::Networking::Sockets::DatagramSocket ^s,
  138. long cmd,
  139. unsigned long *argp);
  140. static int WinRTGetSockName(Windows::Networking::Sockets::DatagramSocket ^s,
  141. struct sockaddr *name,
  142. socklen_t* namelen);
  143. static RNS2_WindowsStore8 *GetRNS2FromDatagramSocket(Windows::Networking::Sockets::DatagramSocket^ s);
  144. protected:
  145. static DataStructures::List<RNS2_WindowsStore8*> rns2List;
  146. static SimpleMutex rns2ListMutex;
  147. Windows::Networking::Sockets::DatagramSocket^ listener;
  148. // Platform::Collections::Map<Windows::Storage::Streams::IOutputStream> ^outputStreamMap;
  149. // Platform::Collections::Map<String^, int>^ m;
  150. //std::map<> m;
  151. ListenerContext^ listenerContext;
  152. };
  153. #elif defined(__native_client__)
  154. struct NativeClientBindParameters
  155. {
  156. _PP_Instance_ nativeClientInstance;
  157. unsigned short port;
  158. const char *forceHostAddress;
  159. bool is_ipv6;
  160. RNS2EventHandler *eventHandler;
  161. };
  162. class RNS2_NativeClient;
  163. struct RNS2_SendParameters_NativeClient : public RNS2_SendParameters
  164. {
  165. RNS2_NativeClient *socket2;
  166. };
  167. class RNS2_NativeClient : public RakNetSocket2
  168. {
  169. public:
  170. RNS2_NativeClient();
  171. virtual ~RNS2_NativeClient();
  172. RNS2BindResult Bind( NativeClientBindParameters *bindParameters, const char *file, unsigned int line );
  173. RNS2SendResult Send( RNS2_SendParameters *sendParameters, const char *file, unsigned int line );
  174. const NativeClientBindParameters *GetBindings(void) const;
  175. // ----------- STATICS ------------
  176. static bool IsPortInUse(unsigned short port, const char *hostAddress, unsigned short addressFamily, int type );
  177. static void GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
  178. // RNS2_NativeClient doesn't automatically call recvfrom in a thread - user must call Update() from the main thread
  179. // This causes buffered sends to send, until send is asynch pending
  180. // It causes recvfrom events to trigger the callback, and push a message to the event handler
  181. //
  182. // Example:
  183. //
  184. // DataStructures::List< RakNet::RakNetSocket2* > sockets;
  185. // rakPeerInterface->GetSockets(sockets);
  186. // for (unsigned int i=0; i < sockets.Size(); i++)
  187. // {
  188. // ((RNS2_NativeClient*)sockets[i])->Update();
  189. // }
  190. void Update(void);
  191. protected:
  192. void ProcessBufferedSend(void);
  193. static void SendImmediate(RNS2_SendParameters_NativeClient *sp);
  194. static void DeallocSP(RNS2_SendParameters_NativeClient *sp);
  195. static RNS2_SendParameters_NativeClient* CloneSP(RNS2_SendParameters *sp, RNS2_NativeClient *socket2, const char *file, unsigned int line);
  196. static void onRecvFrom(void* pData, int32_t dataSize);
  197. void IssueReceiveCall(void);
  198. static void onSocketBound(void* pData, int32_t dataSize);
  199. static void onSendTo(void* pData, int32_t dataSize);
  200. void BufferSend( RNS2_SendParameters *sendParameters, const char *file, unsigned int line );
  201. PP_Resource rns2Socket;
  202. NativeClientBindParameters binding;
  203. bool sendInProgress;
  204. SimpleMutex sendInProgressMutex;
  205. enum BindState
  206. {
  207. BS_UNBOUND,
  208. BS_IN_PROGRESS,
  209. BS_BOUND,
  210. BS_FAILED
  211. } bindState;
  212. DataStructures::Queue<RNS2_SendParameters_NativeClient*> bufferedSends;
  213. SimpleMutex bufferedSendsMutex;
  214. };
  215. #else // defined(WINDOWS_STORE_RT)
  216. struct RNS2_BerkleyBindParameters
  217. {
  218. // Input parameters
  219. unsigned short port;
  220. char *hostAddress;
  221. unsigned short addressFamily; // AF_INET or AF_INET6
  222. int type; // SOCK_DGRAM
  223. int protocol; // 0
  224. bool nonBlockingSocket;
  225. int setBroadcast;
  226. int setIPHdrIncl;
  227. int doNotFragment;
  228. int pollingThreadPriority;
  229. RNS2EventHandler *eventHandler;
  230. unsigned short remotePortRakNetWasStartedOn_PS3_PS4_PSP2;
  231. };
  232. // Every platform except Windows Store 8 can use the Berkley sockets interface
  233. class IRNS2_Berkley : public RakNetSocket2
  234. {
  235. public:
  236. // ----------- STATICS ------------
  237. // For addressFamily, use AF_INET
  238. // For type, use SOCK_DGRAM
  239. static bool IsPortInUse(unsigned short port, const char *hostAddress, unsigned short addressFamily, int type );
  240. // ----------- MEMBERS ------------
  241. virtual RNS2BindResult Bind( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line )=0;
  242. };
  243. // Every platform that uses Berkley sockets, except native client, can compile some common functions
  244. class RNS2_Berkley : public IRNS2_Berkley
  245. {
  246. public:
  247. RNS2_Berkley();
  248. virtual ~RNS2_Berkley();
  249. int CreateRecvPollingThread(int threadPriority);
  250. void SignalStopRecvPollingThread(void);
  251. void BlockOnStopRecvPollingThread(void);
  252. const RNS2_BerkleyBindParameters *GetBindings(void) const;
  253. RNS2Socket GetSocket(void) const;
  254. void SetDoNotFragment( int opt );
  255. protected:
  256. // Used by other classes
  257. RNS2BindResult BindShared( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line );
  258. RNS2BindResult BindSharedIPV4( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line );
  259. RNS2BindResult BindSharedIPV4And6( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line );
  260. static void GetSystemAddressIPV4 ( RNS2Socket rns2Socket, SystemAddress *systemAddressOut );
  261. static void GetSystemAddressIPV4And6 ( RNS2Socket rns2Socket, SystemAddress *systemAddressOut );
  262. // Internal
  263. void SetNonBlockingSocket(unsigned long nonblocking);
  264. void SetSocketOptions(void);
  265. void SetBroadcastSocket(int broadcast);
  266. void SetIPHdrIncl(int ipHdrIncl);
  267. void RecvFromBlocking(RNS2RecvStruct *recvFromStruct);
  268. void RecvFromBlockingIPV4(RNS2RecvStruct *recvFromStruct);
  269. void RecvFromBlockingIPV4And6(RNS2RecvStruct *recvFromStruct);
  270. RNS2Socket rns2Socket;
  271. RNS2_BerkleyBindParameters binding;
  272. unsigned RecvFromLoopInt(void);
  273. RakNet::LocklessUint32_t isRecvFromLoopThreadActive;
  274. volatile bool endThreads;
  275. // Constructor not called!
  276. #if defined(__APPLE__)
  277. // http://sourceforge.net/p/open-dis/discussion/683284/thread/0929d6a0
  278. CFSocketRef _cfSocket;
  279. #endif
  280. static RAK_THREAD_DECLARATION(RecvFromLoop);
  281. };
  282. #if defined(_WIN32) || defined(__GNUC__) || defined(__GCCXML__) || defined(__S3E__)
  283. class RNS2_Windows_Linux_360
  284. {
  285. public:
  286. protected:
  287. static RNS2SendResult Send_Windows_Linux_360NoVDP( RNS2Socket rns2Socket, RNS2_SendParameters *sendParameters, const char *file, unsigned int line );
  288. };
  289. #endif
  290. #if defined(_WIN32)
  291. class RAK_DLL_EXPORT SocketLayerOverride
  292. {
  293. public:
  294. SocketLayerOverride() {}
  295. virtual ~SocketLayerOverride() {}
  296. /// Called when SendTo would otherwise occur.
  297. virtual int RakNetSendTo( const char *data, int length, const SystemAddress &systemAddress )=0;
  298. /// Called when RecvFrom would otherwise occur. Return number of bytes read. Write data into dataOut
  299. // Return -1 to use RakNet's normal recvfrom, 0 to abort RakNet's normal recvfrom, and positive to return data
  300. virtual int RakNetRecvFrom( char dataOut[ MAXIMUM_MTU_SIZE ], SystemAddress *senderOut, bool calledFromMainThread )=0;
  301. };
  302. class RNS2_Windows : public RNS2_Berkley, public RNS2_Windows_Linux_360
  303. {
  304. public:
  305. RNS2_Windows();
  306. virtual ~RNS2_Windows();
  307. RNS2BindResult Bind( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line );
  308. RNS2SendResult Send( RNS2_SendParameters *sendParameters, const char *file, unsigned int line );
  309. void SetSocketLayerOverride(SocketLayerOverride *_slo);
  310. SocketLayerOverride* GetSocketLayerOverride(void);
  311. // ----------- STATICS ------------
  312. static void GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
  313. protected:
  314. static void GetMyIPIPV4( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
  315. static void GetMyIPIPV4And6( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
  316. SocketLayerOverride *slo;
  317. };
  318. #else
  319. class RNS2_Linux : public RNS2_Berkley, public RNS2_Windows_Linux_360
  320. {
  321. public:
  322. RNS2BindResult Bind( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line );
  323. RNS2SendResult Send( RNS2_SendParameters *sendParameters, const char *file, unsigned int line );
  324. // ----------- STATICS ------------
  325. static void GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
  326. protected:
  327. static void GetMyIPIPV4( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
  328. static void GetMyIPIPV4And6( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
  329. };
  330. #endif // Linux
  331. #endif // #elif !defined(WINDOWS_STORE_RT)
  332. } // namespace RakNet
  333. #endif // __RAKNET_SOCKET_2_H
粤ICP备19079148号