NatTypeDetectionClient.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  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 "NativeFeatureIncludes.h"
  11. #if _RAKNET_SUPPORT_NatTypeDetectionClient==1
  12. #include "NatTypeDetectionClient.h"
  13. #include "RakNetSmartPtr.h"
  14. #include "BitStream.h"
  15. #include "SocketIncludes.h"
  16. #include "RakString.h"
  17. #include "RakPeerInterface.h"
  18. #include "MessageIdentifiers.h"
  19. #include "SocketLayer.h"
  20. #include "SocketDefines.h"
  21. using namespace RakNet;
  22. STATIC_FACTORY_DEFINITIONS(NatTypeDetectionClient,NatTypeDetectionClient);
  23. NatTypeDetectionClient::NatTypeDetectionClient()
  24. {
  25. c2=0;
  26. }
  27. NatTypeDetectionClient::~NatTypeDetectionClient()
  28. {
  29. if (c2!=0)
  30. {
  31. RakNet::OP_DELETE(c2,_FILE_AND_LINE_);
  32. }
  33. }
  34. void NatTypeDetectionClient::DetectNATType(SystemAddress _serverAddress)
  35. {
  36. if (IsInProgress())
  37. return;
  38. if (c2==0)
  39. {
  40. DataStructures::List<RakNetSocket2* > sockets;
  41. rakPeerInterface->GetSockets(sockets);
  42. //SystemAddress sockAddr;
  43. //SocketLayer::GetSystemAddress(sockets[0], &sockAddr);
  44. char str[64];
  45. //sockAddr.ToString(false,str);
  46. sockets[0]->GetBoundAddress().ToString(false,str);
  47. c2=CreateNonblockingBoundSocket(str
  48. #ifdef __native_client__
  49. , sockets[0]->chromeInstance
  50. #endif
  51. ,this
  52. );
  53. //c2Port=SocketLayer::GetLocalPort(c2);
  54. }
  55. #if !defined(__native_client__) && !defined(WINDOWS_STORE_RT)
  56. if (c2->IsBerkleySocket())
  57. ((RNS2_Berkley*) c2)->CreateRecvPollingThread(0);
  58. #endif
  59. serverAddress=_serverAddress;
  60. RakNet::BitStream bs;
  61. bs.Write((unsigned char)ID_NAT_TYPE_DETECTION_REQUEST);
  62. bs.Write(true); // IsRequest
  63. bs.Write(c2->GetBoundAddress().GetPort());
  64. rakPeerInterface->Send(&bs,MEDIUM_PRIORITY,RELIABLE,0,serverAddress,false);
  65. }
  66. void NatTypeDetectionClient::OnCompletion(NATTypeDetectionResult result)
  67. {
  68. Packet *p = AllocatePacketUnified(sizeof(MessageID)+sizeof(unsigned char)*2);
  69. //printf("Returning nat detection result to the user\n");
  70. p->data[0]=ID_NAT_TYPE_DETECTION_RESULT;
  71. p->systemAddress=serverAddress;
  72. p->systemAddress.systemIndex=(SystemIndex)-1;
  73. p->guid=rakPeerInterface->GetGuidFromSystemAddress(serverAddress);
  74. p->data[1]=(unsigned char) result;
  75. p->wasGeneratedLocally=true;
  76. rakPeerInterface->PushBackPacket(p, true);
  77. // Symmetric and port restricted are determined by server, so no need to notify server we are done
  78. if (result!=NAT_TYPE_PORT_RESTRICTED && result!=NAT_TYPE_SYMMETRIC)
  79. {
  80. // Otherwise tell the server we got this message, so it stops sending tests to us
  81. RakNet::BitStream bs;
  82. bs.Write((unsigned char)ID_NAT_TYPE_DETECTION_REQUEST);
  83. bs.Write(false); // Done
  84. rakPeerInterface->Send(&bs,HIGH_PRIORITY,RELIABLE,0,serverAddress,false);
  85. }
  86. Shutdown();
  87. }
  88. bool NatTypeDetectionClient::IsInProgress(void) const
  89. {
  90. return serverAddress!=UNASSIGNED_SYSTEM_ADDRESS;
  91. }
  92. void NatTypeDetectionClient::Update(void)
  93. {
  94. if (IsInProgress())
  95. {
  96. RNS2RecvStruct *recvStruct;
  97. bufferedPacketsMutex.Lock();
  98. if (bufferedPackets.Size()>0)
  99. recvStruct=bufferedPackets.Pop();
  100. else
  101. recvStruct=0;
  102. bufferedPacketsMutex.Unlock();
  103. while (recvStruct)
  104. {
  105. if (recvStruct->bytesRead==1 && recvStruct->data[0]==NAT_TYPE_NONE)
  106. {
  107. OnCompletion(NAT_TYPE_NONE);
  108. RakAssert(IsInProgress()==false);
  109. }
  110. DeallocRNS2RecvStruct(recvStruct, _FILE_AND_LINE_);
  111. bufferedPacketsMutex.Lock();
  112. if (bufferedPackets.Size()>0)
  113. recvStruct=bufferedPackets.Pop();
  114. else
  115. recvStruct=0;
  116. bufferedPacketsMutex.Unlock();
  117. }
  118. }
  119. }
  120. PluginReceiveResult NatTypeDetectionClient::OnReceive(Packet *packet)
  121. {
  122. if (IsInProgress())
  123. {
  124. switch (packet->data[0])
  125. {
  126. case ID_OUT_OF_BAND_INTERNAL:
  127. {
  128. if (packet->length>=3 && packet->data[1]==ID_NAT_TYPE_DETECT)
  129. {
  130. OnCompletion((NATTypeDetectionResult)packet->data[2]);
  131. return RR_STOP_PROCESSING_AND_DEALLOCATE;
  132. }
  133. }
  134. break;
  135. case ID_NAT_TYPE_DETECTION_RESULT:
  136. if (packet->wasGeneratedLocally==false)
  137. {
  138. OnCompletion((NATTypeDetectionResult)packet->data[1]);
  139. return RR_STOP_PROCESSING_AND_DEALLOCATE;
  140. }
  141. else
  142. break;
  143. case ID_NAT_TYPE_DETECTION_REQUEST:
  144. OnTestPortRestricted(packet);
  145. return RR_STOP_PROCESSING_AND_DEALLOCATE;
  146. }
  147. }
  148. return RR_CONTINUE_PROCESSING;
  149. }
  150. void NatTypeDetectionClient::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
  151. {
  152. (void) lostConnectionReason;
  153. (void) rakNetGUID;
  154. if (IsInProgress() && systemAddress==serverAddress)
  155. Shutdown();
  156. }
  157. void NatTypeDetectionClient::OnRakPeerShutdown(void)
  158. {
  159. Shutdown();
  160. }
  161. void NatTypeDetectionClient::OnDetach(void)
  162. {
  163. Shutdown();
  164. }
  165. void NatTypeDetectionClient::OnTestPortRestricted(Packet *packet)
  166. {
  167. RakNet::BitStream bsIn(packet->data,packet->length,false);
  168. bsIn.IgnoreBytes(sizeof(MessageID));
  169. RakNet::RakString s3p4StrAddress;
  170. bsIn.Read(s3p4StrAddress);
  171. unsigned short s3p4Port;
  172. bsIn.Read(s3p4Port);
  173. DataStructures::List<RakNetSocket2* > sockets;
  174. rakPeerInterface->GetSockets(sockets);
  175. SystemAddress s3p4Addr = sockets[0]->GetBoundAddress();
  176. s3p4Addr.FromStringExplicitPort(s3p4StrAddress.C_String(), s3p4Port);
  177. // Send off the RakNet socket to the specified address, message is unformatted
  178. // Server does this twice, so don't have to unduly worry about packetloss
  179. RakNet::BitStream bsOut;
  180. bsOut.Write((MessageID) NAT_TYPE_PORT_RESTRICTED);
  181. bsOut.Write(rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS));
  182. // SocketLayer::SendTo_PC( sockets[0], (const char*) bsOut.GetData(), bsOut.GetNumberOfBytesUsed(), s3p4Addr, __FILE__, __LINE__ );
  183. RNS2_SendParameters bsp;
  184. bsp.data = (char*) bsOut.GetData();
  185. bsp.length = bsOut.GetNumberOfBytesUsed();
  186. bsp.systemAddress=s3p4Addr;
  187. sockets[0]->Send(&bsp, _FILE_AND_LINE_);
  188. }
  189. void NatTypeDetectionClient::Shutdown(void)
  190. {
  191. serverAddress=UNASSIGNED_SYSTEM_ADDRESS;
  192. if (c2!=0)
  193. {
  194. #if !defined(__native_client__) && !defined(WINDOWS_STORE_RT)
  195. if (c2->IsBerkleySocket())
  196. ((RNS2_Berkley *)c2)->BlockOnStopRecvPollingThread();
  197. #endif
  198. RakNet::OP_DELETE(c2, _FILE_AND_LINE_);
  199. c2=0;
  200. }
  201. bufferedPacketsMutex.Lock();
  202. while (bufferedPackets.Size())
  203. RakNet::OP_DELETE(bufferedPackets.Pop(), _FILE_AND_LINE_);
  204. bufferedPacketsMutex.Unlock();
  205. }
  206. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  207. void NatTypeDetectionClient::DeallocRNS2RecvStruct(RNS2RecvStruct *s, const char *file, unsigned int line)
  208. {
  209. RakNet::OP_DELETE(s, file, line);
  210. }
  211. // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  212. RNS2RecvStruct *NatTypeDetectionClient::AllocRNS2RecvStruct(const char *file, unsigned int line)
  213. {
  214. return RakNet::OP_NEW<RNS2RecvStruct>(file,line);
  215. }
  216. void NatTypeDetectionClient::OnRNS2Recv(RNS2RecvStruct *recvStruct)
  217. {
  218. bufferedPacketsMutex.Lock();
  219. bufferedPackets.Push(recvStruct,_FILE_AND_LINE_);
  220. bufferedPacketsMutex.Unlock();
  221. }
  222. #endif // _RAKNET_SUPPORT_*
粤ICP备19079148号