4
\$\begingroup\$

I understand that games need to be able to open NAT ports in order to receive incoming connections.

What I do not understand is why there is an issue between "limited" and "open" NAT. The only reason I can see that a game would ever need to have the flexibility to open any port is if it is intending to accept incoming connections on ports that aren't specified in advance as part of the protocol. (If there was a restricted set specified in advance, forwarding these and no others should satisfy all of the game's demands for NAT forwarding, meaning that "open" would not need to be a thing.)

This seems to imply there's some port negotiation going on as part of the protocol (otherwise how does the connector know that this port, not specified in advance, is available?) but if a connection is already established to conduct the negotiation, why move to a different port? And even then, why can't negotiation be limited to a subrange of ports rather than the entire range?

\$\endgroup\$
  • \$\begingroup\$ ...is this asking for help developing a game, or for technical support for a router that isn't working as you expected it to? \$\endgroup\$ – Trevor Powell Dec 21 '16 at 1:10
  • \$\begingroup\$ It's asking for detail on how an aspect of multiplayer networking works, which could be relevant to implementing it. I am not expecting anyone to tell me how to make my router Type 1. I am hoping to understand the multiplayer networking algorithm, and thus to understand why the limitations set by the router are considered a problem. At the moment I cannot see why they would be, but I presume this is because I am unaware of some aspect of how game networking works. \$\endgroup\$ – Mark Green Dec 21 '16 at 1:17
7
\$\begingroup\$

Just to make sure we're all on the same page in terms of terminology:

What is NAT?

NAT is an acronym for "Network Address Translation". It's a system designed to allow a router to allow a whole private network of arbitrary size to appear to be a single device, from the point of view of the outside world. And the magic is that it does this completely transparently, without the clients on either the private or the public network ever needing to know it's happening.

In effect, it takes outgoing requests from the private network and rewrites them to appear to be coming from its single public address and some public port number, and then when it receives a response, it rewrites the response to forward it back into the private network, to whatever device sent the original request.

This was primarily needed because of the rapidly depleting supply of public IPv4 addresses as the Internet's popularity was taking off, but also brought some moderate security benefits by putting a largely one-way barrier between potentially unsecured consumer devices and the public internet. (It also dramatically slowed adoption of IPv6, but that's a topic for another day)

NAT types

This particular classification of NAT types appears to have originated with Microsoft, where it was identified as useful during development of the original XBox game console, since it classed different NAT types into a useful way to determine which clients would be able to directly communicate with which other clients.

Sony uses essentially the same classification system, but uses different terms. In the discussion that follows, I'll mention both company's terms, and then use them interchangeably. But almost everybody has settled on using Microsoft's more human-readable terms for these NAT types; even Nintendo uses Microsoft's terms, now. The only holdout I'm aware of is Sony, who still use their own terms. (I once spent an enjoyable afternoon with a Sony dev rep, trying to make him slip up and use Microsoft's terms for NAT types. I think he figured out what I was doing, and I never managed it. But I did get him to actually say 'Xbox' once, which got him a stern look from his manager. That was a good day. I am a simple man of simple pleasures.)

"Open" NAT (Microsoft's term) or "Type 1" NAT (Sony's term) describes NAT behaviour where a particular private IP address and port behind the NAT device gets mapped to a single public address and port on the outside network. That is, anybody anywhere on the outside who sends a packet to that public address and port will have it successfully delivered to the inside, no matter what. This means that not having a NAT device gets categorised as "Open" NAT. Alternately, setting up a NAT device to forward the correct ports can also achieve this same result.

"Moderate" NAT (Microsoft's term) or "Type 2" NAT (Sony's term) describes NAT behaviour where a particular private IP address and port behind the NAT device gets mapped to a single public address and port on the outside, exactly the same as in "Open" NAT, except that incoming packets to that public IP address and port will only be delivered if we've already recently sent a packet OUT on that port, to the person who is now trying to send a packet IN. That is, people are allowed to respond to us, but not to initiate communication. (This is the most common sort of NAT). We use hole-punching to get through this; a central server tells both of us the other person's public address and port, and we then spam messages to each other, so both of us pretend that we're initiating the conversation, and our NAT devices let both sets of messages get through, thinking that they're "responses".

"Strict" NAT (Microsoft's term) or "Type 3" NAT (Sony's term) describes NAT behaviour which doesn't meet the requirements of Type 1 or Type 2. That is, a single private address and port sometimes get mapped to different public addresses and/or ports, most commonly based upon who the packets are being sent to. For example, if I send a packet from private port 80/UDP to person A and a packet from that same private port 80/UDP to a different person B, then A and B will see those packets as having come from different public port numbers on the NAT device. This means that A and B can't tell each other how to contact me, because my NAT device is going to be requiring that they each only reply to me using the special public port which it allocated for communication to each of them independently; any packets that A might send to the port which was allocated for talking with B won't get through, and vice-versa.

NAT types are broad generalisations

As mentioned above, there are far more types of NAT than just these three, and many more ways to classify them. Sometimes they're classed as "symmetric", or "conical", or in other ways.

One particularly relevant difference, even inside this classification: Moderate/Type 2 NAT devices often differ in terms of how recently we have to have sent an outgoing packet, in order to accept incoming responses. If there's a long delay between our last packet out and someone's response to us, an otherwise Type 2 NAT device may appear to occasionally behave like a Type 3 NAT device.

Another common gotcha is that some routers which behave as Type 2 when there's just one client using the private network begin to behave as Type 3 when there are two clients both using the same private port numbers on that private network.

There is no "standard" implementation of NAT; everybody started from the basic concept for what a NAT device should do, but implemented it separately, so the little details are typically different in every device, and our "NAT types" discussion is just a useful classification system for carving useful information out of a broad spectrum, for the purposes of establishing peer to peer communication when both peers are behind different NAT devices.

Just something to bear in mind.

On the technical support query in the comment

On the PlayStation, NAT type 2 is "moderate", not "restricted" (not sure where you got that term from). It should work perfectly well, since all modern game services are built to perform standard hole-punching to allow clients to communicate with each other.

How to classify a NAT device's behaviour, yourself

To classify a router between the three types we're discussing here, all you need is a server with three different public IP addresses. We'll call these IP addresses 'A', 'B', and 'C'. Follow these steps:

  1. Client sends a packet to A, and a packet to B.
  2. Server compares the packets it received on its A and B addresses, and checks to see if the public IP address and port numbers it sees as the source of those two packets match each other. If not, the client is Type 3 (Strict).
  3. If the packets did both show the same public source IP address and port, then the server sends a packet from C to that IP address and port. Remember that the client has never sent a packet to C, so if the client successfully receives that packet, then we know it's Type 1 (Open). If it fails to receive the packet, it's Type 2 (Moderate).

That's all it takes!

Why any of this matters

Fundamentally, any number of Type 1 and Type 2 clients can successfully talk to each other; the Type 1 clients because anybody can talk to them on their public address/port, and the Type 2 clients because they can hole-punch out, as long as they know the public address/port that is going to be contacting them.

Type 3 clients, on the other hand, can only talk to Type 1 clients, and they require the Type 1 client to have special NAT traversal code to do that successfully; (the program has to be smart enough for the Type 1 client to receive a packet it wasn't expecting from an unknown address/port, and realise that it must actually be the true address/port from the Type 3 client, and redirect itself to talk to that address, instead of the one it had been expecting to hear from. I would be surprised if many folks actually write that sort of code any more; the vast majority of people are using Type 2 NAT devices, these days, so it'd be hard to test and few folks would get any benefit from this work).

Anyhow, Type 3 clients can't talk to Type 2 clients, because the Type 2 clients don't know the correct address/port to send packets to in order to hole-punch through their own NAT device. And obviously two Type 3 clients will likely never manage to reach each other at all, since neither actually knows the correct address/port for talking to the other.

If you're making a multiplayer game, it can be useful to know which NAT type each player is; for example, knowing that Type 3 players will only be able to talk to Type 1 players, you immediately know not to even bother suggesting that they join a game session which includes any Type 2 or Type 3 players; you already know they won't be able to connect to each other!

And similarly, you know not to send Type 2 players to join a game session which includes any Type 3 players; you know they won't be able to connect. All this logic lets you reduce frustrating "trying to connect to game session" processes which will never complete.

And that's pretty much all there is to it!

\$\endgroup\$
4
\$\begingroup\$

Your question is a bit fuzzy regarding the terminology, but if i get you correctly:

A multiplayer solution may want to establish both a persistent connection (TCP or a kept-alive UDP) to a well known public server (a matchmaking/handshaking/hole throughpunching server - maybe it has a better name), while at the same time it may want to allow peers to establish direct connections between each other. Game manufacturers want this to work with the common, normal behaviour of popular home routers. By default, a router does not have static NAT behaviour, as it has no pre-set information about the local computers connecting to it. Meaning that the router itself decides what public port number it assigns to a specific local computer, of multiple, in the local network. This port then points at a specific IP address in the local 192.168.n.n address space.

Clients normally announce themselves (tell their home routers public IP + port that points at a local box) to the matchmaking server, which distributes that endpoint information to other clients, after which all clients can begin to bombard each other with packets - this opens the NATs as needed in the entire cloud. Then there may be different behaviours among the NATs (routers), ie. different restrictions regarding how to allow/disallow ports in opposite peers. The worst case is the symmetric NAT, which changes your routers public port per connection, causing the information it announced to a matchmaking server to be useless for another peer, as these are different connections.

The router needs to have freedom to do this, and nobody wants to set up port assignment tables in the routers, most even don't know how to do this. Hence the router will want to use it's entire public port space, as needed, and dynamically. Eventually, the application(s) started inside the local network determine the extent of all this.

Looking from a coding point of view, this can be a matter of convenience. On can use a single socket for talking with multiple peers, in the case of UDP packets. However one must then parse the remote endpoint in each incoming packet and act accordingly. Another alternative is to use an individual socket for each remote endpoint, in which case the OS sends a callback directly to the correct, assigned callback function. An individual socket however requires an individual local port number, which will translate into an individual port number from the router outwards too - again requiring the routers automation to handle this gracefully.

\$\endgroup\$
  • \$\begingroup\$ Thanks - that makes sense, but doesn't explain fully. I have a SonicWall which does give me full control over all NAT translations. I have all the standard PSN ports forwarded directly to the same external port numbers. But the PS still considers this restricted (type 2) and I don't see why. Under that configuration it can truthfully advertise any of the standard ports (and there are at least 94 in the ranges) with no NAT problems, and make an outbound connection to any port to handle a peer with symmetric NAT. So why can't it handle this? What can't it do that it could do with "open" NAT? \$\endgroup\$ – Mark Green Dec 21 '16 at 1:05
  • \$\begingroup\$ @MarkGreen It will classify as 'type 2' if it failed to get a packet to your console from an address you hadn't yet sent a packet to. That's really all it means; the core difference between 'type 1' and 'type 2' is that 'type 1' will accept unsolicited external packets on a port, while 'type 2' won't. If it's failing to deliver that packet, then you presumably haven't actually opened whatever port it's trying to send to. (but again, for gaming purposes you should be perfectly fine with 'type 2' NAT; it's what virtually everybody uses) \$\endgroup\$ – Trevor Powell Dec 21 '16 at 9:18
  • \$\begingroup\$ It's really hard to tell what happens, with the information given. The cloud seems to have other participants as well (?), plus that the application you are running (?) has some kind of logic for this. To really resolve what happens, one would need detailed info about the behaviour of all involved components, plus probably own code. Trevor's comment above seems a possibility, and there might be others as well. At the moment there are too many unknowns, i'm afraid. \$\endgroup\$ – Stormwind Dec 21 '16 at 13:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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