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.

42 comments:

Jean said...

You sir, are a hero!

My brother and I have been trying to play Starcraft together over Battle.net for three or four years now, and finally we can kick some ass together. With the announcement of Starcraft 2 we felt like playing starcraft again, now we can with a lot more fun. Thanks again.

Anonymous said...

hey man thanks for the info, we got sc working after all the sc2 news.

anyways, we are also able to host by forwarding the 6112 to the computer that hosts the game, then everyone else can join

sorry if im not coherent, trying to reply inbetween sc games!

Anonymous said...

Do I just put the codes in startup scripts?

Do I still have to forward the ports to 63002 now?

John Paul said...

You can put the iptables commands in a startup script on your gateway/route assuming it runs Linux and iptables (like the WRT54G does with alternate firmware).

The iptables commands take care of the forwarding that needs to be done at the NAT gateway, but if you have another system in front of that, which is a configuration beyond what these scripts handle, then you may need to forward ports 63002 and 63003, but on a WRT54G system you do not need to forward these ports since that's what the iptables commands already do.

politelyerased said...

This isn't working for me, we can't see each other type, and it still lags any game we're in together. I've got the script in startup, should the router be reset or something?

John Paul said...

If the startup script has not run at all, then the iptables rules will not have been added. If you have a telnet or ssh shell to your router, you should be able to enter the iptables commands there without having to restart your router, but restarting your router might help if that causes the iptables commands to be run. I'm sorry I cannot really debug particular issues; I have to re-learn how to manage iptables every time I deal with it.

Anonymous said...

Hi, how can I do this with a WPN824 neatgear router? I don't know where to enter the commands. Thanks in advance.

Anonymous said...

just wondering if you know: why doesn't every router allow people to access root and why must people update to alternative firmware in order to use iptables, if it is useful?

John Paul said...

I suggest you post your question of why router firmware is the way it is at Reddit or Slashdot. I do not have an answer.

Anonymous said...

could you PLEASE give step by step instructions on how to do this on the WRT54G? im looking for where to type those codes but i cant find it. i have been trying to do this for years! please help!

John Paul said...

On a WRT54G, you will need first to install an alternate firmware that has some kind of shell access. Check Wikipedia's WRT54G page for links to firmware. I suggest installing the HyperWRT + Thibor firmware since that's what I've used. You can then enable remote shell access daemons on the router (telnetd or sshd) and then telnet (linux and Windows command) or ssh (use Putty on Windows) into the WRT54G and run the iptables commands as root OR put them in the "firewall script" from "Administration->Management->edit firewall script". If you type them in from the login shell, the iptables commands are effective immediately. If you put them in the firewall script, I believe you must restart your router for them to take effect.

toxik said...

I don't see how this could help - if you're already having masquerading on the WAN NIC, this ought to be done for you by automation, but I probably misread the iptables rules.

Feel free to clarify, or ignore my probable misunderstanding.

John Paul said...

The problem that these iptables rules solve is that even with NAT and IP masquerading, the Battle.net protocol that the games use is based on UDP, which is connectionless, using only port 6112. If the protocol were TCP rather than UDP, then the NAT gateway would be able to know which incoming packets went to each machine. In fact the normal IP masquerading rules and NAT work just fine for a single computer behind the NAT gateway because there is no ambiguity about which system should receive the incoming packets. As soon as a second machine is added on the local network, the NAT gateway has to determine where it should send the packets, and what gateways do then is usually simply to send the packets to the last system that sent an outgoing packet on the same port.

John Paul said...

Note also that Warcraft 3 lets the clients use any port from 6112 to 6119 for the Battle.net UDP traffic, and so one would not need to have these iptables rules on the NAT gateway if one were to configure different ports from the game's network settings. Starcraft does not have this networking option.

Anonymous said...
This comment has been removed by a blog administrator.
Anonymous said...
This comment has been removed by a blog administrator.
Chris said...
This comment has been removed by the author.
Chris said...

Did 1.16.1 break this fix? I had it working before, but ever since I upgraded SC, it doesn't seem to work anymore.

John Paul said...

I hope it is not broken. I have not played in a while, and I will have to put the iptables rules on my new router.

bog said...

hey, ever got hosting to work?

John Paul said...

I have not gotten around to trying to get the rules to work with both the game host and one of the other players behind the gateway. I do encourage anyone to get wireshark and look at the packets that are sent for host communications.

RevRed said...

It's broken for me too as of 1.16.1

We (the two computers on the lan) can see and join eachothers game, but people from battle.net cannot join the game.

John Paul said...

You might try using using values of 6113 and 6114, which are valid Battle.net port numbers (at least in Warcraft III) instead of 63002 and 63003. I cannot remember a good reason to use those port numbers.

RevRed said...

Nope. That didn't do it. I'm still having the same problem. Thanks for your help anyway. I'll keep digging around.

John Paul said...

When I have time, I'll take a look. I still prefer Starcraft over all other RTS games, so I hope we can find a way to make it work. Any distinguishing information in the packet envelope can be used to route it to the correct computer behind the NAT, so let's hope Blizzard still allows something to be different in the envelope.

RevRed said...

Any progress? I've tried using WireShark to look at where the packets were heading and coming from. It seems, although I could be mistaken as I'm no expert, that the traffic is on all sorts of different ports now, so the routing rules don't work since they are from specific ports. Thanks for your help in advance!

John Paul said...

I have not looked at this further, and currently I do not know when I will have time to look at making things work again since the 1.16 patch. If I find time to work on this, I will post what I discover.

Jonathan said...

OKAY GUYS! GOOD NEWS!!

JULY 16, 2009

After 5 hours of trial and error, I finally figured it out!!

*** Works perfectly on patch 1.16.1

So the IPTABLES rule above works, with a slight modification (see below).


Step-by-Step:

1. Each computer must have an IP Address with a different Subnet (you can do this by manually changing this in your Network Config):

Example:
Computer A: IP: 192.168.1.129
Subnet Mask: 255.255.255.128

Computer B: IP: 192.168.1.193
Subnet Mask: 255.255.255.192

2. You need to change the Port that Starcraft is using on Computer B.
To do this, open "regedit" and go to your Starcraft registry key (in HKLM) and add a DWORD value, name it [Game Data Port] (without the brackets) and give it a value of 6113 (DECIMAL make sure you check that radio button).

3. Add John Paul's firewall NAT rule on your router (I highly recommend DD-WRT for this, in Administration, Command, Save Firewall):

Note: I used a mix of my values and the same values as John so that you can retrieve yourself more easily. The main difference is that the second iptables rule uses port 6113 instead of 6112 as suggested by John.

iptables -t nat -I PREROUTING -p udp -d 70.100.200.24 --dport 64001 -j DNAT --to-destination 192.168.1.129:6112
iptables -t nat -I POSTROUTING -p udp -s 192.168.1.129 --sport 6112 -j SNAT --to-source 70.100.200.24:64001


iptables -t nat -I PREROUTING -p udp -d 70.100.200.24 --dport 64002 -j DNAT --to-destination 192.168.1.193:6113
iptables -t nat -I POSTROUTING -p udp -s 192.168.1.193 --sport 6113 -j SNAT --to-source 70.100.200.24:64002

4. That's it! You're all set! Only problem is that you guys won't be able to create a game together, BUT IF YOU BOTH JOIN A GAME IT WILL WORK 100% with NO LAG OR CHOPPY! EVEN TRIED 4v4 with no problem whatsoever!!

5. You could add more computers this way, as long as they are not on the same subnet mask and port as the other ones you should be fine!

Examples of additional computers settings:

Computer C: IP Address: 192.168.1.225
Subnet Mask: 255.255.255.224
Game Data Port: 6114


Computer D: IP Address: 192.168.1.241
Subnet Mask: 255.255.255.240
Game Data Port: 6115


Then add the two IPTABLES rule above accordingly (change IPAddress and Port).


Jonathan G.
Quebec, Canada

John Paul said...

Thank you, Jonathan! I wonder why we have to go through so much trouble if it is possible simply to change the port to 6113 using RegEdit. If the port is different, then I would think a standard NAT gateway could handle the routing of the packet.

Jonathan said...

Not sure!! I would have thought so too.. But apparently something probably prevents it from working... Like I said it does not work if the 2+ computers are on the same subnet, even with the port change and iptables rule... I have not looked into it with wireshark but I can confirm that the Game Data Port registry key works (with cports I was able to clearly see that UDP port 6113 was in use when I added the value. Anyways, we made it work!

werk said...

Thanks!! Can't wait to try this. I have tried to solve this problem using iptables a couple of times during the last 6 years, but never succeeded :)

Jonathan said...

I should say that this has been tested with Windows XP only.

If you are using Vista or 7, then you might need to pay attention to which registry key you are modifying, as I believe Game Data Port should not be changed in HKLM, but in HKCU.... But I dont have any computers with any of those OS yet and I havent tested it out.

Cheers,

Jon

Jonathan said...

Guys,

I want to make sure that you guys know where to add that Registry Key:

[HKEY_LOCAL_MACHINE\SOFTWARE\Battle.net\Configuration]

or

[HKEY_CURRENT_USER\SOFTWARE\Battle.net\Configuration]

This is where you add a DWORD value of 6113 (DECIMAL)

Jon

Anonymous said...

(sorry for my bad english)
Is it works for warcraft 3 when playing on non-official pvpgn server?

I have d-link 2540U configureg in router mode. When i'm trying to play with my brother (both computer are connected to LAN ports of router) we able to connect to battle.net, write messages in chat and even create games, but not able to connect to each other. I'm trying to connect to game created by my brother, interface of a game freezes for one second and then appears message somthing like "cant connect, possibly you enterd wrong game name or administrator stops it".
Here http://us.blizzard.com/support/article.xml?locale=en_US&articleId=21109&rhtml=true i've read that
"- NAT users will need to map any "in"s (hosting games only) to the IP of the computer hosting the game.

- Warcraft III is the only Blizzard Title that currently supports multiple players hosting games behind NAT."

After allowing incomig connections on port 6112 for me and port 6113 for my brother (6113 is his game port) the same message appears, but after approximately 5 seconds.
I've tried to change subnet mask in my network connection properties, but it doesn't help.
Am i doing something wrong?

John Paul said...

I've never messed with multiple players and Warcraft III though it should work. Are you forwarding both TCP and UDP traffic on ports 6112 and 6113 to your machine and your brother's machine, respectively? Battle.net uses UDP pakets, and some routers may default only to forwarding TCP packets.

I'm sorry I cannot offer more than that as a suggestion.

Anonymous said...

Thanks for replying John.
Yes, i'm forwarding both TCP and UDP traffic. Are you able to connect to game created by your brother (when both of you behind the same NAT) ?

Long said...

so, what about im using DSL wireless... and every time i click on Save Firewall the router will be reset and the WAN IP will change after that .... This will make those rules not suitable anymore according to the changed WAN IP. .... any solution for this?
Or does any1 know how to fix WAN IP?

ray474 said...

Thats cool for me works the firts way, i didnt probe the second way, but ONLY ONE PROBLEM how i can be host.... maybe you can find some way to solve that, it will be great....

thx men....

Nelson said...

Guys, i have adsl 2+ connection
Modem Zyxel P660HTW2 EE
Firmware 340AZC3D0 (19.03.2010) - late

I open all ports (nat -> port forwarding -> default server 192.168.1.33 - this open all ports in my ip), but people cant join me and 2x2 is lagging.

Then i google my problem and found it http://yigitgursoy.wordpress.com/
90% of this commands dont work, so I use only "-ip nat timeout UDP 6112 10", i decrease 10 to 0, and people join me!
I experimented, 0-3 seconds - people can join me, more - cant.
But anyway, 2x2 lagging...

I dont know what to do...

Some information about me: PFPortChecker show, that all ports open, in particular 6112 TCP & UDP.
I have ESET NOD32 4.2. Firewall turn off here.
My Lan: tcp\ip automatically; DHCP, ip 192.168.1.33, mask 255.255.255.0, gateway 192.168.1.1, DNS 192.168.1.1

StefanieD said...

Ok so I need help...I have a windows 7 computer and a windows XP computer...we want to play online together. We have a wrt310N wireless router and we have also bought a switch and have a 2nd ip address from Shaw. So how can we play together online in the same game?? Can someone send me step by step instructions on how to do this so my husband and I can finally play together online in a game...THANK!!!

StefanieD said...

So Johnathan can you please email me at stefanieddudley@gmail.com I did what you said but now when we try to get on one or both it says Battle.nets connnection has been interupted please try again later...and sometimes we get into the lobby then it does that. Please email me when you can as I REALLY want to get both of us online together!!

StefanieD said...

Ok so after doing everything you said Jonathan ( I think) ..we are having a issue of now when we both try to log into our battlenet accounts, one of us will get a message saying "The connection to Battlenet has been interrupted"....it also did it once when I was just trying by myself to get online it did it too,,,,I would think something to do with my router settings maybe...please emial me personally as listed above we really need you r help!!!