- can't decide on a port in the same message
- don't suffer from NAT port randomization
I'm not saying it will never happen, but the Venn diagram of this being the minimum complexity solution just doesn't seem very large?
The real problem is the port randomization if any client is behind a symmetric NAT. The search space for randomly trying port numbers is too large.
There are some ways to reduce the search space, like port prediction. But ultimately, a large dose of port scanning is the only way I know of to make the connection reliably. And there’s only so much of that you can do before triggering IPS or overwhelming the NAT.
IPv6 makes this way easier, of course!
NAT randomization, I don't know. Depends on your setup, I guess.
I don’t think I’ve ever seen it done successfully and have often wondered if it’s for a lack of use cases or due to its bad success rate and complexity compared to UDP hole punching.
That said, I really wish there was a standardized way to do it. Some sort of explicit (or at least implicit but unambiguous) indicator to all firewalls that a connection from a given host/port pair is desired for the next few seconds. Basically a lightweight, in-band port mapping protocol.
It could have well been an official recommendation to facilitate TCP hole punching, but I guess it’s too late now, as firewall behaviors have had decades to evolve into different directions.
NAT Behavioural Requirements for Unicast UDP, https://datatracker.ietf.org/doc/html/rfc4787
NAT Behavioural Requirements for TCP, https://datatracker.ietf.org/doc/html/rfc5382
TIL, thank you! I've been looking for this for quite a while after hearing it indirectly referenced recently, but only found host-side specifications for TCP simultaneous open.
Do you happen to know if common firewalls and NATs support it? If they do, I really wonder why TCP hole punching isn't more common.
It is precisely this point that has flummoxed me when connecting my p2p wireguard config[1] with a friend that uses a pfsense router, no matter what we tried, pfsense always chooses a random source port.
But in the simple case this blog outlines, if both ends use the same source port, this method punches through 2 firewalls effortlessly:
Hardly the case in even half of typical deployment cases.
>Many home routers try to preserve the source port in external mappings. This is a property called “equal delta mapping” – it won’t work on all routers but for our algorithm we’re sacrificing coverage for simplicity.
So to what percentage is this coverage sacrificed exactly? No idea. Not as useful if the percentage is high, as you are implying.
> This is a property called “equal delta mapping”
FWIW I’ve worked in computer networking for 20 years and have never heard it called this. This blog is the only source that comes up when I search for that exact term. I wonder where the author got it from.
I had to call them to make it stop since it tripped the VPN solution at work, that interpreted it as a MIM attack. They disabled it no questions asked as soon as I called, so I guess it mostly works for most people, but not all.
But on that note, isn't it basically time now for IPv6 so we can stop shit like this and go to directly addressable devices like everyone did in the early 90s.
In this era where AI is eating away at how deterministic computers are, I really appreciate reading about an elegant solution to a real problem using deterministic logic.
Of course there’s still plenty of deterministic software you can run… for now.
Now combining AI with deterministic tool calling brings the best of both worlds.
I wrote little paper on this technique in school and did some practical tests, at the time I was actually unable to find an example of consumer grade router that it didn't work on! But my resources were rather limited, they certainly do exist.
Even in the presence of a conntrack entry created by an earlier outbound SYN,!ACK ?
Got a source?
We are dropping this deterministic punch directly into the grubcrawler.dev edge binaries. Instead of relying on STUN/TURN servers to coordinate a swarm, millions of nodes trapped behind residential NATs will use the unix timestamp to mathematically predict a collision course, aggressively punch through their firewalls, and instantly hand the raw TCP socket over to rust-lightning (LDK).
No DNS. No signaling servers. No legacy IP registries. Just a self-assembling Lightning mesh of autonomous agents spinning up encrypted channels and executing paid RPC calls entirely in the dark.
Do you find this works reliably outside routers that preserve source ports? My understanding was that TCP punching tends to depend heavily on NAT behavior.
NAT is effectively your router doing DHCP with a 17-bit suffix (16-bit port + 1 bit for UDP vs TCP) to each of your applications and then not telling you the address it gave you or how long it is good for (which is what a regular DHCP lease does). This is in addition to it, most likely, already doing regular DHCP and allocating you a IP address that it does tell you about, but which is basically worthless since routing to just that prefix without the hidden suffix goes into a black hole.
If you could just ask your router for a lease on a chunk of IP+NAT addresses that you could allocate to your applications and rotate them as they expire, you would not need this horrifying mess.
The router would just need to maintain the last-leg routing table (what a concept, a router doing routing with routing tables) just like it already does DHCP.
The applications would have short-term stable addresses that they could just tell their peers and just directly tell the router/firewall to block anybody except the desired peer short-term address.
The “just” is doing a lot of lifting there. I’m glad the various port mapping protocols didn’t really take off and it looks like IPv6 is going to actually make it instead. Much less complexity in most parts of the stack and network.
I am pointing out how the problem NAT “solves” is just dynamic address configuration. They have implemented a N+K bit address where the N-bit prefix is routed and allocated using IP and the low K-bits are routed and allocated like a custom fever dream.
You can just do it all the same way instead of doing it differently and worse for the low bits.
To be clear, the router should rewrite zero bits in the packet under the scheme I am describing just like how routers have no need to rewrite any bits when routing to a specific globally-routable IP address.
You get a lease for a /N+K address. /N routes to your router which routes the last K bits just like normal as if it had a /N-M to a /N route. This is a generic description of homogenous hierarchical routing.
We could have a standard for doing that directly at the NAT box level instead of relying on a third party STUN server, it simply didn't happen (and in fairness, the benefits would be quite minimal).
At least with IPv6 this crap becomes a little easier because you no longer have randomized source ports (which this article just ignores because some devices indeed maintain the same source port) and the IP address contains all the routing information you need. A simple simultaneous open is all you need.
In my country: only a few mobile ISPs are not yet native IPv6. The thing now would be to get a fixed IPv6 for mobile internet (which would remove the need of a name->IP "resolver"), but I wonder if the mobile ISPs can handle the quality of "security" this requires. (we all know about enshitific*tion).