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.

Some 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 internal address of a client named private address to its own address (router IP and random port) named public address, because only the public address is visible from the public Internet. This translation is internally stored in the router’s NAT mapping table. The router uses the public address to connect to the destination address. When the router gets the destination’s response, it identifies the actual client by looking up the translated private address with the public address in the mapping table.

There is no possibility to connect to a client behind a NAT router directly because the private address 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.

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

If both clients send a request to the rendezvous server, the public address is known because the source address of the packet contains the public address of the client. These informations will be exchanged to both clients. With getting the public address a client can try to connect to the other client, which private address is hidden by the router.

Both transport protocols, TCP and UDP can be used for the hole punching process.
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: P2P NAT and NAT Traversal Techniques in Peer to Peer Networks

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 of client 1 first request send to the rendezvous server.

Client 1 opens a socket with the private address (192.168.1.1:333) and makes a connection to the rendezvous server with the public address (83.56.3.21:444); now the source address ot the packet is 192.168.1.1:333 and the destination address of the packet is 83.56.3.21:444. But the NAT router uses the mapped public address (79.34.5.23:444; 444 is any free random port) as the source address of the packet to make the connection to the server.
The Router holds the Mapping Information from the private client address (192.168.1.1:333) to the public address (79.34.5.23:555) 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 (79.34.5.23:555) 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: P2P NAT and NAT Traversal Techniques in Peer to Peer Networks

There are some limitations of the hole punching process by different NAT router types, which should be also considered

1. Full Cone NAT

Restriction
This router has no further restrictions; a mapping is done on the router side by sending a request to a destination address. Any host on the Internet can use the public address of the client to connect to the client behind the router, which uses the mapping without restrictions. All you need to consider for the UDP approach is that the router can discard the mapping after a time out.

Solution Experiment
For UDP approach send keep-alive packets.

2. Restricted Cone NAT

Restriction
Additionally 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.

Solution Experiment
First send a packet to the public address of the client trying to send the request.

3. Port-Restricted Cone NAT

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

Solution Experiment
Reuse of the private socket address used to connect to the rendezvous server and send a request to the public address of the other socket used by the other client 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 this is not possible on all operating systems.

4. Symmetric NAT

Restriction
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 private port.

Solution Experiment
In the most cases not possible.
An interesting article about Symmetric NAT and hole punching 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. For both the actor and the reactor it will be used the same private address, which was used to send the request to the rendezvousserver.
For using the same address in Java after a short time the previous socket bound to that address was closed, you have to set the reuseAddress-Flag on the socket to true. Note, this setting does not allow to open two sockets bound to the same address at the same time, but to open a new socket in a short time to the same address bound to the socket which was closed before.
The reactor will use the previous used private address to send periodically some requests to the public address of the actor and the actor will use the previous used private address to listen for incoming requests.

Example Applications Usage

1. Start the rendezvous server:

java -jar rendezvousserver.jar  <time(ms) to wait for reactor>

The first parameter 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 first to add a port forwarding rule on that router to make the server reachable directly.
The second parameter <time(ms) to wait for reactor> is the time in milliseconds which will be waited for the connection of the reactor.

2. Start the actor:

java -jar actor.jar

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

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 files to the example can be downloaded as packed zip-file:
actor/reactor jar-file and the rendezvousserver jar-file .

Also the complete source code can be downloaded as eclipse-maven project .

Conclusion

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.

References

P2P NAT

NAT Traversal Techniques in Peer to Peer Networks

NAT – Network Address Translation

A New Method in Symmetric NAT Traversal in UDP and TCP.

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert