NAT (Network Address Translation) technology is an integral component of modern internet infrastructure, but it creates certain obstacles for direct device-to-device connections. In this article, we look a solving this problem from many angles: from NAT Punch-Through to Relay Fallback, and more.
Hello again! I'm Dmitrii Ivashchenko, Lead Software Engineer at MY.GAMES. In this part of our ongoing series, "Unity Realtime Multiplayer", we'll delve into the effects of NAT on realtime multiplayer games.
Previously, we discussed the TCP, UDP, and WebSocket protocols, which allow for establishing a connection between player devices for data exchange. However, establishing a direct connection between two devices located on opposite sides of the planet is not an easy task. This is due to a number of technological and infrastructure limitations, including mechanisms like Network Address Translation (NAT).
NAT is a fundamental technology used to manage IP addresses. It's commonly used with routers to translate local network addresses (private IP addresses) to global IP addresses on the internet (and vice versa). It allows a single IP address to represent multiple devices in a local network, creating a layer of abstraction that effectively isolates each device.
There are different types of NAT, including:
While NAT is important for preserving limited public IP address resources and ensuring security, NAT also creates obstacles to establishing direct connections between devices on different networks.
NAT Punch-through
Conclusion
NAT Punch-through, also known as hole punching, opens a direct connection without port forwarding. When successful, clients can connect directly to each other to exchange packets.
However, depending on the types of NAT between clients, this often fails. There are various NAT Punch-through methods, including TCP and UDP Hole Punching, ICMP, and STUN.
TCP Hole Punching is a method used to establish a direct TCP connection between two devices, each of which is behind its own NAT. This requires the assistance of a central server, which is usually called an introduction server.
]
Here are the steps in this process:
Server request: As with other hole-punching techniques, both devices (let's call them Device A and Device B) start the process by connecting to the input server.
Information exchange: The input server exchanges information between Device A and Device B; it passes the public IP address and port of each device to the other device.
Connection attempt: Each device attempts to establish a TCP connection with the other; usually one device (let's say Device A) starts with an active opening of the connection, while the other device (Device B) starts with a passive opening.
Hole punching: Device A sends a TCP SYN packet (connection request) to Device B. At the same time, Device B is already waiting for an incoming connection from Device A. This creates a "hole" in the NAT of each device, allowing incoming traffic to pass through.
Connection established: Finally, when the SYN packet from Device A reaches Device B through the hole in its NAT, it will respond with a SYN-ACK packet (connection request acknowledgment). Device A will then complete the handshake process by sending an ACK packet (acknowledgment).
Data exchange: Now that the TCP connection is established, the devices can exchange data directly, bypassing the input server.
Like other hole-punching techniques, the success of TCP Hole Punching depends on the specific NAT configuration and network security policy. Some NATs may not allow this method to work correctly.
UDP Hole Punching is similar to TCP Hole Punching but uses the UDP protocol. UDP Hole Punching is usually considered a simpler and more reliable hole-punching method compared to TCP Hole Punching because there is no need for the complex "handshake" procedure required to establish TCP connections. Instead, UDP packets can be simply sent and received without prior connection establishment. However, in the end, the choice of method for Hole Punching will be determined by the network infrastructure between your players.
ICMP Hole Punching is a technique used to create direct connections between two devices behind NAT. This process usually requires the intervention of a third device, called an "introducer server", which assists in establishing the connection.
Here's how it works, step by step:
Server Request: Both devices (let's call them Device A and Device B) initiate the process by contacting an input server. This establishes a "hole" in each device's NAT, allowing incoming traffic to pass through.
Information Exchange: The input server exchanges information between Device A and Device B, passing along each device's public IP address and port to the other.
Connection Attempt: Now that each device knows the other's public IP address and port, they can attempt to establish a direct connection. They do this by sending an ICMP Echo Request (typically used for "ping") to the other device's address and port.
Connection Establishment: If each device's NAT allows incoming ICMP traffic, these Echo Requests will pass through the "holes" in the NATs created during the initial connection to the input server. This allows a direct connection to be established between Device A and Device B.
Data Exchange: Once the connection is established, the devices can begin exchanging data directly, bypassing the input server.
It's important to note that the effectiveness of ICMP Hole Punching depends on the specific NAT configuration and network security policies. Some NATs or firewalls may block incoming ICMP traffic, rendering this technique unusable.
STUN is a tool for communication protocols that allows detecting and overcoming network addresses that are on the path between two endpoints. It is implemented as a lightweight client-server protocol that requires only simple requests and responses with a third-party server located on a shared, easily accessible network, usually the Internet.
The main protocol works as follows: the client, usually operating in a private network, sends a request to bind to a STUN server on the open Internet. The STUN server responds to the client, including the IP address and port number observed from the server's point of view.
Here's how STUN works step by step:
STUN server request: The device (usually called a client) sends a request to the STUN server. This request goes through the device's NAT.
Determining NAT type and public IP: When the request reaches the STUN server, the server analyzes how the request reached it. It determines the public IP address that was used to send the request (this is the IP address of the NAT device), and information about ports. It also determines NAT type using various tests (e.g. checking if NAT changes the port with every new connection).
STUN server response: The STUN server then sends a response back to the device with information about its public IP address and port, as well as NAT type.
Using the information: Having received the response, the device knows its public IP address and port visible on the Internet, as well as the NAT type used by its network. This information can be used to establish direct connections with other devices on the Internet (e.g. when using NAT Punch-through technology).
STUN messages are sent in User Datagram Protocol (UDP) packets. Since UDP does not provide reliable guaranteed delivery, the retransmission of STUN requests is controlled by the application to achieve reliability. STUN servers do not implement reliability mechanisms for their responses. If reliability is required, the Transmission Control Protocol (TCP) can be used, but this leads to additional network overhead.
It is important to note that the STUN protocol may not work in some scenarios, especially when using stricter types of NAT.
Despite the existence of various hole-punching techniques, a direct connection between two devices on a network is not always possible. In such cases, a backup option in the form of a relay server is often used.
This option combines NAT traversal with a backup relay. Here, clients first attempt to connect to the host using NAT traversal, and if unsuccessful, they switch to the relay server. This reduces the load on the relay server, which allows clients to still connect to the host.
It's important to understand the impact of NAT on the development of real-time multiplayer game connections. Although NAT technology is an integral component of the modern internet infrastructure, it creates certain obstacles for direct device-to-device connections. This necessitates the use of various techniques such as NAT Punch-Through and Relay Fallback to provide the best gaming experience.
However, the development and optimization of networked multiplayer games is not limited to managing connections alone. The next — important — step is preparing and sending data over the network. In our next article, we'll discuss the principles of efficient data encoding and compression for networked games.