Skip to content
This repository has been archived by the owner on Aug 15, 2022. It is now read-only.

NAT Hole Punching

Praneet Sahgal edited this page Sep 9, 2021 · 6 revisions

NAT hole punching is a way for users behind a firewall to connect to each other, without requiring them to open their firewall ports on their router. To do this, you use a special server that is dedicated to registering hosts and keeping an open communication with game hosts. When a client requests to join a host that is behind a NAT, they will communicate with the NAT service host. This NAT service host will then delegate the request to the game host, which then begins communication with the requesting client.

Background

About NAT

Most computers don't connect to the internet directly. Instead, they use Network Address Translation (NAT). Network Address Translation maps a single IP address on the "open internet" (technically called a wider area network, or WAN) to a local area network (LAN). Most users encounter NAT when using a router to connect to their internet service provider. The router maps a single global IP address, assigned to you by your ISP, to the local IP addresses for all of the devices in your home. "NAT" is often used to refer to both the NAT protocol and the device performing network address translation.

By default, most NAT devices will allow any outbound connections, letting you load websites and connect to dedicated game servers, but they will block most inbound connections, such as direct connections from one player to another. Port forwarding is used to configure a NAT device to allow inbound connections from the open internet. It tells your NAT device that a connection from the open internet on a specific port (or range of ports) should be forwarded to a machine on the LAN.

There are four NAT variations, described in the official specification for NAT, RFC 3489.

How NAT Hole Punching Works

If a user makes an outbound connection to a specific IP address on a specific port, by default, a NAT device will allow inbound connections from that IP address on that same port number. NAT hole punching uses this behavior to establish a connection between two machines. Each machine sends data to the other on a specific port number. The first packet will be dropped, but later packets will go through. To make sure both machines are using correct port numbers, a third machine is used. This machine is hosted on the open internet and acts as a "relay" or "rendezvous" server.

Here's the high-level steps of the process. In these steps, the host and the client are behind a NAT, while the relay server is on the open internet.

  1. The host opens a web socket on a specific port, waiting for inbound connections.
  2. The host registers itself with the relay server. The relay server notes the IP address of the host, and the port on the host that is waiting for a connection.
  3. The client opens a web socket on a specific port, waiting for inbound connections.
  4. The client connects to the relay server, requesting a connection to the host's IP address and port. The relay server notes the client's IP address and the port on the client that is waiting for a connection.
  5. The relay server tells the host to connect to the client's IP address on the client's port. The host does so. The first packet sent will "punch a hole" on the host.
  6. The client sends a packet on the web socket to the host's IP address and open port. The first packet sent will "punch a hole" on the client.
  7. With both holes "punched", traffic can flow between both machines. The relay server is no longer needed.

Limitations of Hole Punching

NAT hole punching only works on Normal (Full Cone) NAT, Restricted Cone NAT, and Port Restricted Cone (NAT). It does not work on Symmetric NAT, which is used in most commercial settings. NAT hole punching also may not work on cellular networks, which uses carrier-grade NAT instead.

If you're using NAT hole punching, you should expect that some of your game's users will still have issues connecting to other hosts. You should instruct those users to forward a port on their router to address those issues.

Alternatives to Hole Punching

Modern routers support protocols to temporarily forward ports, such as Universal Plug and Play (UPnP), Port Mapping Protocol (NAT-PMP), and Port Control Protocol (PCP). Forge Networking doesn't support these protocols, but you can use a library such as Open.NAT to configure temporary port forwarding at runtime. Not all routers support these protocols, and some users will have UPnP disabled for security reasons. However, these protocols don't require the use of a NAT hole punch server.

In rare cases where NAT hole punching will not work, a proxy server can be used instead. The host connects to the proxy server, and the proxy server relays all of the packets from a client to the host. Forge Networking does not provide a proxy server implementation.

Dedicated game servers do not require NAT hole punching, as all users connect to machines hosted on the open internet, with the appropriate ports already forwarded.

Using NAT Hole Punching In Forge Networking

Video Tutorial On How To Test

Click me!

Downloading the NAT Hole Punch Server

The NAT Hole Punch Server can either be built from source in the project repo, or downloaded from the nightly builds.

To build the project from source using Visual Studio, follow these steps:

  1. Clone the repo.
  2. Copy all of the files from Forge Networking Remastered Unity/Assets/Bearded man Studios Inc/Scripts/Networking into the folder BeardedManStudios/Source.
  3. Open either NatHolePunch/NatHolePunch.csproj or NatHolePunch_Core/NatHolePunch_Core.csproj. This will create a new solution.
  4. Remove any project references and dependencies that aren't needed, such as Steamworks.NET.
  5. Add a project dependency for the NAT Hole Punch project, BeardedManStudios/BeardedManStudios.csproj. For instructions on how to add project dependencies in a solution, refer to this page.
  6. Add a project reference for the NAT Hole Punch project to the same BeardedManStudios project. To manage project references, refer to this page. Project references are separate from dependencies. You may need to remove an existing reference first.
  7. Add a project dependency and reference to the BeardedManStudios project, ForgeNetworkingCommon/ForgeNetworkingCommon.csproj. You may need to remove an existing reference first.
  8. Build the entire solution. You should now be able to run the NatHolePunch application.

Configuring Your Game to Use the Server

When you look at the Connect method of the UDPServer and UDPClient classes, you will notice that there are 2 optional parameters related to NAT traversal. One is the NAT host address and the other is the NAT server port. When you provide a NAT host address to the Connect method on a UDPServer object, you will tell the server where it needs to register itself as a host. When you provide a NAT host address to the Connect method on a UDPClient object, you will be telling the client to communicate with that specific NAT host to open communications with the desired server.

Setting the correct NAT host in the Connect method of the UDPServer and UDPClient is all you will need to do in your Unity project in order to enable NAT hole punching in your application.

You can safely include the NAT host address and server port even if you're connecting over LAN. The host and client will still communicate with the NAT hole punch server, but since they're on the same LAN, they'll be able to connect to each other anyway.

Troubleshooting

  • If you're on Windows, make sure the firewall settings are allowing traffic. Double-check whether you've set your current network to "public" or "private", and review the firewall settings to make sure your game is allowed to communicate on the current network type. You can also review the application-specific rules to see exactly what ports and protocols are open. For more information, refer to this page.
  • If you're hosting the NAT hole punch server in the cloud, make sure you've opened a port for the correct protocol. If you're using UDPServer and UDPClient in your game code, but have opened a port on TCP for your NAT hole punch server, connections will fail.
  • If you're using a tether to a cell network to test out NAT hole punching, keep in mind that hole punching may not work with your cellular provider. You may need to use another home network to test.

Home

Getting Started
Network Contract Wizard (NCW)
Network Object
Remote Procedure Calls (RPCs)
Unity Integration
Basic Network Samples
Scene Navigation
NetWorker
Master Server
Web Server
Netcoding Design Patterns
Troubleshooting
Miscellaneous
Forge Networking Alloy
Steamworks
Clone this wiki locally