by Spike » Sat Dec 12, 2009 10:51 am
Reasoning:
A NAT will route packets from the client to the server and back.
If you have multiple clients/computers on the inside of the NAT and a new packet arrives, the NAT is only able to route the packet to the client computer if it knows which client computer it is meant to be sent to.
With the NQ protocols, the server listens on one port, and opens a new port for each client. It also initiates the connection on that new port.
This means that the client can begin connecting to the server, but once it has got a connection, the server starts sending packets to the router, and the router receives packets which it does not know how to route.
The solution is to send a dummy packet from the client's port to the server's new port for that client, thus opening a route on the client's NAT which basically tells the router how to route packets properly.
Complications:
Broken routers:
There are some routers which are so mind numbingly stupid that they close the connection again after 2 mins, and which will only be reopened by a client->server packet. NQ clients only send packets on receipt of a packet from a server, and in this case, no NAT fix will save you. Such routers are of course absurdly broken. A work around is to just send dummy nop packets (or even corrupt ones) every 2 mins, or each time you lose your connection, lol.
Server NATS:
Additionally, this is a client-side NAT fix only. For servers behind a NAT or router, the server will listen on a known port for new clients, and then auto-allocate a new port for each client. You can forward the known port, but the port-per-client ports are generated almost at random, depending on the operating system. Its generally a bad plan to route 4096+ to that server... The solution to this is to change port allocation to a known range, or to rewrite the network code to always use a single port for every client. This is probably why there are multiple chunks of proquake code marked as NAT fixes, perhaps.
Alternatives:
As mentioned above, the server can be modified to use a single serverside port. This provides a NAT fix for all clients' NATS as well as the server. But its a lot of code. FTE does this, as does DP, but it doesn't fix the client if they connect elsewhere, of course.
You don't have to send a meaningful packet. You could send a 'corrupt' packet to the server, so long as you send at least one udp payload byte from the correct client port to the correct server port. The server does not need to parse it, it needs merely to be routed by the client's NAT.
Generally UDP over wireless is quite lossy, so you may wish to send a couple of packets (with a time gap) if the client is on a wifi connection before the router, but over ethernet more than 1 is overkill, its not really possible to tell however.
.