We're all familiar with the problem of port-forwarding and NAT: if you want to expose something to accepting an incoming connection, you need to configure port-forwarding on the router or conjure up some other black magickery to "punch holes" in the firewall using UDP or something. I'm fairly new to the whole "hole-punching" concept so could someone explain how it works?

Essentially, I'd like to understand how hole-punching would work and the theory behind it, as well as if two TCP connections could be bridged via a third party. Since there's no issue with outgoing TCP connections since it's handled with NAT, could a third party bridge the connections so that the two parties are still connected but without the bandwidth cost of traffic going through the third party?

migrated from stackoverflow.com Nov 20 '11 at 1:12

This question came from our site for professional and enthusiast programmers.


This is not really a stackoverflow thing, but it certainly can be done and I have written programs to do it.

Essentially you have a program, I will describe the threaded solution. Two threads accept (same port, different ports, whatever). When both threads have a connection, they enter a mode where they read from their socket and write to the other socket. When one receives EOF the other is shutdown() so that half-open connections are supported.

Simple and easy.

Karl makes a good point that I misread the question. He didn't want the traffic going through a third party. Well, this is a solvable problem. If you have outbound UDP connectivity without source port mapping, you can arrange for both parties to send a UDP packet which would then allow UDP connectivity back and forth. Run something like openvpn over that UDP channel and you are all set.

If you do not have UDP connectivity, then you realistically can only do it if you can observe the external traffic (post NAT) and have access to a third party who can forge arbitrary packets. That third party can forge a SYN-ACK in both directions and both sides would think the other was the server. This does not work if the source port is changed by both NAT systems since the other party cannot deterministically figure out the proper destination port to use.

  • If it doesn't belong here, where should it go? Could this method be used to connect machines behind private networks over SSH? – Naftuli Kay Aug 10 '11 at 20:20
  • If you have outbound ssh access on both sides to a common server which you can log into, you can make the connection entirely with ssh and don't need to write any code. But yes. Any time people have unfiltered network access to a common system they control, they can have full arbitrary network connectivity. Even a VPN if they have root on the two end-nodes. – Seth Robertson Aug 10 '11 at 20:25
  • 2
    This solution doesn't meet the "without the bandwidth cost of traffic going through the third party" criteria. – Karl Bielefeldt Aug 10 '11 at 20:39
  • Good point. I edited the answer. – Seth Robertson Aug 10 '11 at 22:35

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.