UDPProxyClient.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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 A RakNet plugin performing networking to communicate with UDPProxyCoordinator. Ultimately used to tell UDPProxyServer to forward UDP packets.
  12. #include "NativeFeatureIncludes.h"
  13. #if _RAKNET_SUPPORT_UDPProxyClient==1
  14. #ifndef __UDP_PROXY_CLIENT_H
  15. #define __UDP_PROXY_CLIENT_H
  16. #include "Export.h"
  17. #include "RakNetTypes.h"
  18. #include "PluginInterface2.h"
  19. #include "DS_List.h"
  20. /// \defgroup UDP_PROXY_GROUP UDPProxy
  21. /// \brief Forwards UDP datagrams from one system to another. Protocol independent
  22. /// \details Used when NatPunchthroughClient fails
  23. /// \ingroup PLUGINS_GROUP
  24. namespace RakNet
  25. {
  26. class UDPProxyClient;
  27. /// Callback to handle results of calling UDPProxyClient::RequestForwarding()
  28. /// \ingroup UDP_PROXY_GROUP
  29. struct UDPProxyClientResultHandler
  30. {
  31. UDPProxyClientResultHandler() {}
  32. virtual ~UDPProxyClientResultHandler() {}
  33. /// Called when our forwarding request was completed. We can now connect to \a targetAddress by using \a proxyAddress instead
  34. /// \param[out] proxyIPAddress IP Address of the proxy server, which will forward messages to targetAddress
  35. /// \param[out] proxyPort Remote port to use on the proxy server, which will forward messages to targetAddress
  36. /// \param[out] proxyCoordinator \a proxyCoordinator parameter originally passed to UDPProxyClient::RequestForwarding
  37. /// \param[out] sourceAddress \a sourceAddress parameter passed to UDPProxyClient::RequestForwarding. If it was UNASSIGNED_SYSTEM_ADDRESS, it is now our external IP address.
  38. /// \param[out] targetAddress \a targetAddress parameter originally passed to UDPProxyClient::RequestForwarding
  39. /// \param[out] targetGuid \a targetGuid parameter originally passed to UDPProxyClient::RequestForwarding
  40. /// \param[out] proxyClient The plugin that is calling this callback
  41. virtual void OnForwardingSuccess(const char *proxyIPAddress, unsigned short proxyPort,
  42. SystemAddress proxyCoordinator, SystemAddress sourceAddress, SystemAddress targetAddress, RakNetGUID targetGuid, RakNet::UDPProxyClient *proxyClientPlugin)=0;
  43. /// Called when another system has setup forwarding, with our system as the target address.
  44. /// Plugin automatically sends a datagram to proxyIPAddress before this callback, to open our router if necessary.
  45. /// \param[out] proxyIPAddress IP Address of the proxy server, which will forward messages to targetAddress
  46. /// \param[out] proxyPort Remote port to use on the proxy server, which will forward messages to targetAddress
  47. /// \param[out] proxyCoordinator \a proxyCoordinator parameter originally passed to UDPProxyClient::RequestForwarding
  48. /// \param[out] sourceAddress \a sourceAddress parameter passed to UDPProxyClient::RequestForwarding. This is originating source IP address of the remote system that will be sending to us.
  49. /// \param[out] targetAddress \a targetAddress parameter originally passed to UDPProxyClient::RequestForwarding. This is our external IP address.
  50. /// \param[out] targetGuid \a targetGuid parameter originally passed to UDPProxyClient::RequestForwarding
  51. /// \param[out] proxyClient The plugin that is calling this callback
  52. virtual void OnForwardingNotification(const char *proxyIPAddress, unsigned short proxyPort,
  53. SystemAddress proxyCoordinator, SystemAddress sourceAddress, SystemAddress targetAddress, RakNetGUID targetGuid, RakNet::UDPProxyClient *proxyClientPlugin)=0;
  54. /// Called when our forwarding request failed, because no UDPProxyServers are connected to UDPProxyCoordinator
  55. /// \param[out] proxyCoordinator \a proxyCoordinator parameter originally passed to UDPProxyClient::RequestForwarding
  56. /// \param[out] sourceAddress \a sourceAddress parameter passed to UDPProxyClient::RequestForwarding. If it was UNASSIGNED_SYSTEM_ADDRESS, it is now our external IP address.
  57. /// \param[out] targetAddress \a targetAddress parameter originally passed to UDPProxyClient::RequestForwarding
  58. /// \param[out] targetGuid \a targetGuid parameter originally passed to UDPProxyClient::RequestForwarding
  59. /// \param[out] proxyClient The plugin that is calling this callback
  60. virtual void OnNoServersOnline(SystemAddress proxyCoordinator, SystemAddress sourceAddress, SystemAddress targetAddress, RakNetGUID targetGuid, RakNet::UDPProxyClient *proxyClientPlugin)=0;
  61. /// Called when our forwarding request failed, because no UDPProxyServers are connected to UDPProxyCoordinator
  62. /// \param[out] proxyCoordinator \a proxyCoordinator parameter originally passed to UDPProxyClient::RequestForwarding
  63. /// \param[out] sourceAddress \a sourceAddress parameter passed to UDPProxyClient::RequestForwarding. If it was UNASSIGNED_SYSTEM_ADDRESS, it is now our external IP address.
  64. /// \param[out] targetAddress \a targetAddress parameter originally passed to UDPProxyClient::RequestForwarding
  65. /// \param[out] targetGuid \a targetGuid parameter originally passed to UDPProxyClient::RequestForwarding
  66. /// \param[out] proxyClient The plugin that is calling this callback
  67. virtual void OnRecipientNotConnected(SystemAddress proxyCoordinator, SystemAddress sourceAddress, SystemAddress targetAddress, RakNetGUID targetGuid, RakNet::UDPProxyClient *proxyClientPlugin)=0;
  68. /// Called when our forwarding request failed, because all UDPProxyServers that are connected to UDPProxyCoordinator are at their capacity
  69. /// Either add more servers, or increase capacity via UDPForwarder::SetMaxForwardEntries()
  70. /// \param[out] proxyCoordinator \a proxyCoordinator parameter originally passed to UDPProxyClient::RequestForwarding
  71. /// \param[out] sourceAddress \a sourceAddress parameter passed to UDPProxyClient::RequestForwarding. If it was UNASSIGNED_SYSTEM_ADDRESS, it is now our external IP address.
  72. /// \param[out] targetAddress \a targetAddress parameter originally passed to UDPProxyClient::RequestForwarding
  73. /// \param[out] targetGuid \a targetGuid parameter originally passed to UDPProxyClient::RequestForwarding
  74. /// \param[out] proxyClient The plugin that is calling this callback
  75. virtual void OnAllServersBusy(SystemAddress proxyCoordinator, SystemAddress sourceAddress, SystemAddress targetAddress, RakNetGUID targetGuid, RakNet::UDPProxyClient *proxyClientPlugin)=0;
  76. /// Called when our forwarding request is already in progress on the \a proxyCoordinator.
  77. /// This can be ignored, but indicates an unneeded second request
  78. /// \param[out] proxyIPAddress IP Address of the proxy server, which is forwarding messages to targetAddress
  79. /// \param[out] proxyPort Remote port to use on the proxy server, which is forwarding messages to targetAddress
  80. /// \param[out] proxyCoordinator \a proxyCoordinator parameter originally passed to UDPProxyClient::RequestForwarding
  81. /// \param[out] sourceAddress \a sourceAddress parameter passed to UDPProxyClient::RequestForwarding. If it was UNASSIGNED_SYSTEM_ADDRESS, it is now our external IP address.
  82. /// \param[out] targetAddress \a targetAddress parameter originally passed to UDPProxyClient::RequestForwarding
  83. /// \param[out] targetGuid \a targetGuid parameter originally passed to UDPProxyClient::RequestForwarding
  84. /// \param[out] proxyClient The plugin that is calling this callback
  85. virtual void OnForwardingInProgress(const char *proxyIPAddress, unsigned short proxyPort, SystemAddress proxyCoordinator, SystemAddress sourceAddress, SystemAddress targetAddress, RakNetGUID targetGuid, RakNet::UDPProxyClient *proxyClientPlugin)=0;
  86. };
  87. /// \brief Communicates with UDPProxyCoordinator, in order to find a UDPProxyServer to forward our datagrams.
  88. /// \details When NAT Punchthrough fails, it is possible to use a non-NAT system to forward messages from us to the recipient, and vice-versa.<BR>
  89. /// The class to forward messages is UDPForwarder, and it is triggered over the network via the UDPProxyServer plugin.<BR>
  90. /// The UDPProxyClient connects to UDPProxyCoordinator to get a list of servers running UDPProxyServer, and the coordinator will relay our forwarding request
  91. /// \sa NatPunchthroughServer
  92. /// \sa NatPunchthroughClient
  93. /// \ingroup UDP_PROXY_GROUP
  94. class RAK_DLL_EXPORT UDPProxyClient : public PluginInterface2
  95. {
  96. public:
  97. // GetInstance() and DestroyInstance(instance*)
  98. STATIC_FACTORY_DECLARATIONS(UDPProxyClient)
  99. UDPProxyClient();
  100. ~UDPProxyClient();
  101. /// Receives the results of calling RequestForwarding()
  102. /// Set before calling RequestForwarding or you won't know what happened
  103. /// \param[in] resultHandler
  104. void SetResultHandler(UDPProxyClientResultHandler *rh);
  105. /// Sends a request to proxyCoordinator to find a server and have that server setup UDPForwarder::StartForwarding() on our address to \a targetAddressAsSeenFromCoordinator
  106. /// The forwarded datagrams can be from any UDP source, not just RakNet
  107. /// \pre Must be connected to \a proxyCoordinator
  108. /// \pre Systems running UDPProxyServer must be connected to \a proxyCoordinator and logged in via UDPProxyCoordinator::LoginServer() or UDPProxyServer::LoginToCoordinator()
  109. /// \note May still fail, if all proxy servers have no open connections.
  110. /// \note RakNet's protocol will ensure a message is sent at least every 5 seconds, so if routing RakNet messages, it is a reasonable value for timeoutOnNoDataMS, plus an extra few seconds for latency.
  111. /// \param[in] proxyCoordinator System we are connected to that is running the UDPProxyCoordinator plugin
  112. /// \param[in] sourceAddress External IP address of the system we want to forward messages from. This does not have to be our own system. To specify our own system, you can pass UNASSIGNED_SYSTEM_ADDRESS which the coordinator will treat as our external IP address.
  113. /// \param[in] targetAddressAsSeenFromCoordinator External IP address of the system we want to forward messages to. If this system is connected to UDPProxyCoordinator at this address using RakNet, that system will ping the server and thus open the router for incoming communication. In any other case, you are responsible for doing your own network communication to have that system ping the server. See also targetGuid in the other version of RequestForwarding(), to avoid the need to know the IP address to the coordinator of the destination.
  114. /// \param[in] timeoutOnNoData If no data is sent by the forwarded systems, how long before removing the forward entry from UDPForwarder? UDP_FORWARDER_MAXIMUM_TIMEOUT is the maximum value. Recommended 10 seconds.
  115. /// \param[in] serverSelectionBitstream If you want to send data to UDPProxyCoordinator::GetBestServer(), write it here
  116. /// \return true if the request was sent, false if we are not connected to proxyCoordinator
  117. bool RequestForwarding(SystemAddress proxyCoordinator, SystemAddress sourceAddress, SystemAddress targetAddressAsSeenFromCoordinator, RakNet::TimeMS timeoutOnNoDataMS, RakNet::BitStream *serverSelectionBitstream=0);
  118. /// Same as above, but specify the target with a GUID, in case you don't know what its address is to the coordinator
  119. /// If requesting forwarding to a RakNet enabled system, then it is easier to use targetGuid instead of targetAddressAsSeenFromCoordinator
  120. bool RequestForwarding(SystemAddress proxyCoordinator, SystemAddress sourceAddress, RakNetGUID targetGuid, RakNet::TimeMS timeoutOnNoDataMS, RakNet::BitStream *serverSelectionBitstream=0);
  121. /// \internal
  122. virtual void Update(void);
  123. virtual PluginReceiveResult OnReceive(Packet *packet);
  124. virtual void OnRakPeerShutdown(void);
  125. struct ServerWithPing
  126. {
  127. unsigned short ping;
  128. SystemAddress serverAddress;
  129. };
  130. struct SenderAndTargetAddress
  131. {
  132. SystemAddress senderClientAddress;
  133. SystemAddress targetClientAddress;
  134. };
  135. struct PingServerGroup
  136. {
  137. SenderAndTargetAddress sata;
  138. RakNet::TimeMS startPingTime;
  139. SystemAddress coordinatorAddressForPings;
  140. //DataStructures::Multilist<ML_UNORDERED_LIST, ServerWithPing> serversToPing;
  141. DataStructures::List<ServerWithPing> serversToPing;
  142. bool AreAllServersPinged(void) const;
  143. void SendPingedServersToCoordinator(RakPeerInterface *rakPeerInterface);
  144. };
  145. //DataStructures::Multilist<ML_UNORDERED_LIST, PingServerGroup*> pingServerGroups;
  146. DataStructures::List<PingServerGroup*> pingServerGroups;
  147. protected:
  148. void OnPingServers(Packet *packet);
  149. void Clear(void);
  150. UDPProxyClientResultHandler *resultHandler;
  151. };
  152. } // End namespace
  153. #endif
  154. #endif // _RAKNET_SUPPORT_*
粤ICP备19079148号