The idea
alice and bob, each behind a home router doing NAT, ask a rendezvous server where the other is, then talk directly if both send at once: NAT traversal by UDP hole punching. carol, behind a carrier-grade NAT that picks a new port for every destination, cannot join them.
Steps
-
What do I look like from outside?
alice is
10.0.1.10behind aliceRouter (10.0.4.2). A rendezvous server answers with the address and port it saw. A device behind NAT cannot see its own public address, so asking someone outside is the only way to learn what to tell a peer.alice:~# socat - UDP4:10.0.4.10:3478,sourceport=5000,reuseaddr
-
Knowing the address is not enough
Both have checked in, so bob knows alice is at
10.0.4.2:5000. Try the obvious thing first, sending straight there, because seeing why it fails is what makes the trick in the next step make sense.bob:~# nping --udp -g 6000 -p 5000 10.0.4.2 aliceRouter:~# conntrack -L -p udp
Pro
3 more steps in the app
- Punching the hole: both send at once
- A new port for every destination
- Keeping holes open, and relays