Jonathan Clark

[Diary] [Contact] [Guest Book] [Projects]
[Photos/Paintings] [Heroes] [Resume]
Jonathan Clark

From jonathanclark.com: August 28, 1999

I wrote this article for Game Developer Magazine a while back, but they were full at the time and I was too busy to try other publications. Recently a friend asked me a question about proxy servers and I broke out this article and decided to post it here, even with the many grammer errors it contains.

Playing games at work

Making your game work with Firewalls.

When someone broke into our web server machine at Crack.com, they were able to get to our development computers and steal the source code for Golgotha and Quake. Besides being very embarrassed, we decided we needed a firewall. The word firewall is used to describe any kind of security measure taken to limit types of Internet traffic that can come in and go out of your local network. Today, any company serious about their network security will have some sort of firewall installed. Because firewalls restrict network traffic that can come in and out of the local network, they can make it hard for your game to communicate with other players or a game server on the Internet. Gamers often have faster computers and Internet connections at work so they would like to play there (after hours of course!), but because most game developers neglect these issues, they can’t.

Firewalls come in two different flavors, routers and proxy servers. A router can be implemented in software and/or in hardware. At Crack.com we had a combination of both: our ISDN modem had filtering features which blocked most traffic, while an old 486 Linux box acted to do logging and further filtering. Filtering is usually packet based, meaning that the header of an IP packet is examined with no regard to the contents of the packet. The port number, source and destination addresses are extracted and compared against a set of rules. If the rule allows it, the packet is passed on, if not it is dropped. One rule might disallow packets traveling into the internal network which have an Internet address already inside the internal network sometimes called "spoofed" packets. Often a filter acts to prevent all incoming UDP data and all TCP data that did not originate from an internal connection. Because UDP is often a faster way for games to communicate this poses a big problem. Further adding to the misery, it is impossible for an application to automatically know which packets are allowed to go out and which are allowed to come in because the router operates transparently. At a big corporation, it’s difficult to get the admin to change the filtering rules or even tell the users what they are.

There are three ways players can find each other and start playing a game. The most primitive method (Figure 1) involves manual communication of an IP address, port, game, and time by phone or email. This method poses a problem if both players are behind different firewalls that do not allow incoming UDP or incoming TCP connections because neither side can connect to the other. A more popular version (Figure 2) automates the process of finding someone to play by having everyone connect to a central match maker server. This method usually tells the players each other's IP addresses and then steps back and lets them play. This puts them into the same problem as the first method because the players need to connect to each other. There are 2 ways to get around this problem when dealing with filter based firewalls:

    • Require at least one player who can accept connections before starting the game. The match maker can determine this by trying to make a test connection to each player. This player becomes the "server" machine and all other players connect to him.
    • Have the match maker server relay the data to the players if all of the players are restricted from connections (Figure 3). This requires dedicated servers and adds some latency because each packet travels to the central computer and then to the destination player. If the server is on the west coast and the players are on the east coast (or the UK!), your fastest response time starts to be limited by the speed of light rather than flaky modems.

Proxy Servers

A second method of implementing a firewall is by using a proxy server. A proxy server and a filtering router are often combined to add more security. Using a proxy server, an application no longer connects to an outside Internet address, but instead connects to the proxy server which in turn connects to another proxy server or the outside internet address (figure 4). Proxy Servers are very nice when dedicated IP addresses cost money because computers inside the network can have "fake" addresses. All the traffic goes through the proxy server, so there is no need to have a valid internet address inside the firewall. For this reason, proxy servers are becoming more popular at home where an ISDN or modem dial-up account can be shared by several computers. Proxy servers can relay raw connections or act on a higher level understanding individual protocols.

Most people are aware of proxies through use of their browser program. Browser’s usually support a number of different proxy protocols, the 2 most important for game developers being HTTP and SOCKS. Created by CERN in the early 1990’s, the HTTP proxy was the first generic Internet/firewall proxy server. Because the CERN web server was the most popular web server deployed during the early days of the net and it was available free of charge it is the most widely supported proxy mechanism today. Normally when a web browser wants to retrieve URL data from a web server, it connects using TCP on port 80 and issues a text command looking like this:

GET /

HTTP proxies commands look much like web HTTP commands. To retrieve a document, from the internet simply send a GET command to the proxy server, for example :

GET http://somewhere.com/somedoc.html

 

The HTTP protocol comes in several flavors, HTTP/0.9, HTTP/1.0, and HTTP/1.1. Version 0.9 only supports the GET command and most users today require the use of SSL tunneling so they can talk to secure servers. Because of this, it’s unlikely you will encounter any 0.9 proxy servers out there. Version 1.0 is probably the most widely used version right now, and 1.1 is backwards compatible with 1.0 so we can focus on 1.0.

Version 1.0 added support for the SSL tunneling protocol, which is what allows web browser to connect to secure web sites on the internet. Despite the name, SSL tunneling protocol is a generic tunneling mechanism you can use to make outgoing connections to any address:port you want and then send and receive data from that site.

A SLL tunnel request looks something like this :

CONNECT somewhere.com:2032 HTTP/1.0

<empty line>

somewhere.com and 2032 are the server and port number you want to connect to.

replied with:

HTTP/1.0 200 Connection established

..other HTTP response headers…

<empty line>

 

After the Connection established response has been received, you can treat the socket connections as though you have a direct connection to the remote server. By using SSL tunneling your game will work with 95% of the proxies. But you have the limitations that you cannot make incoming connections and you cannot use UDP. For any extra 3% of the web proxy server support you must be prepared for handling a SSL tunnel reply stating :


HTTP/1.0 407 Proxy Authentication required

This means that the proxy server needs a username and password before you can use it. In such cases you will need to prompt the user for than information and then resend the request again with authentication information along with the original request like this :

 

CONNECT somewhere.com:2032 HTTP/1.0

Authorization: Basic ZHFjsks9iwf0

<empty line>

The string ZHFjks9iwf0 is the text string "username:password" encoded as a base-64 printable encoding For more information about base-64 encoding see RFC 1421. A RFC "Request For Comments", is a document that describes an internet standard and thousands of them can be found just by searching with any search engine.

 

 

 

SOCKS – (now where did I put the other one?)

Before SOCKS, system administrators often had to install a specific proxy program for each application they wished to allow access to the internet. NEC created SOCKS to solve this problem. The name SOCKS, short for sockets, is printed in capitol letters not because it stands for anything, but to prevent it from being confused with foot apparel.

SOCKS is called a "circuit-level" proxy server because it knows nothing about the data it transmits. Applications connect to a SOCKS server and then can make outgoing connections, accept incomming connections and SOCKSv5 even supports UDP services making it ideal for game developers.

Making a connection through a SOCKS proxy server is slightly more involved. First, you tell the proxy server which authentication methods you support with a structure looking like this

struct supported_methods

{

char ver = 5; // 4 if you want SOCKSv4, 5 if you require UDP

char num_methods = 2; // I’ll talk about 2 methods

char methods[2] = { 0,2 }; // 0 is NO AUTHENTICATION, and 2 is USERNAME/PASSWORD

};

The server responds with 2 bytes, the first being the version of SOCKS it using (5), and the second being the authentication method it wants you to use. If this is 0, then you don’t need to authenticate yourself, and you can proceed to the connection stage. To authenticate yourself, send a structure like this :

struct authenticate_me

{

char ver=1; // authentication version not proxy version

unsigned char user_name_length; // 1..255

char uname[X]; // not NULL terminated!

unsigned char password_length;

char pword[X]; // not NULL terminated!

};

Now you can make a connection to a remote host, bind to a TCP or UDP IP port on the proxy server. This command structure looks like this:

struct command

{

char ver=5; // same as above

char cmd; // 1=CONNECT, 2=TCP BIND, 3=UDP BIND

char reserved=0; // must be 0

char address_type; // 1=4 byte IP address, 3=domain name, 4=6 byte IP address

char address_data[X]; // depends on address type

unsigned short port; // should be in BIG ENDIAN format!

};

After you’ve sent the command to connect or bind, the proxy server should respond with the following structure :

struct command_reply

{

char ver=5; // same as above

char reply; // 0=success, 1-9 are error messages

char reserved;

char address_type; // 1=4 byte IP address, 3=domain name, 4=6 byte IP address

char bind_address_data[X]; // depends on above

unsigned short bind_port; // BIG ENDIAN format!

};

 

If you are making an outgoing connection and you received a SUCCESS reply then you can treat the socket as if you have a direct link to the other user. Reads and writes are proxied. When you close the socket the proxy server shuts down the connection with the other user. If you made a bind request, then you will receive 2 replies, the first having the address and port on the proxy server that is being used. The second reply is sent when a connection is accepted at that port and the reply will contain the address and port of the other user.

For commands that bind ports using UDP, the server will relay packets to and from that port. The following header must be prepending to all outgoing traffic and removed from all incoming traffic:

struct udp_header

{

char reserverd=0;

char fragment_number; // for large packets

char address_type; // 1=4 byte IP address, 3=domain name, 4=6 byte IP address

char dest_address[X];

unsigned short dst_port; // big endian

};

When you close the TCP connection to the proxy server you used to create UDP port, the proxy server will close it’s binding on that port and not retransmit any more data that reaches it.

Configuration

To make your game as easy to play as possible, you should make an effort to self configure proxy support. When Win98 came out it added a "Internet Settings" dialog into the Control Panel (figure 5).

 

If are looking for this dialog with Internet Explorer 5.0 installed it has moved to a button called "Lan Settings", presumably to avoid confusion for modem users.

As shown in Figure 6, this dialog allows the user to set proxy configuration information. Win95 does not have this configuration dialog so you cannot use it to prompt the user, but Internet Explorer still uses and sets the same system registry key through it’s own options menu. Under Windows 95/98 and NT you can find proxy configuration information in the system registry key:

CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\

The subkey "ProxyServer" has a string that looks like this:

"http=201.29.23.87:3218;ftp=201.29.23.87:3128; socks=201.29.23.87:1080"

Http refers to a web proxy (which probably allows SSL tunneling). SOCKS proxy servers generally use the port 1080 and are often built into the web proxy server, so even if they are not configured by the user, you can try a test proxy connection using the http server and port 1080. If this all fails then you can rely on user input to the information, but typically a user won’t know what SOCKS is, so you should you should try to be as automatic as possible.

Netscape Navigator does not use this registry key, so you might want to also check out this key:

CURRENT_USER\Software\Netscape\Netscape Navigator\Proxy Information\ for HTTP_Proxy and HTTPS_Proxy.

There are a few other popular net programs that you can check for which people might have already setup proxy information such as ICQ and AOL Instant Messanger.

 

JAVA considerations

For those of you writing games in JAVA, most of what I’ve written about so far applies, but there are a few things worth mentioning. If you are running the software inside the browser, then TCP connections will automatically be proxied through the same mechanism that the browser uses. However, you can only make outgoing connections to the server the JAVA class file was downloaded from. The outgoing connection will transparently go out through any proxies by using the web browser’s connection code. If you are running your game outside of the browser in your own JAVA virtual machine, you can make connections anywhere you like. Depending on which virtual machine you use, you will most likely have to talk to the proxy servers yourself as you would in C.

Getting your hands on the goods

If you are working at home or at company that doesn’t have all of the proxy services I discussed you can pick up a copy of WinProxy at http://www.tucows.com. This program configures itself through your web browser and has support for HTTP, SOCKS 4 & 5, as well as user Authentication methods. It also includes a built in POP MAIL server, Telnet gateways, FTP gateways, Real Audio Gateways, DNS Relay, News relay, and logs. There are several other programs out there that are capable of doing proxy, but this is my favorite.

NEC offers a commercial product called SocksCap at http://www.socks.nec.com which allows you to run some applications without recompiling. It works by intercepting normal socket calls and transferring them to the proxy server. If you don’t want to add proxy support, but want to allow your customers to use this option there are a couple of things you should keep in mind. Mainly, when creating a new socket let the operating system select the port to bind to. This done by calling connect() directly after socket() without calling bind(). The reason for this is that if you bind to port 3023 then the proxy server must also bind to that port and if there are 2 players behind the same firewall, the operation will fail for one of the players because the proxy server can only bind once.

References:

Book : Web Proxy Servers by Ari Luotonen

http://www.socks.nec.com/socksinfo.html

Need to add proxy support to your application, but short on people to do it?
Contact me about contract work.

Rate this page: Excellent Good Ok Bad Horrible

Other diary entries.....

The Physics of Lens Flares - Tons of pictures! Want to add lens flares to your game? What causes lens flares? Read here.
The Streaming Tree - Taking Napster to the next level. How video will be shared in the future.
So Long Crack dot Com! - The skinny on what happened to Golgotha and Crack dot Com.
Proxies & Firewalls : Playing Games at work. - Discusses what firewalls and proxies are and how you, as a game programmer, can work with them.
Anonymous Publishing on the Internet - Ideas on how to publish information on the internet without being able to trace the source back to you.
Browsing around Amazon.com - Very short book reviews of books I bought this year at Amazon.
Photos : Vacation to Mexico. - Mexico (Cancun, Cozumel, Playa de Carmen, and Mexico City) and Dallas for a wedding.
Making fault tolerant servers. - Discusses what CORBA and DCOM are, why you need them, and which one to use.
Amiga2k and Microsoft's .NET platforms. - What is Amiga2k, where did they come from? How does this compare with Microsoft's .NET platform?
New Paintings and Painting Tips - I've been addicted to my new Wacom drawing tablet lately, checkout some of my recent paintings and painting tips.
Drawings & Paintings - I've been taking a figure sketching class and I thought I'd post a few drawings.
Elimanting external files - Ever wish your application could run as a single file without needing a bunch of external data and DLL files? It's easier than you thought.
BMW Z3 for sale - I'm moving and need to sell my car. Anyone want a Z3, the coolest looking car ever? :)