This is a Quake II proxy (for UNIX systems only, I'm afraid) which proxies packets out of the local network, across a TCP connection, and then masquerades as the client at the other end. It may also work for other games, but I haven't tested them. In fact, this is rather more general than a Quake II proxy: it's a general UDP proxy which can be used to tunnel (and masquerade) UDP over TCP, but Quake II is the most popular application I can think of :-). What this proxy will do:
You can get the latest version of the proxy from the RQProxy home pageThis README contains the following sections:
Find a machine you want to play quake on - A - a machine on the same subnet running UNIX - B (A and B can be the same), and a machine - C -which can talk to B via TCP and to the Quake 2 game server - D. On C, do:
$ q2srv 15004 27910 B DOn B do
$ q2clnt A 27910 B 15004And on A, go to console and do:
] connect BAnd there you go. If you get something like `address already in use' with 15004, try some other number between 1025 and 32767.
Please mail me (Richard.Watts@cl.cam.ac.uk) if you have any problems, or notice any bugs.
More detailed explanations
The source code for four programs is shipped:
q2srv [listen port] [fwd port] [source ip] [target ip]Listen port and source ip are the IP address the TCP stream will come from and the port to listen on, respectively, and fwd port and target ip are the port to forward and the host to forward it to.
q2clnt [listen address] [listen port] [proxy ip] [proxy port]Listen address is the machine to listen to, listen port is the port to listen to, proxy ip is the address of the machine the server is running on, and proxy port is the port the server is listening on.
q2s [port]Listens on a UDP port and prints out all packets that arrive at that port.
q2c [host] [port]Sends a packet containing the data Hello, World! to the given host and (UDP) port once a second until interrupted.
Suppose you have a machine inside a firewall called maui.foo.bar, and a machine outside the firewall called epona.zoop.eep (this will be called the outside proxy machine). You want to play a game of Quake II on maui and you want to forward the traffic through epona to a quake server called quake2.games.foo.bar.net.
You need a Linux machine which packets from maui will reach - we'll call it aztlan.foo.bar (the inside proxy machine). If maui is running Linux, you can probably run the proxy server on it. or your game may slow down (the proxy is quite CPU intensive). You can't run a Quake II server on the internal proxy machin (aztlan).
You only need regular user priveleges on aztlan and epona: root priveleges are NOT required. A typical Quake II game will generate about 2k/s of traffic (ie. it'll saturate a 28k8 baud modem).
Note that, due to the rather odd things the proxy has to do, you can't play Quake II on aztlan whilst it's proxying for maui. See the Technical Details section for more info.
First, start the proxy server on epona:
epona$ q2srv 15004 27910 aztlan.foo.bar quake2.games.foo.bar.netThe 15004 is just a random free port (>1024): if this doesn't work for you (you'll get something like `port already in use'), try some other large number. 27910 is the port on which Quake II servers listen.
You'll get something like:
Binding port 15004 (accepting from XXXXXXXX (aztlan.foo.bar))... Listening for connections...Now q2srv is ready to take packets from the client, and send them as if they came from epona. So, we start the client on aztlan:
aztlan$ q2clnt maui.foo.bar 27910 epona.zoop.eep 15004The 27910 is the UDP port to proxy for (this is the port maui will try to contact to get to the Quake II server), and the 15004 is just the same number you gave the server.
You should get something like:
Binding TCP socket to any old address. Trying to connect to XXXXXXXX (epona.zoop.eep), port 15004 Connected TCP. Opening UDP socket 27910... Waiting for first packet from 820fe880 ...Now, start up Quake II on maui, bring up the console and do:
] connect aztlan.foo.barNote that you can't use Quake II's address book: I don't know why, but I suspect it's something to do with Quake trying to match up the hostname of the inside proxy and the hostname of the game server and failing.
And you should be in business. The client will say something like:
malloc 804d220 Got from XXXXXXXX (27901) Starting packet forwarding for XXXXXXXX (port 27901).. From port now fixed at XXXXXXXXAnd the server will print up some acknowledgement and start printing lines of the form:
1.621588 k/s (2411561 bytes, 2355 k total) 1.849273 k/s (2427960 bytes, 2371 k total) 1.768825 k/s (2444370 bytes, 2387 k total)To terminate the connection, interrupt the server by pressing ^C at its console. It will then show you the total transfer time and the cost of your game at 2p/Mbyte:
Your game cost 2454071 bytes (2396 K, 2 Mbyte), or 4.680769 p at 2p/Mbyte(2p/Mbyte is the cost of a transatlantic transfer over JANET outside 1am-6am).
Why should I want to use this ?
There are a few reasons you might actually find this program useful:
Technical Details
Herein is the wisdom I've carefully hoarded for, oh, at least fifteen
minutes: it's probably mostly wrong.
Quake II is actually rather civilised about its networking requirements: everything is done over plain UDP.
The proxy works like this. We shall call the machine that picks up UDP packets and turns them into TCP (and runs the client) the inside proxy machine, and the machine that picks up the TCP (and runs the server) the outside proxy machine:
Attempts to proxy servers from other ports (eg. proxy port 24000 -> quake2 server port 27910) have failed, as have attempts to use a different proxy port on the outside proxy machine: this is why you can't run a Quake II server on the inside proxy, or a client on the outside proxy. It's also why you need one IP address per server proxied. Sorry :-(.
Implementation Detail
The implementation of the client and server are actually quite
subtle: they both have the same basic structure, but since Quake II
never throttles, we have to make sure we don't queue packets. Both the
server and the client are structured as poll loops, with a select() at
the top to ease the CPU load:
Config File Defines
You shouldn't need to worry about these unless you're modifying the
proxy, but :
You can get copies of those licences either from me or from the Perl and glibc distributions respectively.
Have Fun
:-) - and send me some feedback if you find this proxy useful: you
never know, I may be bored again some day :-).
Richard, Richard.Watts@cl.cam.ac.uk. (aka. Kosh: I may not be able to shoot straight, but I can write low-latency proxies in an evening, so there :-)).