(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/) Note: I've taken Zugg's copy and mirrored it yet again, since the randomly.org page seems to no longer exist either.
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