RFC 2687
PPP in a Real-time Oriented HDLC-like Framing
RFC 2687: PPP in a Real-time Oriented HDLC-like Framing ๐
Okay bestie, here's the title block first so you know the basics ๐
- Working group: Network Working Group
- RFC number: 2687
- Title: PPP in a Real-time Oriented HDLC-like Framing
- Author: C. Bormann, Universitaet Bremen TZI
- Category: Standards Track
- Date: September 1999
- Obsoletes / updates: the header doesn't list anything it obsoletes or updates ๐ซถ
Status of this Memo โจ
Okay so this doc is a Standards Track protocol spec for the Internet community, and it's basically asking everyone to discuss it and send in suggestions ๐ For the official standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1). And distribution of this memo is unlimited, so share it with everyone ๐ธ
Copyright Notice ๐ฅ
Copyright (C) The Internet Society (1999). All Rights Reserved.
Abstract ๐ง
So there's a companion doc that describes an architecture for giving integrated services over low-bitrate links, like modem lines, ISDN B-channels, and sub-T1 links [1]. The main pieces of that architecture are a real-time encapsulation format for asynchronous and synchronous low-bitrate links, a header compression architecture that's optimized for real-time flows, elements of negotiation protocols used between routers (or between hosts and routers), and announcement protocols that applications use so this negotiation can happen ๐
This document proposes the suspend/resume-oriented solution for the real-time encapsulation format part of that architecture. The general vibe is to start from the PPP Multilink fragmentation protocol [2] and its multi-class extension [5], then add suspend/resume in a way that's as compatible with existing hard- and firmware as possible โจ
1. Introduction ๐ฆ
Okay so the Internet is famous for its "best-effort" services, right? But now there are additional types of services ("integrated services") that support real-time multimedia, and they're actually being developed and deployed on the Internet ๐
This document defines the suspend/resume-oriented solution for the real-time encapsulation format part of the architecture. The architecture document goes into more detail, but the short version is that a real-time encapsulation format is needed because, for example, a 1500 byte packet on a 28.8 kbit/s modem link makes that link unavailable for real-time traffic for about 400 ms ๐ญ That adds a worst-case delay, which means real-time apps end up with round-trip delays of at least a second, and that's honestly unacceptable for real-time conversation ๐
A true suspend/resume-oriented approach can only be implemented on a type-1 sender [1], but it gives those senders the best possible delay performance ๐ The format in this document might also be interesting for certain type-2 senders who want to use the better bit-efficiency of this format compared to [5]. And the format was designed so that both type-1 and type-2 receivers can implement it ๐ซถ
1.1. Specification Language ๐
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [8] ๐
2. Requirements ๐
The requirements for this doc are pretty similar to the ones in [5] ๐
Okay so a suspend/resume-oriented solution can give you better worst-case latency than the pre-fragmenting-oriented solution defined in [5] โจ And since this solution needs a new encapsulation scheme anyway, there's a chance to make the format a little more efficient ๐ธ
Predictability, robustness, and cooperation with PPP and existing hard- and firmware installations matter just as much with suspend/resume as they do with pre-fragmenting ๐ฅ A good suspend/resume solution gets good performance even with type-2 receivers [1], and it has to work with PPP hardware like async-to-sync converters ๐ง
Finally, a partial non-requirement: the format in this draft is based on the PPP multilink protocol ([2], also abbreviated as MP), but operating over multiple links is in many cases not required ๐ฆ
3. General Approach ๐
Same as in [5], the general approach starts from PPP multilink and adds multiple classes to get multiple levels of suspension โจ The difference is that, unlike [5], it needs more significant changes so that a packet's transmission can be suspended at any point and a higher priority packet can be injected ๐ฅ
Here's the catch: the multilink header isn't a great fit for suspend/resume implementations, because the "end" bit lives in the multilink header, which is the wrong place for suspend/resume operation ๐ To make a big packet suspendable, it has to be sent with the "end" bit off. Unless the packet was suspended a small number of bytes before its end, an empty fragment then has to be sent afterwards to "close" the packet ๐ญ So the minimum overhead for sending a suspendable packet is twice the multilink header size (six bytes, including a compressed multilink protocol field) plus one PPP framing (three bytes). Each suspension costs another six bytes (not counting the framing overhead of the intervening packet) ๐
The existing multi-link header is also pretty large, and as small high-priority packets become more frequent, that overhead becomes a big deal ๐
So the general approach of this document is to start from PPP Multilink with classes, then add a bunch of extensions to add functionality and cut down the overhead of using PPP Multilink for real-time transmission ๐ง
This document introduces two new features:
- A compact fragment format and header, and
- a real-time frame format.
4. The Compact Fragment Format ๐ฆ
This section describes an optional multilink fragment format. It's more optimized for single-link operation and frequent suspension (type 1 senders)/a small fragment size (type 2 senders), with optional support for multiple links ๐
When you're operating over a single link, the Multilink sequence number is only used for loss detection. Honestly, even a 12-bit sequence number is way bigger than this application needs on most kinds of links ๐ So we define a compact multilink header format option with a three-bit sequence number โจ
With a compact header there's little need to send packets outside the multilink, so we can add another compression mechanism for this format: the MP protocol identifier isn't sent with the compact fragment header ๐ This obviously requires prior negotiation (kind of like how address and control field compression get negotiated). It also needs a way to avoid the bit combination 0xFF (the first octet in an LCP frame before any LCP options have been negotiated), because otherwise the start of a new LCP negotiation couldn't be reliably detected ๐ญ
Figure 1: Compact Fragment Format
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| R | sequence | class | 1 |
+---+---+---+---+---+---+---+---+
| data |
: :
+---+---+---+---+---+---+---+---+
Having the least significant bit always be 1 helps HDLC chips that do special things with the least significant bits in HDLC addresses ๐ค (Initial bytes with the least significant bit set to zero are used for the extended compact fragment format, see next section.)
The R bit is the inverted version of the B bit in the other multilink fragment formats. So R = 1 means this fragment resumes a packet whose previous fragments have already been sent ๐
Now here's a clever trick to avoid a header byte of 0xFF, which would mean R=1, sequence=7, and class=7 ๐ If the class field is set to 7, the R bit MUST never be set to one. So class 7 frames by design can't be suspended/resumed ๐ โโ๏ธ (This is also why the sense of the B bit got flipped to an R bit in the compact fragment format. Without that, class 7 would be useless, because a new packet could never begin.)
Since the sequence number isn't particularly useful when the class field is set to 7, it gets used to distinguish eight more classes. It adds a little complexity, but prefix elision becomes way more applicable because there are more classes that can have different elided prefixes ๐
For purposes of prefix elision, the actual class number of a fragment is computed like this:
- If the class field is 0 to 6, the class number is 0 to 6,
- if the class field is 7 and the sequence field is 0 to 7, the class number is 7 to 14.
So the result is that classes 0 to 6 can be used for suspendable packets, and classes 7 to 14 (where the class field is 7 and the R bit must always be off) can be used for non-suspendable high-priority classes, like eight highly compressed voice streams ๐ค๐
5. The Extended Compact Fragment Format ๐ธ
For operation over multiple links, a three-bit sequence number is rarely going to be enough ๐ฉ So we define an optional extended compact fragment format. When it's negotiated, it lets both the basic compact fragment format and the extended compact fragment format be used, and each fragment says which format it's in ๐ง
Figure 1: Extended Compact Fragment Format
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| R | seq LSB | class | 0 |
+---+---+---+---+---+---+---+---+
| sequence -- MSB | 1 |
+---+---+---+---+---+---+---+---+
| data |
: :
+---+---+---+---+---+---+---+---+
In the extended compact fragment format, the sequence number is made up of three least significant bits from the first octet of the fragment header and seven most significant bits from the second octet ๐งฎ (Again, the least significant bit of the second octet is always set to one for compatibility with certain HDLC chips.)
For prefix elision purposes, fragments with a class field of 7 can use the basic format to indicate classes 7 to 14, and the extended format to indicate classes 7 to 1030 โจ Different classes can use different formats at the same time without problems. (This lets some classes be spread over a multi-link while other classes stay confined to a single link, which is more efficient.) For class fields 0 to 6, which are the suspendable classes, one of the two compact fragment formats SHOULD be used consistently within each class ๐
If the extended compact fragment format has been negotiated, receivers MAY keep 10-bit sequence numbers for all classes, so senders can switch formats within a class more easily ๐ When a sender starts sending basic format fragments in a class that was using extended format fragments, the 3-bit sequence number can be taken as a modulo-8 version of the 10-bit sequence number, so there's no discontinuity ๐ In the other direction, if the receiver has kept a 10-bit sequence number throughout (and no major slips of the sequence number have happened), no discontinuity will result. But this can't be guaranteed in the presence of errors โ ๏ธ (Discontinuity, in this context, means a receiver has to resynchronize sequence numbers by discarding fragments until a fragment with R=0 has been seen.)
6. Real-Time Frame Format โจ
okay so this section is where compact fragment headers get mapped into real-time frames ๐ the big vibe is that the HDLC-based frame shape stays the same, so existing synchronous HDLC chips and async-to-sync converters can still be used on the link ๐ ngl that's giving backwards compatibility realness. there's a note that if the design were only optimized for async operation, more design options would open up [4]. with V.80 style modems around, async is lowkey going to matter less though ๐ฅน
the compact fragment format is a compact version of the PPP multilink header with classes and a smaller sequence number space ๐ BUT it doesn't encode the E-bit from the PPP multilink header, which tells you whether a fragment is the last one of a packet. bestie that's the gap this section fills ๐ซถ
for a solution where packets can be suspended at any point, the E-bit has to be encoded near the end of each fragment ๐ฆ the real-time frame format keeps maximum compatibility with type 2 receivers, so it encodes E like this: any normal frame ending also ends the current fragment, and E is implicitly set to one. the iconic part is that packets ready for delivery to upper layers immediately trigger a receive interrupt, even at type-2 receivers ๐ฅ no waiting around, periodt.
fragments of packets that are being suspended get terminated inside the HDLC frame by a special "fragment suspend escape" byte (FSE) ๐ธ the overall HDLC frame structure doesn't change. FSE detection and handling happens in a layer above HDLC framing โจ
the suspend/resume format with FSE detection is an alternative to address/control field compression (ACFC, LCP option 8) ๐ it does not apply to frames that start with 0xFF, which is the standard PPP-in-HDLC address field. those frames get handled as defined in [6] and [7]. (this is there so attempts to renegotiate LCP don't cause ambiguities ๐)
for frames that don't start with 0xFF, suspend/resume processing scans every HDLC frame received. the FCS of the HDLC frame is checked and then stripped ๐ง compact fragment format headers (basic and extended) get handled without any further FSE processing. (and because the FSE byte was picked so it never shows up in compact fragment format headers, you don't need any special code for this ๐)
within the remaining bytes of the HDLC frame (the "data part"), an FSE byte marks the end of the current fragment, with E implicitly cleared ๐ all fragments up to the last FSE count as suspended (E = 0). the final fragment is terminated (E = 1), or, if it's empty, it's just ignored. so the data part of an HDLC frame can end in an FSE to say the last fragment has E = 0 ๐
each fragment starts with a normal header, so a frame could look like this ๐
Figure 2: Example frame with FSE delimiter
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| R | sequence | class | 1 |
+---+---+---+---+---+---+---+---+
| data |
: :
+---+---+---+---+---+---+---+---+
+ FSE + previous fragment implicitly E = 0
+---+---+---+---+---+---+---+---+
| R | sequence | class | 1 |
+---+---+---+---+---+---+---+---+
| data |
: :
+---+---+---+---+---+---+---+---+
| Frame | previous fragment implicitly E = 1
| CRC |
+---+---+---+---+---+---+---+---+
the value chosen for FSE is 0xDE ๐ฆ it's a relatively unlikely byte in today's data streams, it doesn't trigger octet stuffing, and it only triggers bit stuffing for 1/8 of the possible preceding bytes. very strategic, very intentional ๐
the remaining problem is data transparency ๐ญ in the scheme so far, an FSE is always followed by a compact fragment header. in those headers, a class field set to 7 with R=1 is reserved. data transparency comes from making an FSE byte followed by one of 0x8F, 0x9F, ... to 0xFF special ๐
Figure 3: Data transparency with FSE bytes present
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| R | sequence | class | 1 |
+---+---+---+---+---+---+---+---+
| data |
: :
+---+---+---+---+---+---+---+---+
+ FSE + fragment NOT terminated
+---+---+---+---+---+---+---+---+
| R | S | T | U | 1 | 1 | 1 | 1 | R always is 1
+---+---+---+---+---+---+---+---+
| data | fragment continues
: :
in an FSE/0xnF combo (where n is the first four-bit field in the second byte, RSTU in Figure 3), the n field is a sequence of four bits that says where FSE bytes get added by the receiver ๐ง these are FSE bytes that couldn't just be sent in the data stream. the combos are:
0x8F: insert one FSE, back to data
0x9F: insert one FSE, copy two data bytes, insert one FSE, back to data
0xAF: insert one FSE, copy one data byte, insert one FSE, back to data
0xBF: insert one FSE, copy one data byte, insert two FSE bytes, back
to data
0xCF: insert two FSE bytes, back to data
0xDF: insert two FSE bytes, copy one data byte, insert one FSE, back
to data
0xEF: insert three FSE bytes, back to data
0xFF: insert four FSE bytes, back to data
the data bytes that follow an FSE/0xnF combo, corresponding to the zero bits in the N field, may not be FSE bytes โจ
this scheme caps the worst-case expansion from FSE processing at about 25 % ๐ธ it's also designed so that one data stream can trigger either worst-case expansion from octet stuffing (or bit stuffing) or worst-case FSE processing, but never both. genius, honestly ๐ Figure 4 shows the scheme in a few examples, with FSE/0xnF pairs written in lower case ๐
Figure 4: Data transparency examples
Data stream FSE-stuffed stream
DD DE DF E0 DD de 8f DF E0
01 DE 02 DE 03 01 de af 02 03
DE DA DE DE DB de bf DA DB
DE DE DE DE DE DA de ff de 8f DA
to sum up: the real-time frame format is an HDLC-like frame, delimited by flags, with a final FCS as defined in [7], but without address and control fields. its data is a sequence of FSE-stuffed fragments in compact fragment format, delimited by FSE bytes ๐ฆ as a special case, the final FSE can be the last byte of the data content (right before the FCS bytes). that tells you the last fragment in the frame is suspended and no final fragment is in the frame, for example because the desired maximum frame size was reached ๐ซถ
7. Implementation notes โจ
7.1. MRU Issues
okay this one is about the MRU ๐ the LCP parameter MRU defines the maximum size of packets sent on the link. async-to-sync converters that monitor the LCP negotiations on the link may read the MRU value as the maximum HDLC frame size they should expect ๐ง
implementations of this specification should preferably negotiate an MRU big enough to cover the worst-case 25 % increase in frame size, plus the increase caused by suspended fragments ๐ if that isn't possible, the HDLC frame size should be limited by monitoring the HDLC frame sizes and possibly suspending the current fragment. you do that by sending an FSE with an empty final fragment (an FSE right before the end of the information field, so right before the CRC bytes and a flag). then you can continue in a new HDLC frame ๐ this strategy also helps reduce the impact of a longer HDLC frame on the safety of the 16-bit FCS at the end of the frame ๐ญ
7.2. Implementing octet-stuffing and FSE processing in one automaton
the simplest way to add real-time framing to an implementation is to do HDLC processing as usual, then run FSE processing on the result ๐ธ a more advanced implementation might want to combine the two levels of escape character processing. but note that FSE processing has to wait until two bytes from the HDLC frame are available and a third one follows, so you can be sure those bytes aren't the final HDLC FCS bytes (those aren't subject to FSE processing) ๐ so, when a normal data byte arrives, look for an FSE in the second-to-previous byte. when a frame-end arrives, look for an FSE as the last data byte ๐ฅ
8. Negotiable options ๐
the following options are already defined by MP [2]:
- Multilink Maximum Received Reconstructed Unit
- Multilink Short Sequence Number Header Format
- Endpoint Discriminator
the following options are already defined by MCML [5]:
- Multilink Header Format
- Prefix Elision
this document defines two new code points for the Multilink Header Format option ๐
8.1. Multilink header format option
the multilink header format option is defined in [5] ๐ฆ a summary of its format is shown below. the fields are transmitted from left to right.
Figure 5: Multilink header format option
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 = 27 | Length = 4 | Code | # Susp Clses |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
as defined in [5], this LCP option tells the peer that the implementation wants to receive fragments in the format given by the code number, with the maximum number of suspendable classes (see below) included ๐ this specification adds two more values for Code, on top of the ones in [5]:
- Code = 11: basic and extended compact real-time fragment format with classes, in FSE-encoded HDLC frame
- Code = 15: basic compact real-time fragment format with classes, in FSE-encoded HDLC frame
an implementation MUST NOT request a combination of both LCP Address-and-Control-Field-Compression (ACFC) and the code values 11 or 15 for this option ๐ซ bestie, that one's non-negotiable.
the number of suspendable classes negotiated for the compact real-time fragment format only limits which class numbers are allowed to suspend ๐ง class numbers 7 and higher don't need extra reassembly space, so they aren't subject to the negotiated class number limit โจ
9. Security Considerations ๐ฅ
operation of this protocol is believed to be no more and no less secure than operation of the PPP multilink protocol [2] ๐ but a small sequence number range makes it more likely that fragments from different packets get incorrectly reassembled into one packet. most of those packets will be thrown out by the receiver because of higher-layer checksum failures or other inconsistencies ๐ญ still, there's a higher chance that the contents of packets meant for one host could be delivered to another host. this is the serious part, babe: links that carry packets where this raises security considerations SHOULD use the extended sequence number range for multi-fragment packets ๐ซถ
10. References โจ
Okay bestie, here's the reading list ๐ Every source is listed with all its details, no cuts.
- [1] Bormann, C., "Providing Integrated Services over Low-bitrate Links", RFC 2689, September 1999. ๐ฆ
- [2] Sklower, K., Lloyd, B., McGregor, G., Carr, D. and T. Coradetti, "The PPP Multilink Protocol (MP)", RFC 1990, August 1996. ๐
- [3] Simpson, W., "PPP in Frame Relay", RFC 1973, June 1996. ๐ธ
- [4] Andrades, R. and F. Burg, "QOSPPP Framing Extensions to PPP", Work in Progress. ๐ง
- [5] Bormann, C., "The Multi-Class Extension to Multi-Link PPP", RFC 2686, September 1999. ๐
- [6] Simpson, W., Editor, "The Point-to-Point Protocol (PPP)", STD 51, RFC 1661, July 1994. ๐
- [7] Simpson, W., Editor, "PPP in HDLC-like Framing", STD 51, RFC 1662, July 1994. ๐
- [8] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. ๐ซถ
11. Author's Address ๐
Here's where you can find the author, Carsten Bormann ๐
Carsten Bormann
Universitaet Bremen FB3 TZI
Postfach 330440
D-28334 Bremen, GERMANY
Phone: +49.421.218-7024
Fax: +49.421.218-7000
EMail: cabo@tzi.org
Acknowledgements ๐ซถ
Big thank yous, bestie! The people at a lunch BOF during the Montreal IETF in 1996 gave really useful input on the design tradeoffs across different environments ๐ฑ Richard Andrades, Fred Burg, and Murali Aravamudan were the ones who insisted on a suspend/resume solution alongside the pre-fragmenting one defined in [5]. Honestly iconic behaviour ๐ Also, the members of the ISSLL subgroup on low bitrate links (ISSLOW) helped put together a set of requirements that shaped this whole solution โจ
Full Copyright Statement ๐
Copyright (C) The Internet Society (1999). All Rights Reserved. ๐
Here's the permission situation, and it's pretty generous ๐ฆ You're allowed to copy and share this document and translations of it, and you can make derivative works that comment on or explain it or help with implementing it. You can prepare, copy, publish, and distribute those, in whole or in part, with no restrictions, as long as the copyright notice and this paragraph are included on all copies and derivative works. โจ
Now the one catch: the document itself can't be modified in any way. You can't remove the copyright notice or the references to the Internet Society or other Internet organizations. The exceptions are when you need it to develop Internet standards, in which case the copyright procedures in the Internet Standards process must be followed, or when you're translating it into a language other than English. ๐
The permissions above are perpetual and will not be revoked by the Internet Society or its successors or assigns. Forever and ever ๐
The document and the information in it are provided on an "AS IS" basis, and the warranty disclaimer is important, so here it is in full: THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. ๐
Acknowledgement ๐ธ
Funding for the RFC Editor function is currently provided by the Internet Society. So the people keeping this whole library running are supported by them right now ๐ซถโจ
๐ฆ where this page comes from
- ietf: rfc2687 1999-09
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms