NatTypeDetectionServer.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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. /// \file
  11. /// \brief Contains the NAT-type detection code for the server
  12. ///
  13. #include "NativeFeatureIncludes.h"
  14. #if _RAKNET_SUPPORT_NatTypeDetectionServer==1
  15. #ifndef __NAT_TYPE_DETECTION_SERVER_H
  16. #define __NAT_TYPE_DETECTION_SERVER_H
  17. #include "RakNetTypes.h"
  18. #include "Export.h"
  19. #include "PluginInterface2.h"
  20. #include "PacketPriority.h"
  21. #include "SocketIncludes.h"
  22. #include "DS_OrderedList.h"
  23. #include "RakString.h"
  24. #include "NatTypeDetectionCommon.h"
  25. namespace RakNet
  26. {
  27. /// Forward declarations
  28. class RakPeerInterface;
  29. struct Packet;
  30. /// \brief Server code for NatTypeDetection
  31. /// \details
  32. /// Sends to a remote system on certain ports and addresses to determine what type of router, if any, that client is behind
  33. /// Requires that the server have 4 external IP addresses
  34. /// <OL>
  35. /// <LI>Server has 1 instance of RakNet. Server has four external ip addresses S1 to S4. Five ports are used in total P1 to P5. RakNet is bound to S1P1. Sockets are bound to S1P2, S2P3, S3P4, S4P5
  36. /// <LI>Client with one port using RakNet (C1). Another port not using anything (C2).
  37. /// <LI>C1 connects to S1P1 for normal communication.
  38. /// <LI>S4P5 sends to C2. If arrived, no NAT. Done. (If didn't arrive, S4P5 potentially banned, do not use again).
  39. /// <LI>S2P3 sends to C1 (Different address, different port, to previously used port on client). If received, Full-cone nat. Done. (If didn't arrive, S2P3 potentially banned, do not use again).
  40. /// <LI>S1P2 sends to C1 (Same address, different port, to previously used port on client). If received, address-restricted cone nat. Done.
  41. /// <LI>Server via RakNet connection tells C1 to send to to S3P4. If address of C1 as seen by S3P4 is the same as the address of C1 as seen by S1P1 (RakNet connection), then port-restricted cone nat. Done
  42. /// <LI>Else symmetric nat. Done.
  43. /// </OL>
  44. /// See also http://www.jenkinssoftware.com/raknet/manual/natpunchthrough.html
  45. /// \sa NatPunchthroughServer
  46. /// \sa NatTypeDetectionClient
  47. /// \ingroup NAT_TYPE_DETECTION_GROUP
  48. class RAK_DLL_EXPORT NatTypeDetectionServer : public PluginInterface2, public RNS2EventHandler
  49. {
  50. public:
  51. // GetInstance() and DestroyInstance(instance*)
  52. STATIC_FACTORY_DECLARATIONS(NatTypeDetectionServer)
  53. // Constructor
  54. NatTypeDetectionServer();
  55. // Destructor
  56. virtual ~NatTypeDetectionServer();
  57. /// Start the system, binding to 3 external IPs not already in useS
  58. /// \param[in] nonRakNetIP2 First unused external IP
  59. /// \param[in] nonRakNetIP3 Second unused external IP
  60. /// \param[in] nonRakNetIP4 Third unused external IP
  61. void Startup(
  62. const char *nonRakNetIP2,
  63. const char *nonRakNetIP3,
  64. const char *nonRakNetIP4
  65. #ifdef __native_client__
  66. ,_PP_Instance_ chromeInstance
  67. #endif
  68. );
  69. // Releases the sockets created in Startup();
  70. void Shutdown(void);
  71. /// \internal For plugin handling
  72. virtual void Update(void);
  73. /// \internal For plugin handling
  74. virtual PluginReceiveResult OnReceive(Packet *packet);
  75. virtual void OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason );
  76. enum NATDetectionState
  77. {
  78. STATE_NONE,
  79. STATE_TESTING_NONE_1,
  80. STATE_TESTING_NONE_2,
  81. STATE_TESTING_FULL_CONE_1,
  82. STATE_TESTING_FULL_CONE_2,
  83. STATE_TESTING_ADDRESS_RESTRICTED_1,
  84. STATE_TESTING_ADDRESS_RESTRICTED_2,
  85. STATE_TESTING_PORT_RESTRICTED_1,
  86. STATE_TESTING_PORT_RESTRICTED_2,
  87. STATE_DONE,
  88. };
  89. struct NATDetectionAttempt
  90. {
  91. SystemAddress systemAddress;
  92. NATDetectionState detectionState;
  93. RakNet::TimeMS nextStateTime;
  94. RakNet::TimeMS timeBetweenAttempts;
  95. unsigned short c2Port;
  96. RakNetGUID guid;
  97. };
  98. virtual void OnRNS2Recv(RNS2RecvStruct *recvStruct);
  99. virtual void DeallocRNS2RecvStruct(RNS2RecvStruct *s, const char *file, unsigned int line);
  100. virtual RNS2RecvStruct *AllocRNS2RecvStruct(const char *file, unsigned int line);
  101. protected:
  102. DataStructures::Queue<RNS2RecvStruct*> bufferedPackets;
  103. SimpleMutex bufferedPacketsMutex;
  104. void OnDetectionRequest(Packet *packet);
  105. DataStructures::List<NATDetectionAttempt> natDetectionAttempts;
  106. unsigned int GetDetectionAttemptIndex(const SystemAddress &sa);
  107. unsigned int GetDetectionAttemptIndex(RakNetGUID guid);
  108. // s1p1 is rakpeer itself
  109. RakNetSocket2 *s1p2,*s2p3,*s3p4,*s4p5;
  110. //unsigned short s1p2Port, s2p3Port, s3p4Port, s4p5Port;
  111. char s3p4Address[64];
  112. };
  113. }
  114. #endif
  115. #endif // _RAKNET_SUPPORT_*
粤ICP备19079148号