StarCraft and NAT issues
Recently I set up PvPGN server to host StarCraft games and had to solve some lag problems when people behind NAT tried to play the game. In this post I try to summarize my experience and hope it can be useful for others, as there’s not that much info available on this topic, it seems.
This post was written for people who are familiar with iptables, NAT concepts and networking concepts “in general”, and who already read, understood and tried applying the network setup listed in PvPGN documentation. There’s absolutely no point in asking questions here like “I do not know (and do not care) what it is all about, JUST TELL ME WHAT SHOULD I DO, STEP BY STEP,TO GET THIS DAMN THING WORKING!!!”
I also do not cover here server installation/configuration and firewall configuration for server, as it’s explained in PvPGN documentation, particularly on their NAT / Firewall or TCP/IP Addressing page.
StarCraft LAG problem
If you’re reading this there’s a chance you already know what I’m talking about Anyway, by the “lag problem” here I mean constant and extreme delays during the game when these delays are not the result of network latency or its low speed, but rather network configuration problem.
There are the following pre-conditions for the problem to occur:
- More than one player behind the NAT on the same local network, I will call them the “local” ones.
- At least one player that is not on the same local network as other players, I will call him the “external” one.
PvPGN NAT / Firewall or TCP/IP Addressing page discusses this issue in “StarCraft and LAG” section and proposes solution, but unfortunately it didn’t work for me straight out of the box.
Some other pages about this problem: StarCraft NAT, StarCraft and NAT - they, however, do not get enough into details of why the thing is happening in the first place, and thus offer only partial solution to the problem.
Therefore I had to perform some brief analysis with WireShark and, combining that with PvPGN documentation plus some extra info found on the Net, I’ve got the following picture on how things are working. While I might be wrong at some details and results can depend also on other factors, such as game/server versions or things like that, it shouldn’t be really important for general understanding of the problem. Note that by the “address” here I mean the “IP:port” pair.
- PvPGN server is used only for game setup, all actual communication during the game happens directly between players - this means that each player should be able to contact directly all other players.
- When new game is created, the player that becomes game server registers itself on the PvPGN server as game server.
- When players want to connect to the game they ask PvPGN server for the address of the game server. PvPGN server performs address translations of the game server address as specified in PvPGN address_translation.conf file.
- Having game server address, players connect to game server and ask game server for addresses of other players connected to this game.
- Once all players have each other addresses they exchange info with each other directly using these addresses.
Once more, the actual schema is most likely different, but this description should be enough to understand where the problem is: PvPGN address translation seems to be applied only to game server IP translation, not to other players addresses!
This description allows explaining easily what happens when different players become game server and PvPGN address translation is specified in the way suggested in their documentation:
“External” player hosts the game: “local” players receive its address from PvPGN server unchanged and are able to communicate with it correctly. However, once first “local” player asks for the address of the second one, game server returns the address that it “sees” when receiving messages from the second player, which in the case of NAT is external address. Then first “local” player tries to use received address to communicate with the second “local” player and the outcome of that attempt completely depends on network configuration: if the router is configured in the way that permits communication between local clients through the external address (by setting SNAT/DNAT appropriately) - things will work OK, if not - LAG problem will occur. Firewall rules suggested in PvPGN documentation in fact enable communication between local clients through the external address, though they do not explicitly mention this effect in their documentation.
One of “local” players hosts the game: “external” player receives translated game server address from PvPGN, so he is able to connect to game server correctly. For the second “local” player things are different, however: if we assume that PvPGN server is inside local network, then game server address is returned to second “local” player unchanged and thus it communicates with it directly over local network. Therefore, when “external” player asks game server for second “local” player address, the internal address is returned - as it’s the address game server sees the messages from second “local” player coming from. Therefore “external” player is not able then to communicate with second “local” player, as it does not have its correct, external address.
Therefore, if there’s a need in “complete” solution, which works reliably not depending on where the game is hosted, the following steps should be done:
- Follow PvPGN documentation to ensure there are communication paths between all players.
- Especially, make sure “local” players can communicate between each other using their external addresses! This should be the case by default if you use firewall rules from PvPGN documentation, but also make sure you do not have other rules that might block the appropriate packets. It might be a good idea to try playing the game with “local” players only, run WireShark and check that packets are in fact coming through the external addresses.
- Do not use exclusion ranges when specifying translation rules in address_translation.conf: i.e. instead of
192.168.10.199:16199 245.012.10.1:16199 192.168.10.0/24 ANYlines use
192.168.10.199:16199 245.012.10.1:16199 NONE ANY.
With this kind of setup all players will communicate with each other using external addresses. This can place slightly higher load on your router, though it shouldn’t be a problem as traffic is very low. However, this pays off by the fact that all players are “equal” and contact each other in uniform & consistent way not depending on the game server location.
Moreover, I believe that the same configuration should be applicable to playing on Battle.Net official servers also, though I haven’t tested it myself.