
   Tired of not being able to play on the company's QII server from home
   ?
   Irritated by sysadmins blocking your Quake II packets ?
   Have a machine on the other side of the firewall lying around doing
   nothing ?
   You need...
   
                   [1]RQProxy - Richard's Quake II Proxy
                                      
             By [2]Richard Watts, [3]Richard.Watts@cl.cam.ac.uk
                                      
   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:
     * Allow you to play Quake II through a firewall that blocks Quake II
       packets.
       
   What this proxy will not do:
     * Allow you to proxy more than one Quake II server per IP address.
     * Allow you to play Quake II through a firewall without having a
       machine on the other side of the firewall (you don't need root on
       either machine).
     * Allow you to use Quake II's address book: it just doesn't work -
       don't ask me why. You'll have to use connect from the console. On
       the bright side, the spy protocols for things like XQF seem to get
       through our firewall just fine, so you can still see whether
       servers are up or down.
       
   There are reasons for this: see the technical details section at the
   end. Problems, questions, pieces of cheese, etc., should be sent to
   [4]Richard.Watts@cl.cam.ac.uk.
   
   You can get the latest version of the proxy from [5]the RQProxy home
   pageThis README contains the following sections:
   
     * [6]Quick Start.
     * [7]More detailed explanations
     * [8]Proxying a Quake II game
     * [9]Why should I want to use this ?
     * [10]Technical Details
     * [11]Implementation Details
     * [12]Config file defines
     * [13]Licencing
     * [14]Have fun
     _________________________________________________________________
   
Quick Start

   Unpack the distribution, cd to the src directory and do make to build
   the client and server.
   
   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 D

   On B do
   
$ q2clnt A 27910  B 15004

   And on A, go to console and do:
   
] connect B

   And 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 ([15]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
          This is the Quake II proxy server. It accepts UDP packets over
          a TCP connection, extracts them from the TCP stream, and
          resends them to a destination given on the command line. Its
          syntax is:
          
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
          This is the proxy client: it takes UDP from given machine and
          port and wraps them into a TCP connection to the server. Its
          syntax is:
          
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
          Syntax:
          
q2s [port]

   Listens on a UDP port and prints out all packets that arrive at that
          port.
          
   q2c
          Syntax:
          
q2c [host] [port]

   Sends a packet containing the data Hello, World! to the given host and
          (UDP) port once a second until interrupted.
          
Proxying a Quake II Game

    BE SURE TO DISCONNECT YOUR QUAKE II CLIENT BEFORE CHANGING THE QUAKE
   II SERVER YOU'RE PROXYING TO, OR BOTH YOUR CLIENT AND THE SERVER WILL
                         BECOME TERRIBLY CONFUSED. 
                                      
   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
   [16]Technical Details section for more info.
   
   First, start the proxy server on epona:
   
epona$ q2srv 15004 27910 aztlan.foo.bar quake2.games.foo.bar.net

   The 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 15004

   The 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.bar

   Note 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 XXXXXXXX

   And 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:
   
     * Your sysadmin may have firewalled Quake II packets. This is a good
       way to get around the firewall (yes, I know, I'm beginning to
       sound like RMS).
     * Server admins may want to use it to allow users to connect to
       another server whilst theirs is down: when the other server comes
       back up, players will be able to reconnect without having to
       reconfigure their clients.
     * You may want to reverse-engineer the network protocol, or do other
       natty things (like substituting clients on the fly to see what'll
       happen): the proxy gives you the framework to do this, but it's
       1am so I don't intend to do any more now :-).
     * You may be a sysadmin, and want to control (and throttle) which
       servers your users can access. Firewall rules are a better way to
       do this, but you may want to use this proxy as an alternative.
     * You may want to run a `best of' server for clan meetings and the
       like: again, there are much better ways to do this, but if you're
       in an environment where you can't use them for some reason, you
       can use the proxy.
     * You may be interested in how to do low-latency proxying.
       
   The proxy consumes almost no CPU (it's only a 2k/s proxy anyway), so
   there's no reason not to use it where it would be an elegant solution.
   
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 server listens on port 27910 for a client connect packet. When
     * S client is asked to connect, it opens local port 27901 and sends
       a challenge to the server.
     * The server responds, and communication is established.
       
   Subsequent communication is in the form of small (c. 30-byte) UDP
   packets. These packets are exceptionally sensitive to latency, and
   throttling seems not to take place at all: if the client starts
   lagging, tough. It appears as though these packets are statements
   about the world.
   
   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:
   
    1. When the server starts up, it opens a TCP server socket on the
       outside proxy machine to listen for the client.
    2. The client starts up, and opens its UDP proxy port (usually 27910)
       on the inside proxy machine. It monitors activity on this port
       until it gets a packet from the source machine (this isn't
       confused by other UDP traffic, because only UDP traffic to 27910
       on the inside proxy will be monitored).
    3. The client then finds out what port that packet was sent from
       (typically 27901), opens a TCP connection to the server, and sends
       the port number down the wire.
    4. The server then attempts to open that UDP port number on the
       outside proxy machine.
    5. Subsequently, both sides listen for packets to their UDP ports,
       and transmit them over the TCP connection, and listen for packets
       on the TCP connection to proxy to their TCP ports.
       
   From the Quake II server's PoV, the server (running on the outside
   proxy) looks like the client, whereas from the client's PoV, the
   client (running on the inside proxy machine) looks like the server.
   
   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:
   
     * Having the server do (read TCP/write UDP, read UDP/write TCP) and
       the client do (read UDP/write TCP, write TCP/read UDP). This is an
       immense help, and indeed, if you swap those around again, the
       proxy will stop working.
     * If either end gets two UDP packets in a row, the last one is
       dropped, and if there are more than three TCP packets on the
       queue, all the other packets are dropped.
     * The TCP queue is cleared on every loop.
       
   I apologise for the code: it was written between about 10pm and
   midnight, and therefore suffers from both my RSI and my caffeine
   addiction...
   
Config File Defines

   You shouldn't need to worry about these unless you're modifying the
   proxy, but :
   
   MAX_PACKET_SZ
          The maximum size of a packet: if you get packet overflows,
          increase this (but given that the ethernet MTU is 1500 and the
          modem MTU is 576. UDP packets 8k long will tend to get dropped
          by the routing infrastructure anyway).
          
   DELAY
          Irrelevant and useless.
          
   TGT_OFFSET
          The number to add to the port number sent by the inner proxy to
          get the UDP port number for the outer proxy: connection fails
          if it's anything other than 0.
          
   FLIP_PORT
          don't change this. It's a debugging define.
          
   DEBUG
          If defined, print out debugging info.
          
   STATS
          If defined, print out more detailed statistics.
          
   TIMING
          If defined, print out timing information.
          
   OLD_THROTTLE
          If defined, include some old throttling code that doesn't do
          anything any more.
          
Licencing

   The proxy is licenced under either Larry Wall's Artistic Licence or
   the LGPL, at your option. Mail me if you want to do anything else with
   it.
   
   You can get copies of those licences either from [17]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, [18]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 :-)).
     _________________________________________________________________
   
   
    [19]Richard Watts [20]<Richard.Watts@cl.cam.ac.uk>
    
   Last modified: Wed Oct 21 02:32:56 GMT 1998

References

   1. http://epona.ucam.org/rrw/qproxy.html
   2. http://epona.ucam.org/rrw/index.html
   3. mailto:Richard.Watts@cl.cam.ac.uk
   4. mailto:Richard.Watts@cl.cam.ac.uk
   5. http://epona.ucam.org/rrw/qproxy.html
   6. file://localhost/mnt/hda9/rrw/work/misc/quake/README.html#quick
   7. file://localhost/mnt/hda9/rrw/work/misc/quake/README.html#detail
   8. file://localhost/mnt/hda9/rrw/work/misc/quake/README.html#proxy
   9. file://localhost/mnt/hda9/rrw/work/misc/quake/README.html#why
  10. file://localhost/mnt/hda9/rrw/work/misc/quake/README.html#tech
  11. file://localhost/mnt/hda9/rrw/work/misc/quake/README.html#impl
  12. file://localhost/mnt/hda9/rrw/work/misc/quake/README.html#config
  13. file://localhost/mnt/hda9/rrw/work/misc/quake/README.html#licencing
  14. file://localhost/mnt/hda9/rrw/work/misc/quake/README.html#fun
  15. mailto:Richard.Watts@cl.cam.ac.uk
  16. file://localhost/mnt/hda9/rrw/work/misc/quake/README.html#tech
  17. mailto:Richard.Watts@cl.cam.ac.uk
  18. mailto:Richard.Watts@cl.cam.ac.uk
  19. http://www.cl.cam.ac.uk/users/rrw1000
  20. mailto:Richard.Watts@cl.cam.ac.uk
