Peer to Peer – Hole Punching

Peer to Peer – Hole Punching

This article should only give you a little introduction to the hole punching process and not a complete composition of all technical details.

First I want to show you why peer to peer (P2P) networks are very important for many Internet applications.
One of the most important P2P applications is Skype, originally named “Sky peer-to-peer”, but many other applications like chats, VoIP or multiplayer games need fast, direct connections between peers. But for most Internet users direct connections are not possible because their IP is hidden by a NAT router. Routers use NAT to provide all users on a LAN with an Internet connection using only one public IP address. Such a router acts like a firewall because only the public IP is reachable from the Internet. If a user behind a NAT router wants to be accessible from the Internet, the router has to be manually configured by adding a port forwarding rule.

Many readers know P2P file sharing networks like Napster or Emule which could only be fully used by configuring such a port forwarding rule, so data can be transferred directly from one client/peer to another client/peer.
But reconfiguring routers is tedious and in some environments not even possible due to missing access rights. Therefore Skype and other P2P networks use other technologies to allow direct connections without the need to change router configurations.

What are the possibilities of Internet applications to make connections between clients sitting behind NAT routers?

1. Use of a Public Connection Server
One approach is the use of a server with a public IP which can be accessed directly by the clients. This Server can be contacted by the two clients and transfers the traffic from one client to the other client. One big disadvantage of this solution is the high waste of server resources and the waste of bandwidth because there is no real direct connection between the clients. But in some environments it may be the only solution instead of changing the router configuration.

2. Hole Punching
Another solution, allowing connections between two clients behind NAT routers, tries to utilize the internal router processes.

A NAT router translates the source address of a client (IP and port) to its own source address (router IP and random port). This translation is internally stored in the router’s NAT mapping table. The router uses the translated source address to connect to the destination address (IP and port). When the router gets the destination’s response, it identifies the actual client by looking up the translated source port in the mapping table.

There is no possibility to connect to a client behind a NAT router directly because the IP of the client is not visible on the Internet. But knowing that the Router has an internal mapping table we can “punch a hole” into the router to make the client visible on the Internet.

To connect to a client behind a router we first need to know the public address of the router (IP and port).
This information can be obtained by using a rendezvous server. This server is used by two clients which want to be exchange address information about each other.

The rendezvous server now knows the public address (IP and Port) used by the router of the clients. A client can now use the public address to open a direct connection.

We can use TCP for the hole punching but also UDP can be used as well.
For both approaches the public address of the client is needed and can be obtained by the rendezvous server. Each approach has its own advantages and disadvantages. UDP is connectionless and the router can discard a port mapping, therefore keep-alive messages should be sent periodically. On the other side TCP is more complex and therefore the hole punching process is more difficult. For TCP hole punching the synchronization of sequence numbers of TCP packets should also be managed. For further information please read the following PDFs

The diagram above shows the steps needed to connect to a client behind a NAT router.
As you can see client 2 connects to client 1 using the public address (IP and port) of client 1′s request to the rendezvous server.

Client 1 on IP opens a socket with source port 333 and makes a connection to the rendezvous server with IP on port 444; the source address is and the destination address is But the NAT router uses its own public IP to make the connection to the server and a random free port as the source port (
The Router holds the Mapping Information from the internal client address ( to the public address ( in its own Mapping Table.

The public address of client 1 is now available on the rendezvous server and will be transferred to client 2. Finally client 2 connects to client 1 using the public address received from the rendezvous server.

This is the process of getting the public address of the client which we want to connect to. For TCP/UDP hole punching these address informations are used to send and listen for requests. For more informations about TCP/UDP hole punching, please read the following PDFs ( (

Also there are some limitations of the hole punching by different NAT router types, which should be considered:

Full Cone NAT

This router has no restrictions; a mapping is done on the router side by sending a request to a destination address (IP and port), any host on the Internet can use this mapping to connect to the client behind the router.

Solution Experiment
Not needed.
Restricted Cone NAT

A host on the Internet can only use a mapping for a client behind the router if that client previously sent a packet to any port of the external host.

For the clients which listen for requests, first send a packet to the public address of the client trying to send the request.
Port-Restricted Cone NAT

Restriction Experiment
Additionally the mapping can only be used if the public port of the others host packets matches the destination port of the packet previously sent to the other host. Note that, as for full and address-restricted cone NAT but in contrast to symmetric NAT, the router will always map the internal source address of a packet to the same public address independent of the destination address.

Solution Experiment
Reuse of the socket address used to connect to the rendezvous server and send a request to the public address (IP and port) of the other socket used by the other host to connect to the rendezvous server.

There are also hole punching strategies which use two sockets bound to the same port to simultaneously listen and receive requests. Unfortunately the Reuse of an address (SO_REUSEADDR functionality) is not possible on all operating systems.
Symmetric NAT

In contrast to all other types, a symmetric NAT router will assign a different public address for packets with different destinations even if they have the same internal source port. Otherwise the same restrictions like for a port-restricted cone NAT exist.

Solution Experiment
In the most cases not possible.
An interesting article can be read here.

Example Application
I have implemented a simple Java application which demonstrates TCP hole punching without managing the sequence numbers and without simultaneously sending and listening requests.

According to the three different roles, there is an actor.jar for the role of client 1, a reactor.jar for the role of client 2 and a rendezvousserver.jar for the role of the rendezvous server.
First the actor and later the reactor have to connect to the rendezvous server.

After both clients are connected to the rendezvous server each client will receive the information about the public address of both clients from the rendezvous server. After both clients received the rendezvous information the actor will listen for incoming requests and the reactor will send some packets attempting the hole punching.

Example Applications Usage

1. Start the rendezvous server:
java -jar rendezvousserver.jar 1234 120000

The first parameter (1234) is the port of the rendezvous server. You can use any Port which is directly accessible from the Internet. If the rendezvous server sits behind a router, you have to add a port forwarding rule on that router to make the server reachable directly.
The second parameter is the time in milliseconds which will be waited for the connection of the reactor.

2. Start the actor:
java -jar actor.jar 1234

The first parameter is the IP of the rendezvous server.
The second parameter is the port of the rendezvous server.

3. Start the reactor:
java -jar reactor.jar 1234

The first parameter is the IP of the rendezvous server.
The second parameter is the port of the rendezvous server.

In the console output you can see if the punching process is successful or not.

All Jars and the complete source-code as a Maven project can be downloaded from LINK

There is not much information on the Internet about hole punching. One reason might be that it can be used to bypass the firewall functionality delivered by a NAT router.
Some administrators therefore do not like Skype and similar applications and do not allow them.
But for many applications hole punching is the only way to make the application conveniently useable without the need to configure the users NAT router.



  1. Jerry

    The link is shown in Deutch version of page.

  2. Leo

    I know now. Sorry for the comment before.
    The links appear on the de page, not on english.

  3. Leo

    Thanks for your work.
    May I know where the download link is ?

  4. patric cena

    Hi Martin,
    Thanks for your post. Can I get the download link for above mentioned jar. my email id is

    • patric cena

      Hey Sorry found the link. Actually my page was not loaded properly. Thanks Anyway.

Leave a Reply

Your email address will not be published. Required fields are marked *