RFC 1974

PPP Stac LZS Compression Protocol

๐Ÿ“… published August 1996, from ietf

RFC 1974: PPP Stac LZS Compression Protocol ๐Ÿ’– (Part 1 of 4)

Okay bestie, the title block tea is this: it's RFC 1974, called PPP Stac LZS Compression Protocol ๐ŸŽ€ It came out of the Network Working Group, written by R. Friend from Stac Electronics and W. Simpson from DayDreamer ๐Ÿ‘‘ It's filed as Informational and dated August 1996 ๐ŸŒธ The title block doesn't list anything it obsoletes or updates, so that part is a blank ๐Ÿงš


Status of this Memo ๐ŸŒˆ

This memo provides information for the Internet community ๐Ÿ’… It does not specify an Internet standard of any kind. Distribution of this memo is unlimited.


Abstract ๐Ÿซถ

Quick recap โœจ The Point-to-Point Protocol (PPP) [1] gives everyone a standard way to carry multi-protocol datagrams over point-to-point links ๐Ÿงš

The PPP Compression Control Protocol [2] is the one that lets two sides negotiate and use compression protocols over PPP encapsulated links ๐Ÿ’œ

This doc describes how to use the Stac LZS data compression algorithm, with single or multiple compression histories, to compress PPP encapsulated packets ๐Ÿฆ‹


Table of Contents ๐Ÿ“š

     1.     Introduction ..........................................    2
        1.1       Licensing .......................................    2
        1.2       Specification of Requirements ...................    3
     2.     LZS Packets ...........................................    3
        2.1       Padding .........................................    4
        2.2       Zero Deletion/Insertion .........................    4
        2.3       Reliability and Sequencing ......................    4
           2.3.1  Reset-Request and Reset-Ack Packet Formats.......    5
        2.4       Data Expansion ..................................    6
        2.5       Packet Format ...................................    6
           2.5.1  PPP Protocol ....................................    7
           2.5.2  History Number ..................................    7
           2.5.3  Check Value .....................................    7
              2.5.3.1  LCB ........................................    7
              2.5.3.2  CRC ........................................    7
              2.5.3.3  Sequence Number ............................    8
                 2.5.3.3.1  History Synchronization with Sequence
                             Numbers Example ......................    9

           2.5.4  History Synchronization Procedure ...............   10
           2.5.5  Compressed Data .................................   11
     3.     Sending Compressed Datagrams ..........................   12
        3.1       Transmitter Process .............................   12
        3.2       Receiver Process ................................   12
        3.3       History Maintenance .............................   13
        3.4       History Resynchronization Mechanism .............   14
     4.     Configuration Option Format ...........................   14
     5.     Definition of Extended Mode ...........................   16
        5.1       Extended Mode Packet Format .....................   16
        5.2       Extended Mode Transmitter Process ...............   18
        5.3       Extended Mode Receiver Process ..................   18
        5.4       Extended Mode Synchronization ...................   19
     SECURITY CONSIDERATIONS ......................................   19
     REFERENCES ...................................................   20
     CHAIR'S ADDRESS    ...........................................   20
     AUTHORS' ADDRESSES............................................   20

1. Introduction โœจ

Okay so picture this: Stac Electronics starts from a sliding window compression history, similar to LZ1 [3], and builds a new, enhanced algorithm called Stac LZS ๐Ÿ”ฅ The LZS algorithm is tuned to squash all file types as efficiently as possible. Even string matches as short as two octets get compressed well ๐Ÿ’…

Stac LZS supports both single compression history communication and multiple compression history communication ๐ŸŽ€

A single compression history will require the minimum amount of memory to implement, but it may not provide as much compression as a multiple history implementation ๐ŸŒธ

Often, many streams of information are interleaved over the same link ๐Ÿฆ‹ Each virtual link transmits data that is independent of the other virtual links. Using multiple compression histories can improve the compression ratio of a communication link by giving each virtual link its own separate history ๐Ÿ’œ

1.1. Licensing

Licensing tea ๐Ÿงš Source and object licenses are available on a non-discriminatory basis, and hardware implementations are available too. For more info, contact Stac Electronics at the address and phone number listed with the author's address.

1.2. Specification of Requirements

Now for the key words ๐Ÿ‘‘ In this document, several words are used to signify the requirements of the specification. These words are often capitalized, so here's the glossary:

  • MUST: this word, or the adjective "required", means that the definition is an absolute requirement of the specification.
  • MUST NOT: this phrase means that the definition is an absolute prohibition of the specification.
  • SHOULD: this word, or the adjective "recommended", means there may exist valid reasons in particular circumstances to ignore this item, but the full implications MUST be understood and carefully weighed before choosing a different course.
  • MAY: this word, or the adjective "optional", means that this item is one of an allowed set of alternatives. An implementation which does not include this option MUST be prepared to interoperate with another implementation which does include the option.

2. LZS Packets ๐Ÿ“ฆ

Before any LZS packets may be communicated, PPP must reach the Network-Layer Protocol phase ๐Ÿšฆ

Here's the big one ๐Ÿ’– When the Compression Control Protocol (CCP) has reached the Opened state, and LZS is negotiated as the primary compression algorithm, exactly one Stac LZS datagram gets encapsulated in the PPP Information field. The PPP Protocol field then indicates either type hex 00FD (compressed datagram) or type hex 00FB (Individual link compressed datagram).

Type hex 00FD is used when compression is negotiated over a single physical link, or when compression is negotiated over a single bundle made of multiple physical links. Type hex 00FB is used when compression is negotiated separately over individual physical links to the same destination. For more information, please refer to PPP Compression Control Protocol.

When CCP has not successfully reached the Opened state, or LZS is not the primary compression algorithm, exactly one LZS datagram gets encapsulated in the PPP Information field, where the PPP Protocol field indicates type hex 4021 (Stac LZS).

Heads up: in that second case, LZS use is terminated by the PPP LCP Protocol-Reject. The default format is used: a single history with no History Number field and no Check Value field (as if the negotiated history count were 1).

The maximum length of the Stac LZS datagram transmitted over a PPP link is the same as the maximum length of the Information field of a PPP encapsulated packet ๐Ÿ“

Before compression, the uncompressed data begins with the PPP Protocol ID Field. Protocol-Field-Compression MAY be used on this value, if it has been successfully negotiated for the link ๐Ÿซง

The PPP Protocol ID Field is followed by the original Information field. The length of the uncompressed data field is limited only by the allowed size of the compressed data field and the higher protocol layers.

PPP Link Control Protocol packets MUST NOT be sent within Stac LZS packets. PPP Network Control Protocol packets MUST NOT be sent within Stac LZS packets. Not allowed, bestie ๐Ÿ™…โ€โ™€๏ธ

2.1. Padding

The LZS Information field always ends with the last compressed data byte (also known as the <end marker>), which is used to disambiguate padding ๐Ÿ•ต๏ธโ€โ™€๏ธ This allows trailing bits as well as octets to be considered padding.

2.2. Zero Deletion/Insertion

When the sender does not add Padding [1], any trailing zero octets MAY be removed prior to transmission ๐Ÿงน A single trailing zero octet MUST be appended upon receipt, after removal of any framing FCS. Put it back, periodt ๐Ÿ’…

2.3. Reliability and Sequencing

Reliability tea ๐Ÿซ– When no Compression History is kept, the algorithm does not depend on a reliable link, and does not require that packets be delivered in sequence. However, per packet compression results in a lower compression ratio than it could be on a stream ๐Ÿ˜ญ

Some reasons for resetting the history on a per packet basis include:

  • The link has a high error rate.
  • The resources of the transmitter or receiver limit the ability to maintain a compression history between packets.

When more than 1 Compression History is negotiated, the packet sequence MUST be preserved within specific History Numbers. There is no sequence requirement between different History Numbers โœจ

When one or more compression histories are negotiated on the link, the implementation MUST implement either a lower layer reliable link protocol, or keep the compressor and decompressor histories in synchronization, or both ๐Ÿ”—

To maintain history synchronization, the implementation MUST use the Reset-Request and Reset-Ack messages of the Compression Control Protocol and MUST use an Option 17 check mode value of sequence numbers (and MAY implement other check mode values other than none). In this case, the Data field of the CCP Reset-Request and Reset-Ack MUST contain the two octet History Number to be reset, most significant octet first ๐Ÿ”ข

If neither of these conditions is met on the data link, then the compression histories MUST be reset after transmitting each datagram ๐Ÿงผ

The transmitter MAY clear a Compression History at any time. The receiver is implicitly notified of this event, and the decompression history will automatically be affected. Silent but deadly ๐Ÿฅท

The transmitter MUST reset a history after a CCP Reset-Request for the given History Number.

2.3.1. Reset-Request and Reset-Ack Packet Formats

Here's a summary of the CCP Reset-Request and Reset-Ack packet formats for Stac LZS compressed links. The fields are transmitted from left to right ๐Ÿงฉ

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Code      |  Identifier   |            Length             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |              Data             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Code

  • 14 for Reset-Request;
  • 15 for Reset-Ack.

Identifier

On transmission, the Identifier field MUST be changed whenever the content of the Data field changes, and whenever a valid reply has been received for a previous request. For retransmissions, the Identifier MAY remain unchanged ๐Ÿ”„

On reception, the Identifier field of the Reset-Request is copied into the Identifier field of the Reset-Ack packet ๐Ÿชž

Data

The Data field contains the two octet History Number of the compression history that is to be reset, most significant octet first. This History Number value is 1 when no history number is present ๐Ÿ’œ

2.4. Data Expansion ๐Ÿ’…

Okay bestie, the absolute max expansion Stac LZS can do is 12.5% ๐Ÿ“โœจ That's the ceiling, so you know exactly how much room to expect.

A Maximum Receive Unit (MRU) MAY be negotiated that's 12.5% bigger than a normal packet ๐ŸŽ€ With that extra headroom, packets can always go out compressed, even when they expand a little ๐Ÿฆ‹

If the expansion plus the compression header goes over the peer's MRU for the link, the PPP packet MUST be sent uncompressed ๐Ÿ™…โ€โ™€๏ธ It goes out in its original PPP packet form with the "native" PPP Protocol ID number. And the transmitter MUST reset the affected history ๐Ÿ”„

If it's detected that most packets are expanding (like, because the data was already compressed ๐Ÿ’€), the transmitter SHOULD stop sending compressed packets and reset the appropriate history. Data compression MAY be resumed on this data link later ๐ŸŒธ


2.5. Packet Format ๐Ÿ“

Here's the Stac LZS packet format at a glance ๐Ÿ‘€ The fields go left to right โžก๏ธ

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         PPP Protocol          |       (History Number*)       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|        (Check Value*)         |       Compressed Data ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * Note: these fields are variable length fields as described below.

2.5.1. PPP Protocol

The PPP Protocol field is 2 octets, and it's described in the Point-to-Point Protocol Encapsulation [1] ๐Ÿ“ฆ

When Stac LZS is successfully negotiated by the PPP Compression Control Protocol [2], the value is 00FD hex or 00FB hex, as described in section 2. This value MAY be compressed when Protocol-Field-Compression is negotiated ๐Ÿ—œ๏ธ

2.5.2. History Number

The history number field is 0, 1, or 2 octets, depending on the setup ๐Ÿงฉ

It holds the number of the compression history that was used, ranging from 2 to the negotiated History Count. By default a History Count of value 1 is supported, and in that case this field isn't present ๐Ÿ™ˆ

If the negotiated History Count is less than 2, the field gets removed. There's no need for it when no history is kept, or when only a single history is kept โœจ

If the negotiated History Count is 2 or more but less than 256, this field is 1 octet. If 256 or more histories are negotiated, this field is 2 octets, most significant octet first ๐Ÿ”ข

2.5.3. Check Value

The check value field is 0, 1, or 2 octets. By default, a sequence number check gets added to the packet, and in that case the field is 1 octet ๐Ÿ•ต๏ธโ€โ™€๏ธ

2.5.3.1. LCB

A simple one octet Longitudinal Check Byte (LCB) MAY be used, once the LCB option has been successfully negotiated ๐Ÿญ

The LCB is the Exclusive-OR of FF(hex) and each octet of the uncompressed datagram (before the compression operation). On receipt, the receiver computes the Exclusive-OR of FF(hex) and each octet of the decompressed packet. If that value doesn't match the received LCB, then a receive failure for that history has happened ๐Ÿ’” The receive failure gets handled according to the history synchronization procedure in section 2.5.4 ๐Ÿ› ๏ธ

2.5.3.2. CRC

A two octet Cyclic Redundancy Check (CRC) MAY be used instead of the LCB, once the CRC option has been successfully negotiated ๐Ÿ”

The transmitter MUST initialize the CRC value to FFFF (hex) at the beginning of each packet. The CRC computation is based on the HDLC FCS-16 polynomial:

x**16 + x**12 + x**5 + 1

The ones complement of the CRC is transmitted least significant octet first, which holds the coefficient of the highest term ๐ŸŽฏ On receipt, the receiver initializes the CRC to FFFF (hex) and computes the CRC based on the formula above for each octet of the decompressed packet. If the received CRC value doesn't match the transmitted CRC value, then a receive failure for that history has happened ๐Ÿ˜ญ That gets handled according to the history synchronization procedure in section 2.5.4 ๐Ÿ’…

2.5.3.3. Sequence Number

A one octet Sequence Number MAY be used instead of an LCB or CRC, once the Sequence Number option has been successfully negotiated ๐Ÿ”ข

After CCP has reached the open state, the transmitter MUST set the value of the sequence number field (the sequence number of the packet) to "1", then increment it modulo 256 on successive packets that contain data fields. The sequence number is relative to the history number used ๐Ÿงฎ

After CCP has reached the open state, the receiver MUST set its internal reference value of the next expected sequence number (the sequence number of the next packet to be received) to "1" ๐Ÿ‘€

After a packet is received, the receiver MUST set its internal reference value of the next expected sequence number for that history to the sequence number field of the received packet plus 1, modulo 256 โž•

If the sequence number of the received packet isn't equal to the internal reference value of the expected sequence number for the same history, a receive failure for that history has happened ๐Ÿšจ The receiver MUST silently discard the out of order packet, and handle the failure according to the history synchronization procedure in section 2.5.4 ๐Ÿคซ

The sequence number MUST NOT be reset by the transmitter when a packet containing a Reset-Req is received. The receiver MUST always maintain its sequence number references for all supported histories ๐Ÿซถ

2.5.3.3.1 History Synchronization with Sequence Numbers Example

Okay, here's the sequence number sync dance step by step ๐Ÿ’ƒ

Compressing Sender                Decompressing Receiver
....                              ....
send seq 101     ----------->     recv seq 101
                                  is 101 == 101?  Ok.
                                  forward packet for processing
                                  set internal reference to 102

send seq 102     ----------->     recv seq 102
                                  is 102 == 102?  Ok.
                                  forward packet for processing
                                  set internal reference to 103

send seq 103     ------X          (packet lost)

send seq 104     ----------->     recv seq 104
                                  is 104 == 103?  Send reset req!
                                  silently discard packet
                                  set internal reference to 105

(packet lost)        X-------     send reset request (ID=200)
                                  post-increment the identifier.

send seq 105     ----------->     recv seq 105
                                  is 105 == 105?  Ok.
                                  was reset ack received?  No!
                                  silently discard packet
                                  set internal reference to 106

                 <-----------     send reset request again(ID=200)
                                  (e.g. reset-ack time out)

send seq 106     ------X          (packet lost)

recv reset req   <-----------
(after line delay)
   (ID=200)

reset compression
   history
send reset ack   ----------->     recv reset ack (ID=200)
   (ID=200)

send seq 107     ----------->     recv seq 107
                                  is 107 == 106?  Send reset req!
                                  silently discard packet
                                  set internal reference to 108

recv reset req   <-----------     send reset request (ID=201)
   (ID=201)                       post-increment the identifier.

send seq 108     ----------->     recv seq 108
                                  is 108 == 108?  Ok.
                                  was reset ack received?  No!
                                  silently discard packet
                                  set internal reference to 109

send seq 109     ----------->     recv seq 109
                                  is 109 == 109?  Ok.
                                  was reset ack received?  No!
                                  silently discard packet
                                  set internal reference to 110

reset compression
   history
send reset ack   ----------->     recv reset ack (ID=201)
   (ID=201)

send seq 110     ----------->     recv seq 110
                                  is 110 == 110?  Ok.
                                  forward packet for processing
                                  set internal reference to 111

send seq 111     ----------->     recv seq 111
                                  is 111 == 111?  Ok.
                                  forward packet for processing
                                  set internal reference to 112
....                              ....

2.5.4. History Synchronization Procedure

On receipt, if Sequence Number one (1) follows any other number than zero (0), or is otherwise out of sequence, or the LCB or CRC is invalid, then a CCP Reset-Request MUST be sent ๐Ÿšฉ It contains the two octet History Number (most significant octet first, and it's the value 1 when no History Number is present), along with a CCP Identifier. Identifiers get incremented on each occurrence of an out of sequence packet ๐Ÿ”

Upon receipt of the Reset-Request, the transmitter MUST reset the affected compression history, and transmit a CCP Reset-Ack packet. Its Identifier field and data (history number) field are set to the corresponding values of the Reset-Request ๐Ÿชž However, the Sequence Number (if implemented) is not reset ๐Ÿ™…โ€โ™€๏ธ

For each packet that generates a receive failure, the receiver MUST increment the Identifier and transmit a CCP Reset-Request. For re-transmissions of existing receive failures, the Identifier MUST NOT be incremented ๐Ÿซ 

After transmitting the Reset-Request packet, the receiver MUST continue silently discarding valid compressed packets for the corresponding history. It keeps doing that until the correct CCP Reset-Ack Identifier (matching the Reset-Request) for that History Number arrives ๐Ÿค And note that if sequence numbers are used, the receiver MUST process the sequence number of a received packet according to the procedures in section 2.5.4 ๐Ÿง 

2.5.5. Compressed Data

The data field MUST contain only one datagram in compressed form. The length of this field is always an integer number of octets. There MUST BE only one end marker per block of compressed data ๐Ÿ

The form of the data field is one block of compressed data as defined in 3.2 of X3.241-1994. It's repeated here for informational purposes ONLY ๐Ÿ“š

<Compressed Stream> := [<Compressed String>] <End Marker>
<Compressed String> := 0 <Raw Byte> | 1 <Compressed Bytes>
<Raw Byte> := <b><b><b><b><b><b><b><b>          (8-bit byte)
<Compressed Bytes> := <Offset> <Length>

<Offset> := 1 <b><b><b><b><b><b><b> |           (7-bit offset)
            0 <b><b><b><b><b><b><b><b><b><b><b> (11-bit offset)
<End Marker> := 110000000
<b> := 1 | 0

   <Length> :=
   00        = 2     1111 0110      = 14
   01        = 3     1111 0111      = 15
   10        = 4     1111 1000      = 16
   1100      = 5     1111 1001      = 17
   1101      = 6     1111 1010      = 18
   1110      = 7     1111 1011      = 19
   1111 0000 = 8     1111 1100      = 20
   1111 0001 = 9     1111 1101      = 21
   1111 0010 = 10    1111 1110      = 22
   1111 0011 = 11    1111 1111 0000 = 23
   1111 0100 = 12    1111 1111 0001 = 24
   1111 0101 = 13     ...

3. Sending Compressed Datagrams โœจ

okay so getting datagrams across the data link reliably AND efficiently depends on the processes below ๐Ÿ’…

3.1. Transmitter Process

when a network datagram shows up, it gets assigned to a specific history buffer and then gets run through ANSI X3.241-1994 to become compressed data ๐ŸŽ€ before any compression happens, if a Reset-Request is still outstanding for that history buffer, or the negotiated history count for this data link is 0, the history buffer gets cleared ๐Ÿงน

uncompressed data MUST be sent (in the original PPP packet form with the "native" PPP Protocol ID number) if compression causes enough expansion that the compressed datagram size goes over the Information field's MRU ๐Ÿ˜ญ and since the compressor already changed the history buffer before sending that uncompressed datagram, the history buffer MUST be cleared before the next datagram gets processed ๐ŸŒธ

the compression output goes into the information field of the datagram โœจ if the sequence number field is present (based on the check mode field), the sequence number counter for the applicable history number MUST be incremented, and its value goes in the sequence number field ๐Ÿฆ‹ if the LCB field is present (again, based on the check mode field), the LCB value MUST be computed as specified in section 2.5.3.1. and placed in the LCB field ๐Ÿ’– if the CRC field is present, the CRC value MUST be computed as specified in section 2.5.3.2. and the resultant value placed in the LCB field ๐Ÿ™ˆ and when a CCP Reset-Request packet comes in, the transmitting compressor MUST be cleared to an initial state, which includes clearing the history buffer ๐Ÿ’€ on top of resetting the compressor, a CCP Reset-Ack packet MUST be transmitted ๐Ÿซถ the data field of that packet MUST be filled with the corresponding two octet history number, most significant octet first ๐Ÿ‘‘

3.2. Receiver Process

if a CCP Reset-Request packet is received, the local compression engine MUST be signaled that a Reset-Request came in for the history number listed in the data field ๐Ÿ”ฅ if a CCP Reset-Ack packet is received, any outstanding receive failure for the specified history MUST be cleared โœจ if there's no receive failure outstanding and the sequence number field is present, its value gets checked ๐Ÿ‘€ if a receive failure has happened, it MUST be handled according to the history resynchronization mechanism described below, and the rest of the datagram is discarded ๐Ÿ’…

if no receive failure is detected, the data gets assigned to the indicated decompression history buffer, and the compressed data block MUST be decompressed according to ANSI X3.241-1994 ๐Ÿงš if the LCB or CRC fields are present on the received datagram, an LCB or CRC for the uncompressed data MUST be computed and checked against the received LCB or CRC, following sections 2.5.3.1. or 2.5.3.2., respectively ๐ŸŒˆ if a receive failure has occurred, it MUST be handled according to the History Resynchronization Mechanism described in section 3.4 ๐Ÿซ 

if a CCP Reset-Ack packet is received, the receiving decompressor's corresponding history MAY be reset to an initial state. (however, because of the characteristics of the Stac LZS algorithm, a decompressor history reset is not required ๐Ÿคทโ€โ™€๏ธ). after any reset, any compressed or uncompressed data in the packet gets processed ๐Ÿ“

when a receive failure happens, an implementation MUST transmit a CCP Reset-Request packet, with the data field holding the two octet history number (most significant octet first) that matches the history that failed ๐Ÿšจ once a receive failure has occurred, the data in any packets received after that for that history MUST be discarded until a CCP Reset-Ack packet comes in with a valid Identifier that matches the Identifier sent with the last CCP Reset-Request packet ๐Ÿ’œ it's the receiver's job to make sure the Reset-Request/Ack mechanism is reliable ๐Ÿซถ that might mean sending extra CCP Reset-Request packets before a CCP Reset-Ack packet shows up โœจ

3.3. History Maintenance

the History Count field decides how many history buffers get maintained for the compression protocol ๐ŸŽ€ for example, each history buffer could be its own separate logical connection between the data compression peers ๐Ÿฆ‹ when keeping a history, the peers MUST use link error detection and signaling so that the compressor and decompressor copies of each history buffer are always identical ๐Ÿ”’

setting the History Count field to "0" means the compression is on a connectionless basis ๐Ÿงƒ in that case, a single history buffer gets used, and it MUST be cleared at the beginning of every datagram ๐Ÿงผ

when the History Count field is "1", each data compression peer maintains a single history buffer ๐Ÿ’–

(a single logical connection. cute and simple ๐ŸŒท)

when the History Count field is greater than "1", the decompressing entity keeps separate history buffers, error detection states, and signaling states for each history ๐ŸŒŸ the compressing peer can transmit data on any number of separate histories, up to the value of the History Count field ๐Ÿ’…

3.4. History Resynchronization Mechanism

the Stac LZS protocol uses the CCP Reset-Request/Reset-Ack mechanism to signal a receiver failure in one direction of a compressed link without messing with traffic in the other direction ๐Ÿฆ‹ a receive failure gets detected using the LCB, CRC, or sequence number mechanisms, depending on the value of the check mode field ๐Ÿ”

Reset-Requests and Reset-Acks are specific to the history number of the packet they're in ๐ŸŽ€

Reset-Request/Reset-Ack history synchronization signaling exists to recover from a loss of synchronization between peers, especially over unreliable transport layers ๐Ÿ› ๏ธ as with all compression algorithms, the decompressor can't recover from dropped, erroneous, or mis-ordered datagrams, and it'll spread errors catastrophically until both peers are reset to an initial state ๐Ÿ˜ฑ

the Stac LZS protocol has ways to detect these error conditions: LCB or CRC for erroneous datagrams, and sequence number for dropped or mis-ordered datagrams ๐Ÿ•ต๏ธโ€โ™€๏ธ and there's a way to fix a loss of synchronization: clear both the failing compression and decompression histories, then follow the transmitter and receiver processes in sections 3.1. and 3.2. ๐Ÿงนโœจ


4. Configuration Option Format ๐ŸŽ€

Description

the CCP Stac LZS Configuration Option is how you negotiate using Stac LZS on the link ๐ŸŒธ by ultimate disagreement, no compression is used ๐Ÿ™ƒ

all implementations must support the default values ๐Ÿ’œ

here's a summary of the Stac LZS Configuration Option format. the fields go left to right ๐Ÿ‘€

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Type      |    Length     |        History Count          |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |   Check Mode  |
   +-+-+-+-+-+-+-+-+

Type

the Type is 17 ๐Ÿฆ‹

Length

the Length is 5 โœจ

History Count

the History Count field is two octets, most significant octet first, and it specifies the maximum number of Compression Histories ๐Ÿง

the value 0 means the implementation expects the peer to clear the Compression History at the beginning of every packet ๐Ÿงผ

the value 1 is the default, and it means only one history is maintained ๐ŸŒท

other valid values range from 2 to 65535 ๐Ÿ’– the peer isn't required to send as many histories as the implementation says it can accept ๐Ÿค but ngl, resources get allocated in each peer to support the number of negotiated histories in this field, so keep that in mind ๐Ÿ’…

Check Mode

the Check Mode field indicates support for LCB, CRC, or Sequence checking, plus other future extensions to this standard ๐ŸŽ€ it's made of 2 sub-fields and it's bit-mapped ๐Ÿ—บ๏ธ the 3 least significant bits hold 5 mutually exclusive values ๐Ÿ”ข the upper 5 bits are all "Reserved" bit locations, and they must be set to "0" so future backward-compatible extensions can fit ๐ŸŒˆ

for compatibility, Sequence Numbers MUST be implemented ๐Ÿซถ the other four check modes MAY be implemented ๐Ÿฆ‹

defined values:

  • 0 None (MAY be implemented; however, MUST implement history count of zero)
  • 1 LCB (MAY be implemented)
  • 2 CRC (MAY be implemented)
  • 3 Sequence Number (MUST be implemented)
  • 4 Extended Mode (MAY be implemented)

the bit layout is below ๐Ÿ‘‡

          0       1        2        3     4     5     6     7
      +-------+-------+----------+-----+-----+-----+-----+-----+
      |    LCB/CRC/Seq#/Ext'd    | Res | Res | Res | Res | Res |
      +-------+-------+----------+-----+-----+-----+-----+-----+

5. Definition of Extended Mode ๐Ÿงš

when Check Mode 4 (Extended Mode) is successfully negotiated, the packet format is different from the format described above ๐Ÿ˜ณ the Extended Mode format is described below ๐Ÿซ  and extended mode only supports a history count of 1 ๐Ÿ‘‘

5.1. Extended Mode Packet Format ๐ŸŽ€

Okay bestie, here's the extended mode packet layout ๐Ÿ’… The diagram is copied exactly so nothing gets lost:

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         PPP Protocol          |A|B|C|D| Coherency Count       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |        Compressed Data...
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

PPP Protocol ๐Ÿงš

The PPP Protocol field is described in the Point-to-Point Protocol Encapsulation [1].

When a compression protocol is successfully negotiated by the PPP Compression Control Protocol [2], the value is hex 00FD. Protocol-Field-Compression MUST NOT be used on this value when extended mode is negotiated on the link, even if Protocol-Field-Compression was successfully negotiated before data compression. ๐Ÿ™…โ€โ™€๏ธ

Bit A - PACKET_FLUSHED ๐ŸŒธ

This bit indicates that the history buffer has just been reset before this packet was generated. Thus, this packet can ALWAYS be decompressed because it is not based on any previous history. โœจ This bit is typically sent to inform the peer that it has reset its history buffer and that the peer can accept this packet and re-synchronize. ๐Ÿซถ

Bit B ๐Ÿฆ‹

This bit is not used with Stac LZS compression.

Bit C - PACKET_COMPRESSED ๐Ÿ’œ

This bit is used to indicate that the packet is compressed. A value of 0 indicates uncompressed data, and a value of 1 indicates compressed data.

Bit D ๐Ÿ“

This bit is not used with Stac LZS compression.

Coherency Count ๐Ÿ”ข

The coherency count is used to assure that the packets are sent in proper order and that no packet has been dropped. This count is initialized to the value 0x000, and is always increased by 1 after each PPP packet is sent. When all bits are 1, the count returns to 0.

The coherency count is 12 bits so the decompressor must handle the rollover case. ๐Ÿ”„

Compressed Data ๐Ÿ“ฆ

The compressed data begins with the protocol field. For example, an IP packet may contain 0021 followed by an IP header. The compressor will first try to compress the 0021 protocol field and then move on to the IP header.

Protocol-Field-Compression MUST NOT be used on this value when extended mode is negotiated on the link, even if Protocol-Field-Compression was successfully negotiated before data compression.

Zero deletion/insertion described in section 2.2 MUST NOT be performed when extended mode is negotiated. ๐Ÿ™…โ€โ™€๏ธ๐Ÿ’…


5.2. Extended Mode Transmitter Process โœจ

When a network datagram is received, it is processed according to ANSI X3.241-1994 to form compressed data. If a CCP Reset-Request has been received from the decompressor, the compressor must clear its history buffer before sending the next packet. ๐Ÿงน

Uncompressed data MUST be sent if the compression operation causes the compressed datagram to expand. In this case, since the compressor has modified the history buffer before sending an uncompressed datagram, the history buffer MUST be cleared before the next datagram is processed. ๐Ÿ˜ฌ The uncompressed data is placed in the information field of the datagram, and Bit-A MUST be set (indicating the history was cleared) and Bit-C MUST be clear (indicating uncompressed data) in the current packet's header. The value of the coherency counter is placed in the coherency count field and then the coherency counter is incremented.

If the compression operation does not cause the compressed datagram to expand and if a received Reset-Request is outstanding, then the output of the compression operation is placed in the information field of the datagram, and Bit-A MUST be set (indicating the history was cleared) and Bit-C MUST be set (indicating compressed data) in the current packet's header. The value of the coherency counter is placed in the coherency count field and then the coherency counter is incremented. ๐ŸŽฏ

If the compression operation does not cause the compressed datagram to expand and there is not a Reset-Request outstanding, then the output of the compression operation is placed in the information field of the datagram, and Bit-A MUST be clear (indicating the history was not cleared) and Bit-C MUST be set (indicating compressed data) in the current packet's header. The value of the coherency counter is placed in the coherency count field and then the coherency counter is incremented. ๐Ÿ’–

Upon reception of a CCP Reset-Request packet, the transmitting compressor MUST be cleared to an initial state, which includes clearing the history buffer. In addition to the reset of the compressor, the PACKET_FLUSHED bit MUST be set in the header of the next transmitted data packet. ๐Ÿ”ฅ


5.3. Extended Mode Receiver Process ๐Ÿฆ‹

When a data compression datagram is received from the peer, Bit-A and Bit-C MUST be checked. Prior to the decompression operation, if Bit-A is set, then the coherency count MUST be resynchronized to the received value in the coherency count field of the received packet, and the receiving decompressor's corresponding history MAY be reset to an initial state. (However, due to the characteristics of the Stac LZS algorithm, a decompressor history reset is not required). After reset, any compressed or uncompressed data contained in the packet is processed, depending on the state of Bit-C. ๐Ÿง 

Prior to the decompression operation, if Bit-C is clear (indicating uncompressed data), then the decompression history buffer must not be modified and the decompressor is not involved with deencapsulation. If Bit-C is set (indicating compressed data) then the received packet is decompressed according to ANSI X3.241-1994. ๐Ÿ“ฌ

If the received packet is corrupt, then a Reset-Request is sent and this packet is discarded. If the received packet contains an incorrect coherency count, a Reset-Request is sent and this packet is discarded. ๐Ÿ—‘๏ธ Bestie, that's the safety net. ๐Ÿฅบ


5.4. Extended Mode Synchronization ๐Ÿซถ

Packets may be lost during transfer. If the decompressor maintained coherency count does not match the coherency count received in the compressed packet or if the decompressor detects that a received packet is corrupted, the decompressor drops the packet and sends a CCP Reset-Request packet. The compressor on receiving this packet resets the history buffer and sets the PACKET_FLUSHED bit in the next frame it sends. The decompressor on receiving a packet with its PACKET_FLUSHED bit set, resets its history buffer and sets its coherency count to the one shipped by the compressor in that packet. ๐Ÿ”

Thus synchronization is achieved without a Reset-Ack packet. ๐ŸŽ‰๐Ÿ‘‘


Security Considerations ๐Ÿ”

Security issues are not discussed in this memo. ๐Ÿšจ Bestie, take that seriously and don't assume this document covers security for you. ๐Ÿ™ˆ

References ๐Ÿ“š

  • [1] Simpson, W., Editor, "The Point-to-Point Protocol (PPP)", STD 51, RFC 1661, Daydreamer, July 1994.
  • [2] Rand, D., "The PPP Compression Control Protocol (CCP)", RFC 1962, July 1996.
  • [3] Lempel, A. and Ziv, J., "A Universal Algorithm for Sequential Data Compression", IEEE Transactions On Information Theory, Vol. IT-23, No. 3, May 1977.
  • [4] Rand, D., "PPP Reliable Transmission", RFC 1663, Novell, July 1994.

Chair's Address ๐ŸŒธ

The working group can be contacted via the current chair:

Karl F. Fox
Ascend Communications
3518 Riverside Dr., Suite 101
Columbus, Ohio  43221

(614) 451-1883

EMail: karl@ascend.Com

Authors' Addresses ๐Ÿ’–

Questions about this memo can also be directed to:

Robert Friend
Stac Technology
12636 High Bluff Drive
San Diego, CA  92130
(619) 794-4542
EMail: rfriend@stac.com


William Allen Simpson
Daydreamer
Computer Systems Consulting Services
1384 Fontaine
Madison Heights, Michigan  48071
Bill.Simpson@um.cc.umich.edu
    bsimpson@MorningStar.com (preferred)
๐Ÿ“ฆ where this page comes from