A hack I'm rather proud of
We're working to make a new version of the game, that's web-based, free to play, and easier for anyone.. But until it's done, we had the question of "How to we keep the old game going long enough to transition?"
One of the key problems with the old game is that games are peer to peer. While the game server authenticates users, the actual card battles have one client connect directly to the other, and play directly.
This worked out well in 1997, in the age of dialup and open ports, but today almost everyone has a firewall, either in software or as a Linksys router.. They just can't get through to play, and the popularity has taken a corresponding hit. We're excited to work toward the new web version, but until we do, we want to help the player base grow, which means we needed to slay the firewall demon.
I had started looking into Hamachi, which creates a direct machine to machine VPN, and lets users connect to one another. Sounds pretty decent... The problem is, it's free for up to 16 users, but after that, users would need to pay $5/month, just to be able to connect... Given that they'd be paying a monthly fee, and we wouldn't even see it, that's a pretty big negative. The second problem is that since it puts everyone on a VPN, BOTH players would need to have it installed to play, not just the player behind a firewall.
Instead, I put together a hack that I'm rather proud of.. I hacked together OpenVPN to put together a quick click-and-run installer, which creates a VPN into our servers.. Unlike the Hamachi VPN, however, our VPN assigns each user a public, routable, IP address, on the outside world, such as 72.10.x.y.z.
Then, we set their default gateway to go through the VPN, and block all ports except for our game.
What this does is give them a public, routable, real IP address, which can only be used for contacting other Chron X clients.
What I really like about this solution is that it's expandable to any other game system.. If you wanted to run a Diablo 2 tunnel, it'd be just a few configuration changes to open up those ports, and bam, it'd just work.
Players each have a public ip and can play against each other, and we get keep the old client workable for a while longer, while we get more done on Chron X 2.
I'm just excited, and wanted to share the hack ;)
-Colin
Keep in mind, this is for a full-screen game, and you can't really play the game and do other things. (This is one of many reasons why we're re-writing it to be web-based)
I think that when it comes to behavior on this subject, there are really two types of users..
The users who are bittorrent downloading, streaming media and other things where cutting out the internet connection would matter.. And the others, who just want to do some homework, then play a game for a while.
For the people who just want to play for a while, having the rest of their internet cut out won't be a major issue.. If they're playing the game, they can't browse the web, or use AIM, but since it's full-screen, they wouldn't be able to do those things anyway.
For the other folk, who use their connection heavily downloading torrents (legally), and listening to streaming radio- They're far more likely to be technically savvy enough to forward the ports necessary to make the game work, and wouldn't require any sort of VPN at all.
however, the hack itself is neat.
Truth be told, we probably could fix the background download problem.. If we recorded every IP that tried to contact your public IP, and then set your gateway to be through the VPN when trying to reach THAT IP, it just might work..
The thing is, that would be fragile, and might take a week or two of work to get right.. Since this is a legacy application, and we're actively working to replace it, for now I'm happy with the 90% solution. I'd rather spend the two weeks making version 2.0 closer to launch.
-Colin
There is no guarantee that this part: "our VPN assigns each user a public, routable, IP address, on the outside world, such as 72.10.x.y.z" will always lead back to a client behind layer(s) of NAT, unless the listening port is manually forwarded in the router itself.
Protocols such as STUN have developed methods to attempt to solve this, but its not easy because of issues such as there being no standard for the amount of time that NAT must keep pipes open after they are finished being used.
Basically, it deals with the NAT-traversal elements for me, once I've twisted it's arm into doing so.. It works, if I recall correctly, using the UDP trick to keep a port open by sending traffic to a host repeatedly.
The nice part about the hack that I'm using is that I don't need to deal with the specifics of the UDP punching, or how often to poll, etc.. I can use industry tested and standard software for that.
Think of it this way-
Have you ever worked at a large corporation, that has a VPN? Once connected to that VPN, you could access all the servers internally, and they could access you, right?
We're basically creating a VPN, and giving everyone an internal IP address.. And then using linux, iptables, and NATing to map all those internal ip addresses to external ones.
1. Fog Creek's Co-pilot: Joel wrote about something similar
2. Skype: How skype connects calls even in the presence of firewalls
The solution is not full proof and takes a few attempts to predict the outgoing ports.
You'll go a long way my friend, I'm sure.
The code is all pretty simple, once you get it working.
We've had several users quit because they can't/won't configure their firewalls, so we needed an automatic solution.
upnp just isn't reliable- It fails in > 60% cases, according to some case study I can't find at the moment.
Hamachi won't work for the reasons above. Too Expensive, and requires both parties to have the VPN installed.
Our only solution was to roll our own.
good luck with it.