PageRenderTime 61ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/raknet/RakNetSocket2.cpp

https://gitlab.com/computerphilly/openblox
C++ | 513 lines | 342 code | 134 blank | 37 comment | 30 complexity | 8691e07a59342da203b958a067ebee28 MD5 | raw file
  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. #include "RakNetSocket2.h"
  11. #include "RakMemoryOverride.h"
  12. #include "RakAssert.h"
  13. #include "RakSleep.h"
  14. #include "SocketDefines.h"
  15. #include "GetTime.h"
  16. #include <stdio.h>
  17. #include <string.h> // memcpy
  18. using namespace RakNet;
  19. #ifdef _WIN32
  20. #else
  21. #include <unistd.h>
  22. #include <fcntl.h>
  23. #include <arpa/inet.h>
  24. #include <errno.h> // error numbers
  25. #if !defined(ANDROID)
  26. #include <ifaddrs.h>
  27. #endif
  28. #include <netinet/in.h>
  29. #include <net/if.h>
  30. #include <sys/types.h>
  31. #include <sys/socket.h>
  32. #include <sys/ioctl.h>
  33. #endif
  34. #ifdef TEST_NATIVE_CLIENT_ON_WINDOWS
  35. #else
  36. #define RAKNET_SOCKET_2_INLINE_FUNCTIONS
  37. #include "RakNetSocket2_360_720.cpp"
  38. #include "RakNetSocket2_PS3_PS4.cpp"
  39. #include "RakNetSocket2_PS4.cpp"
  40. #include "RakNetSocket2_Windows_Linux.cpp"
  41. #include "RakNetSocket2_Windows_Linux_360.cpp"
  42. #include "RakNetSocket2_Vita.cpp"
  43. #include "RakNetSocket2_NativeClient.cpp"
  44. #include "RakNetSocket2_Berkley.cpp"
  45. #include "RakNetSocket2_Berkley_NativeClient.cpp"
  46. #include "RakNetSocket2_WindowsStore8.cpp"
  47. #undef RAKNET_SOCKET_2_INLINE_FUNCTIONS
  48. #endif
  49. #ifndef INVALID_SOCKET
  50. #define INVALID_SOCKET -1
  51. #endif
  52. void RakNetSocket2Allocator::DeallocRNS2(RakNetSocket2 *s) {RakNet::OP_DELETE(s,_FILE_AND_LINE_);}
  53. RakNetSocket2::RakNetSocket2() {eventHandler=0;}
  54. RakNetSocket2::~RakNetSocket2() {}
  55. void RakNetSocket2::SetRecvEventHandler(RNS2EventHandler *_eventHandler) {eventHandler=_eventHandler;}
  56. RNS2Type RakNetSocket2::GetSocketType(void) const {return socketType;}
  57. void RakNetSocket2::SetSocketType(RNS2Type t) {socketType=t;}
  58. bool RakNetSocket2::IsBerkleySocket(void) const {
  59. return socketType!=RNS2T_CHROME && socketType!=RNS2T_WINDOWS_STORE_8;
  60. }
  61. SystemAddress RakNetSocket2::GetBoundAddress(void) const {return boundAddress;}
  62. RakNetSocket2* RakNetSocket2Allocator::AllocRNS2(void)
  63. {
  64. RakNetSocket2* s2;
  65. #if defined(WINDOWS_STORE_RT)
  66. s2 = RakNet::OP_NEW<RNS2_WindowsStore8>(_FILE_AND_LINE_);
  67. s2->SetSocketType(RNS2T_WINDOWS_STORE_8);
  68. #elif defined(__native_client__)
  69. s2 = RakNet::OP_NEW<RNS2_NativeClient>(_FILE_AND_LINE_);
  70. s2->SetSocketType(RNS2T_CHROME);
  71. #elif defined(_WIN32)
  72. s2 = RakNet::OP_NEW<RNS2_Windows>(_FILE_AND_LINE_);
  73. s2->SetSocketType(RNS2T_WINDOWS);
  74. #else
  75. s2 = RakNet::OP_NEW<RNS2_Linux>(_FILE_AND_LINE_);
  76. s2->SetSocketType(RNS2T_LINUX);
  77. #endif
  78. return s2;
  79. }
  80. void RakNetSocket2::GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] )
  81. {
  82. #if defined(WINDOWS_STORE_RT)
  83. RNS2_WindowsStore8::GetMyIP( addresses );
  84. #elif defined(__native_client__)
  85. RNS2_NativeClient::GetMyIP( addresses );
  86. #elif defined(_WIN32)
  87. RNS2_Windows::GetMyIP( addresses );
  88. #else
  89. RNS2_Linux::GetMyIP( addresses );
  90. #endif
  91. }
  92. unsigned int RakNetSocket2::GetUserConnectionSocketIndex(void) const {return userConnectionSocketIndex;}
  93. void RakNetSocket2::SetUserConnectionSocketIndex(unsigned int i) {userConnectionSocketIndex=i;}
  94. RNS2EventHandler * RakNetSocket2::GetEventHandler(void) const {return eventHandler;}
  95. void RakNetSocket2::DomainNameToIP( const char *domainName, char ip[65] ) {
  96. #if defined(WINDOWS_STORE_RT)
  97. return RNS2_WindowsStore8::DomainNameToIP( domainName, ip );
  98. #elif defined(__native_client__)
  99. return DomainNameToIP_Berkley( domainName, ip );
  100. #elif defined(_WIN32)
  101. return DomainNameToIP_Berkley( domainName, ip );
  102. #else
  103. return DomainNameToIP_Berkley( domainName, ip );
  104. #endif
  105. }
  106. #if defined(WINDOWS_STORE_RT)
  107. #elif defined(__native_client__)
  108. RNS2_NativeClient::RNS2_NativeClient() {bindState = BS_UNBOUND; sendInProgress=false;}
  109. RNS2_NativeClient::~RNS2_NativeClient()
  110. {
  111. bufferedSendsMutex.Lock();
  112. while (bufferedSends.Size())
  113. RakNet::OP_DELETE(bufferedSends.Pop(), _FILE_AND_LINE_);
  114. bufferedSendsMutex.Unlock();
  115. }
  116. void RNS2_NativeClient::onSocketBound(void* pData, int32_t dataSize)
  117. {
  118. RAKNET_DEBUG_PRINTF("onSocketBound ==> %d\n", dataSize);
  119. RNS2_NativeClient *csc = (RNS2_NativeClient *)pData;
  120. //any error codes will be given to us in the dataSize value
  121. if(dataSize < 0)
  122. {
  123. csc->bindState=BS_FAILED;
  124. fprintf(stderr,"onSocketBound exiting, dataSize = %d\n", dataSize);
  125. return;
  126. }
  127. csc->bindState=BS_BOUND;
  128. csc->ProcessBufferedSend();
  129. csc->IssueReceiveCall();
  130. }
  131. void RNS2_NativeClient::ProcessBufferedSend(void)
  132. {
  133. // Don't send until bound
  134. if (bindState!=BS_BOUND)
  135. return;
  136. // Fast non-threadsafe check
  137. if (bufferedSends.IsEmpty()==true)
  138. return;
  139. sendInProgressMutex.Lock();
  140. if (sendInProgress==true) {sendInProgressMutex.Unlock(); return;}
  141. else {sendInProgress=true;}
  142. sendInProgressMutex.Unlock();
  143. RNS2_SendParameters_NativeClient *sp;
  144. bufferedSendsMutex.Lock();
  145. if (bufferedSends.IsEmpty()==false)
  146. sp=bufferedSends.Pop();
  147. else
  148. sp=0;
  149. bufferedSendsMutex.Unlock();
  150. if (sp==0)
  151. {
  152. sendInProgressMutex.Lock();
  153. sendInProgress=false;
  154. sendInProgressMutex.Unlock();
  155. return; // Nothing to send after all
  156. }
  157. SendImmediate(sp);
  158. // sp remains in memory until the callback completes
  159. // DeallocSP(sp);
  160. }
  161. void RNS2_NativeClient::DeallocSP(RNS2_SendParameters_NativeClient *sp)
  162. {
  163. rakFree_Ex(sp->data, _FILE_AND_LINE_);
  164. RakNet::OP_DELETE(sp, _FILE_AND_LINE_);
  165. }
  166. RNS2_SendParameters_NativeClient* RNS2_NativeClient::CloneSP(RNS2_SendParameters *sp, RNS2_NativeClient *socket2, const char *file, unsigned int line)
  167. {
  168. RNS2_SendParameters_NativeClient *spNew = RakNet::OP_NEW<RNS2_SendParameters_NativeClient>(file, line);
  169. spNew->data=(char*) rakMalloc(sp->length);
  170. memcpy(spNew->data,sp->data,sp->length);
  171. spNew->length = sp->length;
  172. spNew->socket2=socket2;
  173. spNew->systemAddress=sp->systemAddress;
  174. spNew->ttl=0; // Unused
  175. return spNew;
  176. }
  177. void RNS2_NativeClient::onSendTo(void* pData, int32_t dataSize)
  178. {
  179. if(dataSize <= 0)
  180. RAKNET_DEBUG_PRINTF("onSendTo: send failed with error %d\n", dataSize);
  181. RNS2_SendParameters_NativeClient *sp = (RNS2_SendParameters_NativeClient*) pData;
  182. // Caller will check sendInProgress to send again if needed
  183. sp->socket2->sendInProgressMutex.Lock();
  184. sp->socket2->sendInProgress=false;
  185. sp->socket2->sendInProgressMutex.Unlock();
  186. DeallocSP(sp);
  187. // if(dataSize == PP_ERROR_ABORTED)
  188. // return;
  189. }
  190. RNS2SendResult RNS2_NativeClient::Send( RNS2_SendParameters *sendParameters, const char *file, unsigned int line )
  191. {
  192. if (bindState==BS_FAILED)
  193. return -1;
  194. // This is called from multiple threads. Always buffer the send, until native client is threadsafe
  195. BufferSend(sendParameters, file, line);
  196. return sendParameters->length;
  197. }
  198. void RNS2_NativeClient::BufferSend( RNS2_SendParameters *sendParameters, const char *file, unsigned int line )
  199. {
  200. if (bindState==BS_FAILED)
  201. return;
  202. RNS2_SendParameters_NativeClient* sp = CloneSP(sendParameters, this, file, line);
  203. bufferedSendsMutex.Lock();
  204. bufferedSends.Push(sp, file, line);
  205. bufferedSendsMutex.Unlock();
  206. // Do not check to send immediately, because this was probably invoked from a thread and native client is not threadsafe
  207. }
  208. void RNS2_NativeClient::GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] ) {addresses[0]=UNASSIGNED_SYSTEM_ADDRESS; RakAssert("GetMyIP Unsupported?" && 0);}
  209. const NativeClientBindParameters *RNS2_NativeClient::GetBindings(void) const {return &binding;}
  210. void RNS2_NativeClient::Update(void)
  211. {
  212. // Don't send until bound
  213. if (bindState==BS_BOUND)
  214. {
  215. do
  216. {
  217. ProcessBufferedSend();
  218. } while (sendInProgress==false && bufferedSends.Size()>1);
  219. }
  220. }
  221. #else // defined(__native_client__)
  222. bool IRNS2_Berkley::IsPortInUse(unsigned short port, const char *hostAddress, unsigned short addressFamily, int type ) {
  223. RNS2_BerkleyBindParameters bbp;
  224. bbp.remotePortRakNetWasStartedOn_PS3_PS4_PSP2=0;
  225. bbp.port=port; bbp.hostAddress=(char*) hostAddress; bbp.addressFamily=addressFamily;
  226. bbp.type=type; bbp.protocol=0; bbp.nonBlockingSocket=false;
  227. bbp.setBroadcast=false; bbp.doNotFragment=false; bbp.protocol=0;
  228. bbp.setIPHdrIncl=false;
  229. SystemAddress boundAddress;
  230. RNS2_Berkley *rns2 = (RNS2_Berkley*) RakNetSocket2Allocator::AllocRNS2();
  231. RNS2BindResult bindResult = rns2->Bind(&bbp, _FILE_AND_LINE_);
  232. RakNetSocket2Allocator::DeallocRNS2(rns2);
  233. return bindResult==BR_FAILED_TO_BIND_SOCKET;
  234. }
  235. #if defined(__APPLE__)
  236. void SocketReadCallback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
  237. // This C routine is called by CFSocket when there's data waiting on our
  238. // UDP socket. It just redirects the call to Objective-C code.
  239. { }
  240. #endif
  241. RNS2BindResult RNS2_Berkley::BindShared( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line ) {
  242. RNS2BindResult br;
  243. #if RAKNET_SUPPORT_IPV6==1
  244. br=BindSharedIPV4And6(bindParameters, file, line);
  245. #else
  246. br=BindSharedIPV4(bindParameters, file, line);
  247. #endif
  248. if (br!=BR_SUCCESS)
  249. return br;
  250. unsigned long zero=0;
  251. RNS2_SendParameters bsp;
  252. bsp.data=(char*) &zero;
  253. bsp.length=4;
  254. bsp.systemAddress=boundAddress;
  255. bsp.ttl=0;
  256. RNS2SendResult sr = Send(&bsp, _FILE_AND_LINE_);
  257. if (sr<0)
  258. return BR_FAILED_SEND_TEST;
  259. memcpy(&binding, bindParameters, sizeof(RNS2_BerkleyBindParameters));
  260. /*
  261. #if defined(__APPLE__)
  262. const CFSocketContext context = { 0, this, NULL, NULL, NULL };
  263. _cfSocket = CFSocketCreateWithNative(NULL, rns2Socket, kCFSocketReadCallBack, SocketReadCallback, &context);
  264. #endif
  265. */
  266. return br;
  267. }
  268. RAK_THREAD_DECLARATION(RNS2_Berkley::RecvFromLoop)
  269. {
  270. RNS2_Berkley *b = ( RNS2_Berkley * ) arguments;
  271. b->RecvFromLoopInt();
  272. return 0;
  273. }
  274. unsigned RNS2_Berkley::RecvFromLoopInt(void)
  275. {
  276. isRecvFromLoopThreadActive.Increment();
  277. while ( endThreads == false )
  278. {
  279. RNS2RecvStruct *recvFromStruct;
  280. recvFromStruct=binding.eventHandler->AllocRNS2RecvStruct(_FILE_AND_LINE_);
  281. if (recvFromStruct != NULL)
  282. {
  283. recvFromStruct->socket=this;
  284. RecvFromBlocking(recvFromStruct);
  285. if (recvFromStruct->bytesRead>0)
  286. {
  287. RakAssert(recvFromStruct->systemAddress.GetPort());
  288. binding.eventHandler->OnRNS2Recv(recvFromStruct);
  289. }
  290. else
  291. {
  292. RakSleep(0);
  293. binding.eventHandler->DeallocRNS2RecvStruct(recvFromStruct, _FILE_AND_LINE_);
  294. }
  295. }
  296. }
  297. isRecvFromLoopThreadActive.Decrement();
  298. return 0;
  299. }
  300. RNS2_Berkley::RNS2_Berkley()
  301. {
  302. rns2Socket=(RNS2Socket)INVALID_SOCKET;
  303. }
  304. RNS2_Berkley::~RNS2_Berkley()
  305. {
  306. if (rns2Socket!=INVALID_SOCKET)
  307. {
  308. /*
  309. #if defined(__APPLE__)
  310. CFSocketInvalidate(_cfSocket);
  311. #endif
  312. */
  313. closesocket__(rns2Socket);
  314. }
  315. }
  316. int RNS2_Berkley::CreateRecvPollingThread(int threadPriority)
  317. {
  318. endThreads=false;
  319. int errorCode = RakNet::RakThread::Create(RecvFromLoop, this, threadPriority);
  320. return errorCode;
  321. }
  322. void RNS2_Berkley::SignalStopRecvPollingThread(void)
  323. {
  324. endThreads=true;
  325. }
  326. void RNS2_Berkley::BlockOnStopRecvPollingThread(void)
  327. {
  328. endThreads=true;
  329. // Get recvfrom to unblock
  330. RNS2_SendParameters bsp;
  331. unsigned long zero=0;
  332. bsp.data=(char*) &zero;
  333. bsp.length=4;
  334. bsp.systemAddress=boundAddress;
  335. bsp.ttl=0;
  336. Send(&bsp, _FILE_AND_LINE_);
  337. RakNet::TimeMS timeout = RakNet::GetTimeMS()+1000;
  338. while ( isRecvFromLoopThreadActive.GetValue()>0 && RakNet::GetTimeMS()<timeout )
  339. {
  340. // Get recvfrom to unblock
  341. Send(&bsp, _FILE_AND_LINE_);
  342. RakSleep(30);
  343. }
  344. }
  345. const RNS2_BerkleyBindParameters *RNS2_Berkley::GetBindings(void) const {return &binding;}
  346. RNS2Socket RNS2_Berkley::GetSocket(void) const {return rns2Socket;}
  347. // See RakNetSocket2_Berkley.cpp for WriteSharedIPV4, BindSharedIPV4And6 and other implementations
  348. #if defined(_WIN32)
  349. RNS2_Windows::RNS2_Windows() {slo=0;}
  350. RNS2_Windows::~RNS2_Windows() {}
  351. RNS2BindResult RNS2_Windows::Bind( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line ) {
  352. RNS2BindResult bindResult = BindShared(bindParameters, file, line);
  353. if (bindResult == BR_FAILED_TO_BIND_SOCKET)
  354. {
  355. // Sometimes windows will fail if the socket is recreated too quickly
  356. RakSleep(100);
  357. bindResult = BindShared(bindParameters, file, line);
  358. }
  359. return bindResult;
  360. }
  361. RNS2SendResult RNS2_Windows::Send( RNS2_SendParameters *sendParameters, const char *file, unsigned int line ) {
  362. if (slo)
  363. {
  364. RNS2SendResult len;
  365. len = slo->RakNetSendTo(sendParameters->data, sendParameters->length,sendParameters->systemAddress);
  366. if (len>=0)
  367. return len;
  368. }
  369. return Send_Windows_Linux_360NoVDP(rns2Socket,sendParameters, file, line);
  370. }
  371. void RNS2_Windows::GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] ) {return GetMyIP_Windows_Linux(addresses);}
  372. void RNS2_Windows::SetSocketLayerOverride(SocketLayerOverride *_slo) {slo = _slo;}
  373. SocketLayerOverride* RNS2_Windows::GetSocketLayerOverride(void) {return slo;}
  374. #else
  375. RNS2BindResult RNS2_Linux::Bind( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line ) {return BindShared(bindParameters, file, line);}
  376. RNS2SendResult RNS2_Linux::Send( RNS2_SendParameters *sendParameters, const char *file, unsigned int line ) {return Send_Windows_Linux_360NoVDP(rns2Socket,sendParameters, file, line);}
  377. void RNS2_Linux::GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] ) {return GetMyIP_Windows_Linux(addresses);}
  378. #endif // Linux
  379. #endif // defined(__native_client__)