Way to bridge two outgoing TCP connections in order to bypass firewalls and NAT

networkingtcp

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?

Best Answer

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.