Wednesday, April 11, 2007

Starcraft and NAT

Getting Starcraft to work for two people behind NAT

Update: Please see Jonathan's comment for v 1.16.1 for an updated set of instructions.

Ed. The symptom that this solves is that when two people are behind the same NAT gateway, they experience lots of lag in the game, and may see high latency in the Battle.net game setup. We work around this by remapping port 6112 at the NAT gateway.

This information is from Jan 18, 2007. (original)

My friend Jason and I have been figuring out how to allow two people behind a single NAT gateway router to play Starcraft through Battle.net. Limited information is found through Google on this topic, and Blizzard offers no help. We each have Linksys WRT54G routers with alternate firmware that supports running iptables. (DD-WRT and HyperWRT Thibor + tofu)

Having two people behind a single NAT gateway router connect to the same Battle.net game typically results in the appearance of lots of lag as the two clients do not communicate with each other. To get around this, the following iptables rules can be inserted on the NAT gateway or router.

In this example 70.100.200.24 is the public IP address for the two people behind the NAT router. 192.168.1.2 is the IP address of one client machine, and 192.168.1.3 is the IP address of the other client machine. On the router, type these commands as root:

(NOTE: Try using 6113 and 6114 instead of 63002 and 63003, respectively. The original rules are not working as of Starcraft version 1.16.1. I suspect that the clients outside the NAT no longer listen or respond to UDP messages on "invalid" ports such as 63002 or 63003. I hope Blizzard did not restrict all traffic to port 6112.)

iptables -t nat -I PREROUTING -p udp -d 70.100.200.24 --dport 63002 -j DNAT --to-destination 192.168.1.2:6112
iptables -t nat -I POSTROUTING -p udp -s 192.168.1.2 --sport 6112 -j SNAT --to-source 70.100.200.24:63002
iptables -t nat -I PREROUTING -p udp -d 70.100.200.24 --dport 63003 -j DNAT --to-destination 192.168.1.3:6112
iptables -t nat -I POSTROUTING -p udp -s 192.168.1.3 --sport 6112 -j SNAT --to-source 70.100.200.24:63003

The PREROUTING chain entries cause the packets to be sent to the Internet with port 63002 or 63003 rather than the standard port 6112 for Starcraft.

The POSTROUTING chain entries cause the packets to be sent on the LAN. It's important to make sure these are the first rules in their chains. I've seen other instructions that use "-A" rather than "-I" to add the rules, and this does not work for me since there are already some global rules in the chains that will handle the packets. For example, the POSTROUTING chain has a MASQUERADE target for all packets. That causes the local packets to be sent to their destinations with a LAN source address, which will be dropped by the Starcraft client because it is expecting the source address on game packets to be the public IP address.

These iptables rules will not allow one of the local machines to host the game. When we've tried that, some clients were unable to connect, so this is an issue still under some investigation. When we have time, we'll look at the Wireshark captures.

Labels: , , , , ,