(Note: This was taken from the abandoned.org/nemon/compress/protocol.html page.  This page no longer seems to exist, so I wanted to preserve the spec here.  --Zugg.
Original page now at: http://www.randomly.org/projects/MCCP/)

The Mud Client Compression Protocol - Specification - Version 2

This document describes version 2 of the protocol, using the COMPRESS2 option. An earlier version described a protocol using the COMPRESS option -- this is referred to as the version 1 protocol below.

The protocol used by mcclient is based on 'telnet' option negotiation. See RFCs 854 and 855 for an overview of the mechanism used.

Compression is currently unidirectional - only output from the mud server is compressed. This simplifies the implementation, and also avoids potential problems with hostile clients sending data intended to cause problems (via crashing or excessive memory/cpu use) with the decompressor. The compressor is entirely controlled by the server. While attacks on the client are potentially possible, this seems less of a problem as the client is not a shared resource.

Servers supporting version 2 (this version) of the protocol should indicate they support it by offering the COMPRESS2 option (number 86): IAC WILL COMPRESS2. They may also optionally offer the older version 1 option (number 85) to support older clients: IAC WILL COMPRESS. Servers should offer COMPRESS2 before COMPRESS to allow newer clients to support any extra features added to COMPRESS2 in the future while still supporting COMPRESS.

Clients should respond to the COMPRESS2 option with IAC DO COMPRESS2 if they want the server to enable compression. To support older servers, clients may respond to the COMPRESS option with IAC DO COMPRESS, although it is recommended that the COMPRESS option is refused with IAC DONT COMPRESS if COMPRESS2 has been previously offered by the server.

There is no requirement for either server or client to support the version 1 protocol.

Once either COMPRESS or COMPRESS2 is negotiated, the server may enable compression. Since the start point of the compression stream needs to be known, the server prefixes the start of the stream with a suboption negotiation packet. This is IAC SB COMPRESS WILL SE for the obsolete COMPRESS option (note that this is not a valid suboption negotiation sequence according to RFC854/855 -- the terminating SE isn't correctly escaped), or IAC SB COMPRESS2 IAC SE for the COMPRESS2 option.

Immediately following this, a zlib stream (as defined in RFC 1950 - see also the zlib home page) begins.

In summary, negotiation between server and client takes one of these forms:

  version 1 server                      version 1 client
  IAC WILL COMPRESS
                                        IAC DO COMPRESS
  IAC SB COMPRESS WILL SE
  (compressed stream)

  version 2 server (supporting v1)      version 1 client
  IAC WILL COMPRESS2
  IAC WILL COMPRESS
                                        (nothing) or IAC DONT COMPRESS2
                                        IAC DO COMPRESS
  IAC SB COMPRESS WILL SE
  (compressed stream)
    
  version 2 server (not supporting v1)  version 1 client
  IAC WILL COMPRESS2
                                        (nothing) or IAC DONT COMPRESS2
  (uncompressed connection continues)
    
  version 1 server                      version 2 client (supporting v1)
  IAC WILL COMPRESS        
                                        IAC DO COMPRESS
  IAC SB COMPRESS WILL SE
  (compressed stream)
  
  version 1 server                      version 2 client (not supporting v1)
  IAC WILL COMPRESS        
                                        IAC DONT COMPRESS
  (uncompressed connection continues)
  
  version 2 server                      version 2 client
  IAC WILL COMPRESS2
  IAC WILL COMPRESS
                                        IAC DO COMPRESS2
                                        IAC DONT COMPRESS
  IAC SB COMPRESS2 IAC SE
  (compressed stream)

The compressed data should be transmitted unescaped. IAC should be sent as-is. Telnet option negotiation and IAC escaping continues as normal for the uncompressed data stream -- the entire telnet TCP stream is compressed, negotiation and all.

Compression can only be terminated by the server - a normal end to the compression stream is assumed to mean "revert to uncompressed mode". It may be desirable for the server to automatically terminate compression when an IAC DONT COMPRESS sequence is received from the client.

Any decompression errors are unrecoverable, and should result in a disconnection. Given that TCP is a reliable transport mechanism, bug-free implementations should never encounter compression errors, so this should not affect normal operation. When an error is encountered, something has gone badly wrong, and it seems hard to recover. Allowing raw (uncompressed) option negotiation to reset compression is one possibility, but would require that option negotiation take place outside the compressed stream.

 
Oliver Jowett <icecube@ihug.co.nz>, 2000/05/30