Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm unsure of whether this question is more appropriate for stackoverflow or serverfault. If you think it's more suited for stackoverflow, let me know and I'll delete this and move it over.

I have a STUNT implementation. If you don't know what STUNT is, it's a protocol used to make a direct TCP connection between two peers behind separate NATs. I'll give a brief overview, though my question doesn't directly relate to the protocol.

It's done by using a third party to predict which port each of the peers' NATs will map their next outgoing connection do. The third party then tells each peer the other's predicted port, and they both attempt to connect to each other on the predicted ports. When they fire off their SYN packets to each other, it opens a 'hole' in the NAT at that port, which allows the SYN packet through and the handshake to take place.

One of my colleagues suggested having the peer that initiates the STUNT connection attempt to fire off SYN packets to the predicted port, as well as the next four ports, in case the predicted port is used by another application (or even our application) before our connection is attempted, but after the predictions have been made.
An example of this would be predicting that the other peer is going to connect to us from port 80, but then another application ends up using port 80, so the connection actually comes from port 81; but firing off SYN packets to five different ports, we would (in theory) succeed if it comes from 80, 81, 82, 83, or 84.

However, this isn't the case; when tested, only the first SYN packet has a chance of succeeding. Even if the first SYN packet is sent to the wrong port, but one of the next four are sent to the correct port, they're all silently dropped; there's no response, the connection attempt just times out.

A quick example:
Peer A is initiating a STUNT connection to Peer B.
Peer A is predicted to connect to Peer B from port 1000.
Peer B is predicted to connect to Peer A from port 2000.
The server sends 1000 to Peer B and 2000 to Peer A.
Another application on Peer B's computer makes a new connection, taking over port 2000.
Another application on Peer A's computer makes a new connection, taking over port 1000.
Peer A simultaneously attempts to connect to Peer B on ports 2000, 2001, 2002, 2003, and 2004; the connection attempts come from ports 1001, 1002, 1003, 1004, and 1005.
Peer B attempts to connect to Peer B on port 1000; the connection attempt comes from port 2001.
A hole is created in Peer A and Peer B's NATs, at ports 1001 and 2001 respectively; it should allow SYN packets through.

What I believe is happening is that Peer B's NAT isn't allowing Peer A's SYN packet through port 2001, because it was expecting the connection to come from 1000 but it came from 1002. This suggests to me that the NAT is verifying the source of the SYN packet.

However, from what I've read, one flaw of STUNT is that when creating the connection there's a window of vulnerability where the connection can be hijacked by another source. If it's standard behavior for the NAT to verify the source of the incoming connection, then I don't see how this window of vulnerability can exist.

Note that my implementation is not flawed. If either of the predicted ports is correct, the connection will succeed; the problem happens when both of the predicted ports are wrong and it resorts to attempting multiple ports at once.

As a side note to anyone familiar with the protocol, I'm using the method that involves sending a SYN that I expect to be silently before attempting the actual connection. I'm not using the low-TTL implementation.

Is my NAT rejecting the SYN packets because they aren't coming from the expected port, or is it something else that's rejecting them? If it is my NAT, is this the expected/standard behavior? Note that by rejected I mean 'silently dropping,' as no RST or any response at all is being returned, the connections just time out.

EDIT: The routers in question are both the kind you'd buy at Walmart for home-use, not the kind large businesses would use.

share|improve this question
I don't think you're likely to get good answers to this question on either serverfault or stackoverflow. Also, your question assumes that all NAT implementations are created equal, when they most certainly aren't. – womble Jan 7 '10 at 1:45
That's what I thought, I was afraid it would required someone with specialized knowledge. I'm aware that they aren't created equally, but I think there is some standard behavior you can expect of the majority of NATs. – user30994 Jan 7 '10 at 1:46
There is standard behaviour you can expect from NATs -- translating network addresses. Everything else is up for grabs. – womble Jan 7 '10 at 2:17
up vote 4 down vote accepted

Short answer: Yes-- your NAT is rejecting packets because they're not exactly what it expects. This is going to vary from NAT implementation to NAT implementation.

Editorial aside: I hadn't heard of STUNT before... (STUN, yes-- not STUNT). Oh, ick... what a hack. It makes me weep that the Internet has turned into this NAT trailer park and that we're resorting to hacks like this.

After reading the paper I get what they're doing. It's basically STUN with the added bit of packet sniffing on each "endpoint" to sniff the intial sequence numbers and trade them up via a third-party on the 'net who can accept arbitrary incoming TCP connections. It's a cute trick, actually.

You're never going to get 100% reliable communication like this. I see that the researchers who initially implemented this have some test results that look fairly good at port prediction, though... That's actually a very interesting, albeit dense, little chart. The paper goes into all the prediction issues in more depth, and gives some success percentages. It's shocking to me that they did so well, actually.

Any sane NAT implmentation is going to use, at minimum, source IP, destination IP, protocol, protocol source port, and protocol destination port to identify "connections". (Hopefully they're tracking sequence / acknowledgement numbers, too.)

If your SYN doesn't exactly match the combination of these attributes stored in the device's NAT table the NAT implementation really ought to silently drop it. That would be the behaviour that I'd expect.

share|improve this answer
Nice. Even though I live in a trailer park. (jk) – squillman Jan 7 '10 at 2:10
Thank you, I'll take it. I just wanted a second opinion before deciding whether it would make sense to leave this 'scatter shot' implementation in, or just completely remove it because it wouldn't do much to increase the chance of success. – user30994 Jan 7 '10 at 2:13
So many of us live in Internet trailer parks. I'm horrified that we're not going to see IPv6 adoption but, rather, the rise of "carrier grade NAT" implementations. I can hear the dripping as Time Warner salivates over putting their Customers behind gigantic NAT implementations. – Evan Anderson Jan 7 '10 at 2:14
It dissapoints me that even in 2010 ISP's "Do not believe that running out of IPv4 addresses is anything to be concerned about". Only two or three Australian ISP's support it, and NONE of the big ISPs do. They don't even offer IPv6 tunnels. – Mark Henderson Jan 7 '10 at 2:24
You read the paper and wrote this answer in just 40 minutes? FGITW indeed. – Teddy Jan 7 '10 at 7:36

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.