#include <NatPunchthrough.h>
Public Member Functions | |
NatPunchthrough () | |
Constructor. | |
virtual | ~NatPunchthrough () |
Destructor. | |
void | FacilitateConnections (bool allow) |
bool | Connect (const char *destination, unsigned short remotePort, const char *passwordData, int passwordDataLength, SystemAddress facilitator) |
bool | Connect (SystemAddress destination, const char *passwordData, int passwordDataLength, SystemAddress facilitator) |
void | Clear (void) |
Free internal memory. | |
virtual void | OnAttach (RakPeerInterface *peer) |
virtual void | Update (RakPeerInterface *peer) |
virtual PluginReceiveResult | OnReceive (RakPeerInterface *peer, Packet *packet) |
virtual void | OnShutdown (RakPeerInterface *peer) |
virtual void | OnCloseConnection (RakPeerInterface *peer, SystemAddress systemAddress) |
A NAT (Network Address Translator) is a system that will makes it so your system's IP address is different from the IP address exposed to the internet. This provides some security and allows multiple computers, each with a different IP address, to share one IP address as seen by the internet.
The problem is that NATs also ignore packets sent to them unless they sent a packet to the sender first. If two systems are both behind NATs, then neither system can connect to each other. Furthermore, some NATs will impose a temporary ban on an IP address that send unsolicited packets to them.
This can be solved by using a third system, a facilitator, that is not behind a NAT and that both systems are already connected to. It will synchronize a send between both NAT systems such that the routers will both consider themselves as handling a reply to a message, when in fact they are handing an initial message. As replies are allowed, both systems get their corresponding messages and the connection takes place. S = system that wants to connect F = facilitator R = system to get the connection request.
S knows IP of R in advance. 1. S->F facilitate connection request to R 2. if (R is not is connected) F->S ID_NAT_TARGET_NOT_CONNECTED. Exit. 3. F -> (Ping S, Ping R), every X ms Y times. Wait Max(Ping(s), Ping(r) * multiple ms more, then go to step 4. 4. F picks time highest(ave of Ping R,S) * N from now and sends this time RELIABLE and timestamped to R,S. 5. At time picked in (4), S attempts to connect to R. R sends offline ping to S. 6. If R disconnects before or at step 4, tell this to S via ID_NAT_TARGET_CONNECTION_LOST
void NatPunchthrough::FacilitateConnections | ( | bool | allow | ) |
Call with true to allow other systems to use this system as a NAT punch through facilitator. This takes a little bandwidth but otherwise there is no reason to disallow it. Defaults to true
[in] | allow | True to allow, false to disallow. |
bool NatPunchthrough::Connect | ( | const char * | destination, | |
unsigned short | remotePort, | |||
const char * | passwordData, | |||
int | passwordDataLength, | |||
SystemAddress | facilitator | |||
) |
Call this to start to connect to the specified host (ip or domain name) and server port using facilitator to punch through a NAT This is a non-blocking operation You know the connection is successful when you get the message ID_CONNECTION_ACCEPTED. You know the connection failed when you get the message ID_CONNECTION_ATTEMPT_FAILED, ID_CONNECTION_BANNED, or ID_NAT_TARGET_NOT_CONNECTED Both you and the host must be connected to the facilitator.
Both host and this system must already be connected to the system at the address facilitator and facilitator must be running NatPunchthrough with FacilitateConnections(true) previously called.
[in] | destination | Either a dotted IP address or a domain name of the system you ultimately want to connect to. |
[in] | remotePort | Which port to connect to of the system you ultimately want to connect to. |
[in] | passwordData | A data block that must match the data block on the host. This can be just a password, or can be a stream of data |
[in] | passwordDataLength | The length in bytes of passwordData |
bool NatPunchthrough::Connect | ( | SystemAddress | destination, | |
const char * | passwordData, | |||
int | passwordDataLength, | |||
SystemAddress | facilitator | |||
) |
Same as above, but takes a SystemAddress for a host
[in] | destination | The address of the host to connect to. |
[in] | remotePort | Which port to connect to of the system you ultimately want to connect to. |
[in] | passwordData | A data block that must match the data block on the host. This can be just a password, or can be a stream of data |
[in] | passwordDataLength | The length in bytes of passwordData |
void NatPunchthrough::OnAttach | ( | RakPeerInterface * | peer | ) | [virtual] |
Called when the interface is attached
[in] | peer | the instance of RakPeer that is calling Receive |
Reimplemented from PluginInterface.
void NatPunchthrough::Update | ( | RakPeerInterface * | peer | ) | [virtual] |
Update is called every time a packet is checked for .
[in] | peer | - the instance of RakPeer that is calling Receive |
Reimplemented from PluginInterface.
PluginReceiveResult NatPunchthrough::OnReceive | ( | RakPeerInterface * | peer, | |
Packet * | packet | |||
) | [virtual] |
OnReceive is called for every packet.
[in] | peer | the instance of RakPeer that is calling Receive |
[in] | packet | the packet that is being returned to the user |
Reimplemented from PluginInterface.
void NatPunchthrough::OnShutdown | ( | RakPeerInterface * | peer | ) | [virtual] |
Called when RakPeer is shutdown
[in] | peer | the instance of RakPeer that is calling Receive |
Reimplemented from PluginInterface.
void NatPunchthrough::OnCloseConnection | ( | RakPeerInterface * | peer, | |
SystemAddress | systemAddress | |||
) | [virtual] |
Called when a connection is dropped because the user called RakPeer::CloseConnection() for a particular system
[in] | peer | the instance of RakPeer that is calling Receive |
[in] | systemAddress | The system whose connection was closed |
Reimplemented from PluginInterface.