What is the difference between a server and a client? Those of you who have tried to explain this difference to non-technical people will have found it difficult, people seem always to think of servers to be different, huge machines sitting in some climatized room, they are disappointed when I tell them that even my Notebook can be used as a Server. For the purpose of this article a server will be simply a computer that offers some services over the network.
So why can’t every client be a server? A basic rule for servers is that they have to be reachable over the network, clients on the other hand don’t require this and most of aren’t either. The trend is going away from the classic layout where a computer would be connected directly to the internet using a Modem, and towards the small family networks, using wireless structures and requiring another layout:
Thus more and more computers on the network become unreachable from the outside, allowing them to be contacted often requires complex configurations on the NAT (Network Address Translation), and sometimes the simple user can’t do this. This is deadly for P2P! P2P is another approach to offering services, away from the Client-Server paradigm, in this new Network every Client is a Server in the meantime, it is used to distribute the service it’s using to other clients (often called peers since “Client” refers to the Client-Server paradigm). P2P is proving stronger than the Server modell, and is having a huge success amongst all kinds of Companies (no, I’m not only talking about FileSharing) it can be used in many different applications and is cheaper than having to buy huge dedicated machines.
Ignoring all those shielded and unreachable peers is a huge waste of resources, and we absolutely have to find a way to deal with this problem.
The Solution is NAT-Hole-Punching (also called UDP-Hole-Punching, but it is also applicable for TCP/IP) it is a way to reach otherwise unreachable hosts, with a minimal additional effort. All you need is a Peer that is reachable by both Peers that want to establish a connection that coordinates the connections. But let’s start from the beginning. Routers use a NAT-table to decide the packages to drop and those that are to be redirected to a host in its network. When a Computer in the network behind a router wants to open a connection to another computer a SYN-packet is sent to the server, through the router, and the router will register in its NAT-Table that all responses from the ip:port combination will be redirected to the client. Now the problem is if both peers are behind a Router:
Wether Peer A or Peer B try to open a connection it will fail because the other Router will drop the unrequested packets. Now the idea is that both Peers punch a hole in the NAT of their router (punching is a bit a hard word for it, they just tell the router that they want the packets to a certain port to be redirected to them). But ports for outgoing connections are assigned by the Operating System randomly, so what we do is:
- Create a socket as we usually would in our program
- Get the port this socket is bound to
- Inform a transaction handler what our IP:Port combination is
- The transaction handler will tell the foreign host this combination and the same way we get the information from the foreign host
- Now that we have all the required information we start sending specifically crafted packets with source ip and port we told the transaction handler earlier, and destination ip and port the information we got from the transaction handler.
- Eventually one of the two routers will have the hole we were looking for and the packets from the other peers will finally reach the destination, thus the communication has been established.
In the entire process the only precondition is that we have a Peer that is reachable by both Peers, that will act as a transaction handler, this is already given in most of the layouts as for example a Chat where the peers are connected to a central server, MSN which could act as a transaction handler too, or a BitTorrent Tracker. The load on the transaction handler is minimal and does not affect the performance of the P2P Concept, because once the connection is established, the peers become completely independent from the transaction handler.
NAT-Hole-Punching does not weaken the protection that a Firewall or Router gives to its users as for a communication to be established an action from the inside must be taken to open the connection. It still remains difficult or even impossible to open unrequested connections to the inside!
In this article we focused on Routers because they are the most common problem for P2P-Communication, but the concepts are also applicable to most kinds of middleboxes as is explained in more detail in the draft at the bottom of this article.
Interesting readings and resources: