NAT and Peer-to-peer networking

Peer-to-peer is a style of networking in which a group of computers communicate directly with each other, rather than through a central server. This is often used for multiplayer online games, such as Activision's Battlezone, to avoid the expense and delay of handling all that traffic at the server. However, this style of networking often has problems dealing with Network Address Translators (NATs). In this page, I describe a way to solve these problems. Products that use this technique now work properly through several commercial NATs.

The situation

The Internet is based on 32-bit IP (Internet Protocol) addresses, which means the theoretical maximum number of computers on the Internet is 4 billion or so. The practical limit is much lower, due to inefficiences in how IP addresses are used. In fact, the Internet may be only a few years away from running out of IP addresses.

As IP addresses become scarce, a technique known as Network Address Translation, or NAT, was developed to allow the use of a single IP address for a whole network of computers.

A NAT sits inbetween the public Internet and the network it serves, and works by rewriting IP addresses and port numbers in IP headers on the fly so the packets all appear to be coming from (or going to) the single public IP address of the NAT device instead of the actual source or destination.

NAT is now commonly employed in small home-office routers and in software used by consumers to connect several personal computers to a single cable modem. It is even used by some Internet Service providers.

(NAT is not the only possible solution; proxy servers are also commonly used, but require more configuration, and sometimes require custom client software. Eventually, we'll all switch to IPv6, which will have 128-bit addresses, and will solve the problem once and for all, but that's probably not going to be commonplace for many years.)

Some Protocols Aren't NAT-Friendly

Some applications send IP addresses or port numbers hidden inside their datapackets, where NAT can't properly rewrite them - so those applications don't work when you try to use them on computers behind NATs.

Some NATs, for security reasons, only allow incoming traffic from an outside address if an outgoing packet has already been sent to that outside address. This means that two people behind different NATs can't open up connections to each other in the usual way - ever!

The solution

Peer-to-peer protocols that wish to be NAT-friendly must be aware that any addresses they embed in their data packets may be invalid once the packets pass through the NAT, and compensate accordingly. One way to do it is as follows:

All traffic between the peers is done via a single UDP port. There is an address server which is not behind any NAT. Users connect to the address server first, and send it the IP address they think they have; the server notes both that address and the address it sees in the UDP header. The server then sends both addresses to the other peers. At this point, everyone knows everyone else's address(es).

To open up peer-to-peer connections, all old peers send a UDP packet to the new peer, and the new peer sends a UDP packet to each of the old peers. Since nobody knows at first whether they are behind the same NAT, the first packet is always sent to both the public and the private address.

This causes everyone's NAT to open up a bidirectional hole for the UDP traffic to go through. Once the first reply comes back from each peer, the sender knows which return address to use, and can stop sending to both addresses.

Compatibility Requirements

Above and beyond the basic NAT RFC, a NAT device that wants to support this scheme should have the following desirable property:
NATs should not change the number of UDP ports used by a stream of packets.
Correlary:
If a host behind a NAT sends a series of packets from a single UDP port, the packets as relayed by the NAT should also appear to come from a single host and UDP port.

Draft RFC

I'm working on a draft RFC describing this technique in more detail. Contact me if you're interested.

Compatibility Test Results

I am testing the compatibility of this approach with several NAT implementations. Here are partial results:

Known Compatible NAT Implementations

NAT Implementations Soon to be Compatible

Not yet known to be compatible

Not compatible

Software using this technique

The following peer-to-peer network software packages are known to support operation from behind NATs:

Discussion Area

I'd love to hear what other developers think about this technique, or about how Masq could be rewritten to reuse UDP ports properly. Join the NAT-peer-games mailing list and let's talk.

Wierd problems

While testing Sygate, and later NAT1000, I had some wierd problems. Everything was fine if the machine running the gateway is connected to the Internet via a modem. But if the the gateway machine was connected to the Internet by Ethernet, clients couldn't access other hosts on that outer Ethernet. It's as if packets from the gateway were being utterly ignored by the other hosts on the outside Ethernet. Routers didn't ignore the packets, though, so connecting to distant hosts was no problem. Go figure. See my Usenet post for more info.

I'm inclined to believe this was hardware trouble, but who knows...

Links

History

This is to my knowledge a novel technique. I started working with it in 1997, and shipped my first product using it in 1998. This technique was developed while working on multiplayer games at Activision.
Copyright 1999 Dan Kegel
dank@alumni.caltech.edu
Last updated: 17 July 1999
[Return to www.kegel.com]