Peer to Peer Communication Across NAT - pvgupta24/Jitsi-Meet-Concepts GitHub Wiki

What is p2p?

In a client server interaction, between a client and a server, the same server interacts with different clients in a 2 way relationship. It does not share any information with the other clients downloading at the same time. A peer to peer network on the other hand has multiple point to point connections. A peer to peer (p2p) network builds a layer of redundancy and creates interrelationships between the participants of a p2p protocol. There is a negative side effect in having many clients and one server. This limits the scalability of web servers in a big way. One cannot provision for rare instances of heavy load. The notion of client and server blurs when we enter the p2p world. Every node acts as a server as well as a client. But there is a significant problem here. It is called Network Address Translation or NAT.

How does NAT cause a problem?

Private IP addresses are unroutable and they cannot be participants in a p2p protocol or any Internet client server protocol. However they use the globally unique public IP address allocated to the router or MODEM that does NATing to connect to any server on the Internet. Since many machines share a single(or few) public IP addresses, an ephemeral public port(TCP or UDP) is assigned on the NAT device for communicating with the Internet. This works without hassle when the device is a client and not as a server. The client uses ephemeral ports anyway, so this is not a problem. But in the case of servers, this will not work. One can emulate a fixed port mapping in a machine behind NAT by using a technique known as port forwarding. This involves configuring the router/MODEM to redirect requests coming to a certain public port to a certain private port running in a certain private IP address. In a p2p protocol without port forwarding, this problem can be solved using UDP Hole Punching.

NAT Terminology

A session endpoint for TCP or UDP is an (IP address, port number) pair, and a particular session is uniquely identified by its two session endpoints. From the perspective of one of the hosts involved, a session is effectively identified by the 4-tuple (local IP, local port, remote IP, remote port). Of the various flavors of NAT, the most common type is traditional or outbound NAT, which provides an asymmetric bridge between a private network and a public network. Outbound NAT by default allows only outbound sessions to traverse the NAT: incoming packets are dropped unless the NAT identifies them as being part of an existing session initiated from within the private network. Outbound NAT conflicts with peer-to-peer protocols because when both peers desiring to communicate are “behind” (on the private network side of) two different NATs, whichever peer tries to initiate a session, the other peer's NAT rejects it. NAT traversal entails making P2P sessions look like “outbound” sessions to both NATs. Outbound NAT has two sub-varieties: Basic NAT, which only translates IP addresses, and Network Address/Port Translation (NAPT), which translates entire session endpoints. NAPT, the more general variety, has also become the most common because it enables the hosts on a private network to share the use of a single public IP address. Throughout the discussions we assume NAPT, though the principles and techniques we discuss apply equally well (if sometimes trivially) to Basic NAT.

Relaying

The most reliable but least efficient method of P2P communication across NAT is simply to make the communication look to the network like standard client/server communication, through relaying. Suppose two client hosts A and B have each initiated connections to a well-known server S. Instead of attempting a direct connection, the two clients can simply use the server S to relay messages between them. For example, to send a message to client B, client A simply sends the message to server S along its already-established client/server connection, and server S forwards the message on to client B using its existing client/server connection with B. Relaying always works as long as both clients can connect to the server. Its disadvantages are that it consumes the server's processing power and network bandwidth, and communication latency between the peering clients is likely increased even if the server is well-connected. Nevertheless, since there is no more efficient technique that works reliably on all existing NATs, relaying is a useful fall-back strategy if maximum robustness is desired. The TURN protocol defines a method of implementing relaying in a relatively secure fashion.

Connection Reversal

Some P2P applications use a straight forward but limited technique, known as connection reversal, to enable communication when both hosts have connections to a well-known rendezvous server S and only one of the peers is behind a NAT, as shown in Figure 3. If A wants to initiate a connection to B which is not behind a NAT, then a direct connection attempt works automatically, because B is not behind a NAT and A's NAT interprets the connection as an outgoing session. If B wants to initiate a connection to A, however, any direct connection attempt to A is blocked by A's NAT. B can instead relay a connection request to A through a well-known server S, asking A to attempt a “reverse” connection back to B. Despite the obvious limitations of this technique, the central idea of using a well-known rendezvous server as an intermediary to help set up direct peer-to-peer connections is fundamental to the more general hole punching techniques described next.

UDP Hole Punching

UDP hole punching enables two clients to set up a direct peer-to-peer UDP session with the help of a well-known rendezvous server, even if the clients are both behind NATs.

The Rendezvous Server

Hole punching assumes that the two clients, A and B, already have active UDP sessions with a rendezvous server S. When a client registers with S, the server records two endpoints for that client: the client's private endpoint and the client's public endpoint, each with an IP address and port number. The server might obtain the client's private endpoint from the client itself, and obtain the client's public endpoint from the source IP address and source UDP port fields in the IP and UDP headers of that registration message. If the client is not behind a NAT, then its private and public endpoints will be identical.

Establishing Peer-to-Peer Sessions

Suppose client A wants to establish a UDP session directly with client B. Hole punching proceeds as follows:

  1. A initially does not know how to reach B, so A asks S for help in establishing a UDP session with B.
  2. S replies to A with a message containing B's public and private endpoints. At the same time, S uses its UDP session with B to send B a connection request message containing A's public and private endpoints. Once these messages are received, A and B know each other's public and private endpoints.
  3. When A receives B's public and private endpoints from S, A starts sending UDP packets to both of these endpoints, and subsequently “locks in” whichever endpoint first elicits a valid response from B. Similarly, when B receives A's public and private endpoints in the forwarded connection request, B starts sending UDP packets to A at each of A's known endpoints, locking in the first endpoint that works. The order and timing of these messages are not critical as long as they are asynchronous.

Peers Behind a Common NAT

Suppose that client A uses the hole punching technique outlined above to establish a UDP session with B, using server S as an introducer. Client A sends S a message requesting a connection to B. S responds to A with B's public and private endpoints, and also forwards A's public and private endpoints to B. Both clients then attempt to send UDP datagrams to each other directly at each of these endpoints. The messages directed at the private endpoints do reach their destinations, however, and since this direct route through the private network is likely to be faster than an indirect route through the NAT anyway (if it were possible), and the clients are most likely to select the private endpoints for subsequent regular communication.

Peers Behind Different NATs

In the case of both peers being behind different NATs, first, A sends a request message to S asking for help connecting with B. In response, S sends B's public and private endpoints to A, and sends A's public and private endpoints to B. A and B each start trying to send UDP datagrams directly to each of these endpoints. Since A and B are on different private networks and their respective private IP addresses are not globally routable, the messages sent to these endpoints will reach either the wrong host or no host at all. Now consider A's first message sent to B's public endpoint. As this outbound message passes through A's NAT, this NAT notices that this is the first UDP packet in a new outgoing session. The new session's source endpoint is the same as that of the existing session between A and S, but its destination endpoint is different. If NAT A is well-behaved, it preserves the identity of A's private endpoint. A's first outgoing message to B's public endpoint thus, in effect, “punches a hole” in A's NAT for a new UDP session. B's first message to A's public address, however, similarly opens a hole in B's NAT, for a new UDP session. Once the first messages from A and B have crossed their respective NATs, holes are open in each direction and UDP communication can proceed normally. Once the clients have verified that the public endpoints work, they can stop sending messages to the alternative private endpoints.