NatPunchthroughServer.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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-punchthrough plugin for the server.
  12. ///
  13. #include "NativeFeatureIncludes.h"
  14. #if _RAKNET_SUPPORT_NatPunchthroughServer==1
  15. #ifndef __NAT_PUNCHTHROUGH_SERVER_H
  16. #define __NAT_PUNCHTHROUGH_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. namespace RakNet
  25. {
  26. /// Forward declarations
  27. class RakPeerInterface;
  28. struct Packet;
  29. #if _RAKNET_SUPPORT_PacketLogger==1
  30. class PacketLogger;
  31. #endif
  32. /// \defgroup NAT_PUNCHTHROUGH_GROUP NatPunchthrough
  33. /// \brief Connect systems despite both systems being behind a router
  34. /// \details
  35. /// \ingroup PLUGINS_GROUP
  36. /// \ingroup NAT_PUNCHTHROUGH_GROUP
  37. struct RAK_DLL_EXPORT NatPunchthroughServerDebugInterface
  38. {
  39. NatPunchthroughServerDebugInterface() {}
  40. virtual ~NatPunchthroughServerDebugInterface() {}
  41. virtual void OnServerMessage(const char *msg)=0;
  42. };
  43. /// \ingroup NAT_PUNCHTHROUGH_GROUP
  44. struct RAK_DLL_EXPORT NatPunchthroughServerDebugInterface_Printf : public NatPunchthroughServerDebugInterface
  45. {
  46. virtual void OnServerMessage(const char *msg);
  47. };
  48. #if _RAKNET_SUPPORT_PacketLogger==1
  49. /// \ingroup NAT_PUNCHTHROUGH_GROUP
  50. struct RAK_DLL_EXPORT NatPunchthroughServerDebugInterface_PacketLogger : public NatPunchthroughServerDebugInterface
  51. {
  52. // Set to non-zero to write to the packetlogger!
  53. PacketLogger *pl;
  54. NatPunchthroughServerDebugInterface_PacketLogger() {pl=0;}
  55. ~NatPunchthroughServerDebugInterface_PacketLogger() {}
  56. virtual void OnServerMessage(const char *msg);
  57. };
  58. #endif
  59. /// \brief Server code for NATPunchthrough
  60. /// \details Maintain connection to NatPunchthroughServer to process incoming connection attempts through NatPunchthroughClient<BR>
  61. /// Server maintains two sockets clients can connect to so as to estimate the next port choice<BR>
  62. /// Server tells other client about port estimate, current public port to the server, and a time to start connection attempts
  63. /// \sa NatTypeDetectionClient
  64. /// See also http://www.jenkinssoftware.com/raknet/manual/natpunchthrough.html
  65. /// \ingroup NAT_PUNCHTHROUGH_GROUP
  66. class RAK_DLL_EXPORT NatPunchthroughServer : public PluginInterface2
  67. {
  68. public:
  69. STATIC_FACTORY_DECLARATIONS(NatPunchthroughServer)
  70. // Constructor
  71. NatPunchthroughServer();
  72. // Destructor
  73. virtual ~NatPunchthroughServer();
  74. /// Sets a callback to be called with debug messages
  75. /// \param[in] i Pointer to an interface. The pointer is stored, so don't delete it while in progress. Pass 0 to clear.
  76. void SetDebugInterface(NatPunchthroughServerDebugInterface *i);
  77. /// \internal For plugin handling
  78. virtual void Update(void);
  79. /// \internal For plugin handling
  80. virtual PluginReceiveResult OnReceive(Packet *packet);
  81. /// \internal For plugin handling
  82. virtual void OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason );
  83. virtual void OnNewConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, bool isIncoming);
  84. // Each connected user has a ready state. Ready means ready for nat punchthrough.
  85. struct User;
  86. struct ConnectionAttempt
  87. {
  88. ConnectionAttempt() {sender=0; recipient=0; startTime=0; attemptPhase=NAT_ATTEMPT_PHASE_NOT_STARTED;}
  89. User *sender, *recipient;
  90. uint16_t sessionId;
  91. RakNet::Time startTime;
  92. enum
  93. {
  94. NAT_ATTEMPT_PHASE_NOT_STARTED,
  95. NAT_ATTEMPT_PHASE_GETTING_RECENT_PORTS,
  96. } attemptPhase;
  97. };
  98. struct User
  99. {
  100. RakNetGUID guid;
  101. SystemAddress systemAddress;
  102. unsigned short mostRecentPort;
  103. bool isReady;
  104. DataStructures::OrderedList<RakNetGUID,RakNetGUID> groupPunchthroughRequests;
  105. DataStructures::List<ConnectionAttempt *> connectionAttempts;
  106. bool HasConnectionAttemptToUser(User *user);
  107. void DerefConnectionAttempt(ConnectionAttempt *ca);
  108. void DeleteConnectionAttempt(ConnectionAttempt *ca);
  109. void LogConnectionAttempts(RakNet::RakString &rs);
  110. };
  111. RakNet::Time lastUpdate;
  112. static int NatPunchthroughUserComp( const RakNetGUID &key, User * const &data );
  113. protected:
  114. void OnNATPunchthroughRequest(Packet *packet);
  115. DataStructures::OrderedList<RakNetGUID, User*, NatPunchthroughServer::NatPunchthroughUserComp> users;
  116. void OnGetMostRecentPort(Packet *packet);
  117. void OnClientReady(Packet *packet);
  118. void SendTimestamps(void);
  119. void StartPendingPunchthrough(void);
  120. void StartPunchthroughForUser(User*user);
  121. uint16_t sessionId;
  122. NatPunchthroughServerDebugInterface *natPunchthroughServerDebugInterface;
  123. SystemAddress boundAddresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS];
  124. unsigned char boundAddressCount;
  125. };
  126. } // namespace RakNet
  127. #endif
  128. #endif // _RAKNET_SUPPORT_*
粤ICP备19079148号