Advertisement

Very simple questions about NAT

Started by June 14, 2017 05:51 PM
4 comments, last by frob 7 years, 5 months ago

My understanding is that packets sent from computers behind the same router to an external address will have the same public IP address from the perspective of the external service being contacted.

First question: I want to verify that although they share the same public IP, the port number attached to the public IP will be unique, correct? Its by having a unique port that two computers behind a home router (sharing the same public IP) can connect to a game server and can be uniquely identified (via unique ports), correct?

Second question: I was reading about how Quake did its networking and it appears old routers would sometimes change a computers public port mid-game causing clients to no longer match their port stored on the game server. John Carmack ended up having to generate a "qport" (a random number at connection time) which would uniquely identify the client even if their real port changed. Is this still necessary?

TL;DR The ultimate point of this post is to verify that I can reliably use a clients IP address and port to uniquely identify them on the server. I'm wanting to make sure two home computers sharing the same router (and thus same public IP) appear unique due to them each getting a unique public port.

1. Correct. An IP connection is uniquely identified by four pieces of data: host IP address, host port, client IP address, and client port. Given those 4 things you know you have a unique connection.

2. This depends on protocol. AFAIK it is not compliant with TCP standards to change ports mid-connection. UDP may behave differently, I haven't spent nearly as much time with it to say for sure.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Advertisement

First question: I want to verify that although they share the same public IP, the port number attached to the public IP will be unique, correct?

Generally yes. This is what is usually desired from NAPT.
This would not be the case however if the router were configured to evict any previous port mapping when two different internal devices make a request to the same host:port pair. (Hopefully!) Nobody's home router is going to be doing that however.

Second question: I was reading about how Quake did its networking and it appears old routers would sometimes change a computers public port mid-game causing clients to no longer match their port stored on the game server. John Carmack ended up having to generate a "qport" (a random number at connection time) which would uniquely identify the client even if their real port changed. Is this still necessary?

Routers will occasionally refresh their forwarding tables so this is still required.
If, say, a router expires any port mappings that haven't been used for 5 minutes then a client that hasn't contacted your server for >5 minutes (e.g. the game is paused or there's temporary network drop) will consequently lose its port assignment and (potentially) be assigned a new external port the next time it generates traffic.

TL;DR The ultimate point of this post is to verify that I can reliably use a clients IP address and port to uniquely identify them on the server.

Yes but only for the duration of a short-term connection. Over long periods of time or between connections this is not reliable.

As a rule you cannot trust network devices and their vendors to implement standards correctly, or even in a predictable way.

To get reliable behaviour you are going to need to implement an application-level protocol over the top, I would suggest you generate a UUID on the client that it passes to the server when it first connects. The server can use that UUID to track the client reliably even if the client's IP address changes, or there's a network outage, or the router is rebooted, or the port mapping changes, etc.

Thank you both for clearing up my confusion. I'm trying to get a client/server architecture using UDP working. The Quake 3 and ENet sources have been helpful for learning. If you guys have any other reading material suggestions (source code, books, or otherwise) on the subject, then I'd appreciate it. Thanks again!

Stevens, TCP/IP Illustrated: http://amzn.to/2sbWmqI
enum Bool { True, False, FileNotFound };

If you guys have any other reading material suggestions (source code, books, or otherwise) on the subject, then I'd appreciate it.

Seconding the Stevens book. Volume 1 is a must read for network programmers.

It is great for learning and as a reference. I keep my own copy at home, but I think I've seen it on some programmer's bookshelf at every company I've worked.

This topic is closed to new replies.

Advertisement