/* * Copyright (c) 2014, Oculus VR, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ /// \file /// \brief A RakNet plugin performing networking to communicate with UDPProxyServer. It allows UDPProxyServer to control our instance of UDPForwarder. /// #include "NativeFeatureIncludes.hpp" #if _RAKNET_SUPPORT_UDPProxyServer==1 && _RAKNET_SUPPORT_UDPForwarder==1 #ifndef __UDP_PROXY_SERVER_H #define __UDP_PROXY_SERVER_H #include "Export.hpp" #include "RakNetTypes.hpp" #include "PluginInterface2.hpp" #include "UDPForwarder.hpp" #include "RakString.hpp" namespace RakNet { class UDPProxyServer; /// Callback to handle results of calling UDPProxyServer::LoginToCoordinator() /// \ingroup UDP_PROXY_GROUP struct UDPProxyServerResultHandler { UDPProxyServerResultHandler() {} virtual ~UDPProxyServerResultHandler() {} /// Called when our login succeeds /// \param[out] usedPassword The password we passed to UDPProxyServer::LoginToCoordinator() /// \param[out] proxyServer The plugin calling this callback virtual void OnLoginSuccess(RakNet::RakString usedPassword, RakNet::UDPProxyServer *proxyServerPlugin)=0; /// We are already logged in. /// This login failed, but the system is operational as if it succeeded /// \param[out] usedPassword The password we passed to UDPProxyServer::LoginToCoordinator() /// \param[out] proxyServer The plugin calling this callback virtual void OnAlreadyLoggedIn(RakNet::RakString usedPassword, RakNet::UDPProxyServer *proxyServerPlugin)=0; /// The coordinator operator forgot to call UDPProxyCoordinator::SetRemoteLoginPassword() /// \param[out] usedPassword The password we passed to UDPProxyServer::LoginToCoordinator() /// \param[out] proxyServer The plugin calling this callback virtual void OnNoPasswordSet(RakNet::RakString usedPassword, RakNet::UDPProxyServer *proxyServerPlugin)=0; /// The coordinator operator set a different password in UDPProxyCoordinator::SetRemoteLoginPassword() than what we passed /// \param[out] usedPassword The password we passed to UDPProxyServer::LoginToCoordinator() /// \param[out] proxyServer The plugin calling this callback virtual void OnWrongPassword(RakNet::RakString usedPassword, RakNet::UDPProxyServer *proxyServerPlugin)=0; }; /// \brief UDPProxyServer to control our instance of UDPForwarder /// \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.
/// The class to forward messages is UDPForwarder, and it is triggered over the network via the UDPProxyServer plugin.
/// The UDPProxyServer connects to UDPProxyServer to get a list of servers running UDPProxyServer, and the coordinator will relay our forwarding request. /// \ingroup UDP_PROXY_GROUP class RAK_DLL_EXPORT UDPProxyServer : public PluginInterface2 { public: // GetInstance() and DestroyInstance(instance*) STATIC_FACTORY_DECLARATIONS(UDPProxyServer) UDPProxyServer(); ~UDPProxyServer(); /// Sets the socket family to use, either IPV4 or IPV6 /// \param[in] socketFamily For IPV4, use AF_INET (default). For IPV6, use AF_INET6. To autoselect, use AF_UNSPEC. void SetSocketFamily(unsigned short _socketFamily); /// Receives the results of calling LoginToCoordinator() /// Set before calling LoginToCoordinator or you won't know what happened /// \param[in] resultHandler void SetResultHandler(UDPProxyServerResultHandler *rh); /// Before the coordinator will register the UDPProxyServer, you must login /// \pre Must be connected to the coordinator /// \pre Coordinator must have set a password with UDPProxyCoordinator::SetRemoteLoginPassword() /// \returns false if already logged in, or logging in. Returns true otherwise bool LoginToCoordinator(RakNet::RakString password, SystemAddress coordinatorAddress); /// \brief The server IP reported to the client is the IP address from the server to the coordinator. /// If the server and coordinator are on the same LAN, you need to call SetServerPublicIP() to tell the client what address to connect to /// \param[in] ip IP address to report in UDPProxyClientResultHandler::OnForwardingSuccess() and UDPProxyClientResultHandler::OnForwardingNotification() as proxyIPAddress void SetServerPublicIP(RakString ip); /// Operative class that performs the forwarding /// Exposed so you can call UDPForwarder::SetMaxForwardEntries() if you want to change away from the default /// UDPForwarder::Startup(), UDPForwarder::Shutdown(), and UDPForwarder::Update() are called automatically by the plugin UDPForwarder udpForwarder; virtual void OnAttach(void); virtual void OnDetach(void); /// \internal virtual void Update(void); virtual PluginReceiveResult OnReceive(Packet *packet); virtual void OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason ); virtual void OnRakPeerStartup(void); virtual void OnRakPeerShutdown(void); protected: void OnForwardingRequestFromCoordinatorToServer(Packet *packet); DataStructures::OrderedList loggingInCoordinators; DataStructures::OrderedList loggedInCoordinators; UDPProxyServerResultHandler *resultHandler; unsigned short socketFamily; RakString serverPublicIp; }; } // End namespace #endif #endif // _RAKNET_SUPPORT_*