RFC 6256

Using Self-Delimiting Numeric Values in Protocols

πŸ“… published May 2011, from ietf

RFC 6256: Using Self-Delimiting Numeric Values in Protocols πŸ’–

  • Stream: Internet Research Task Force (IRTF) πŸŽ€
  • Authors: W. Eddy (MTI Systems) and E. Davies (Folly Consulting) ✨
  • Category: Informational πŸ“š
  • ISSN: 2070-1721
  • Date: May 2011 🌸
  • Obsoletes / Updates: the header doesn't list any RFCs it obsoletes or updates πŸ¦‹

Abstract πŸ”₯

okay so Self-Delimiting Numeric Values (SDNVs) were recently introduced as a field type in proposed Delay-Tolerant Networking protocols 🧚. SDNVs encode an arbitrary-length non-negative integer or an arbitrary-length bitstring with minimum overhead πŸ’…. The whole vibe is protocol flexibility without giving up economy, plus helping protocols stay future-proof while they're still being built 🫢. This document covers the formats and algorithms for SDNV encoding and decoding, along with notes on implementation and usage πŸ’œ. It's a product of the Delay-Tolerant Networking Research Group, and that group reviewed it. No objections to publishing it as an RFC were raised ✨.

Status of This Memo 🌈

This one is not an Internet Standards Track specification. It's published for informational purposes πŸ“š.

It's a product of the Internet Research Task Force (IRTF), which publishes the results of Internet-related research and development activities πŸ”¬. These results might not be suitable for deployment ⚠️. This RFC represents the consensus of the Delay-Tolerant Networking Research Group of the IRTF 🫢. Documents approved for publication by the IRSG are not a candidate for any level of Internet Standard. See Section 2 of RFC 5741 for details πŸ’€.

For the current status of this document, any errata, and how to give feedback on it, check http://www.rfc-editor.org/info/rfc6256 πŸŽ€.

Copyright (c) 2011 IETF Trust and the persons identified as the document authors. All rights reserved 🌸.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents, which you can find at http://trustee.ietf.org/license-info, as they were in effect on the date this document was published. Please actually read these documents carefully, because they spell out your rights and restrictions with respect to this document πŸ™ˆ.

Table of Contents πŸ“

   1. Introduction ....................................................2
      1.1. Problems with Fixed-Value Fields ...........................3
      1.2. SDNVs for DTN Protocols ....................................4
      1.3. SDNV Usage .................................................5
   2. Definition of SDNVs .............................................6
   3. Basic Algorithms ................................................8
      3.1. Encoding Algorithm .........................................8
      3.2. Decoding Algorithm .........................................9
      3.3. Limitations of Implementations ............................10
   4. Comparison to Alternatives .....................................10
   5. Security Considerations ........................................13
   6. Acknowledgements ...............................................13
   7. Informative References .........................................14
   Appendix A. SDNV Python Source Code ...............................15

1. Introduction ✨

okay this section is the intro and it's giving background πŸ“–. This document is a product of the Internet Research Task Force (IRTF) Delay-Tolerant Networking (DTN) Research Group (DTNRG) 🧚. It got review and support inside the DTNRG, which you can read about in the Acknowledgements section 🫢.

So the doc starts by explaining why fixed-width protocol fields are a headache 😭. Then it gives some backstory on the SDNVs that were proposed for DTN protocols, and it explains why they could be useful in other networking protocols too πŸ¦‹. The DTNRG made SDNVs to solve the challenges it was dealing with, and people have pointed out that SDNVs look a lot like certain things in ASN.1 and even older ITU protocols. So these problems aren't new, and they aren't unique to DTN πŸ’…. SDNVs focus strictly on numeric values or bitstrings. Other mechanisms exist for encoding more complex data structures, like ASN.1 encoding rules and Haverty's Message Services Data Transmission Protocol (MSDTP) [RFC0713]. Because SDNVs stay so focused, they can be implemented quickly with only a small amount of code πŸ“.

SDNVs are tersely defined in both the Bundle Protocol [RFC5050] and the Licklider Transmission Protocol (LTP) [RFC5326] specifications. That's because of the order documents got produced in the DTNRG πŸ™ˆ. This document is here to clarify and explain the motivations and engineering decisions behind SDNVs πŸ’œ.

1.1. Problems with Fixed-Value Fields πŸ”₯

Protocol designers are always stuck on the same optimization problem: how big should the header fields be? 😩 There's a strong desire to keep fields as small as possible, to cut down on the protocol's overhead and to allow for fast processing. But protocols get used for years (even decades) after they're designed, and networking tech changes fast. So it's not unusual for a protocol's use, deployment, or performance to get limited or infringed upon because some header field is too short πŸ’€. Two well-known examples of this are the TCP-advertised receive window and the IPv4 address length πŸ‘‘.

TCP segments carry an advertised receive window field that's fixed at 16 bits [RFC0793], which encodes a maximum value of around 65 kilobytes πŸŽ€. Its job is flow control: it lets a receiver say how many sent bytes its peer can have outstanding (unacknowledged) at any time, so the receiver can limit its buffer size 🧁. Network speeds have grown by several orders of magnitude since TCP was created, and the mix of that 65 kilobyte maximum window with long round-trip times kept TCP senders from reaching the high throughput the underlying network could handle 😭. The fix was the Window Scale option [RFC1323], which provides a multiplier for the advertised window field 🌈. But the Window Scale multiplier stays fixed for the whole connection, it needs support from each end of the TCP connection, and it limits how precise the advertised receive window can be. So yeah, it's certainly a less-than-ideal solution πŸ™ƒ. Because of the field width limit in the original design, though, Window Scale is necessary for TCP to reach high sending rates πŸ’….

An IPv4 address is fixed at 32 bits [RFC0791]. (Fun historical note: an early version of the IP header format spec in [IEN21] used variable-length addresses in multiples of 8 bits, up to 120 bits 🧚.) Because of how subnetting and address block assignment worked, the number of IPv4 addresses has been seen as a limit on Internet growth [Hain05] 😬. Two different paths have been tried to solve this. One is Network Address Translators (NATs), and the other is the development of IPv6 πŸ¦‹. NATs have caused a bunch of other issues and problems [RFC2993], which led to more complexity and fragility, and also forced workarounds to be engineered for many other protocols to work inside a NATed environment πŸ™ˆ. The IPv6 transition work has been underway for several years, but it has only just started to have a visible impact on the global Internet 🌍.

Of course, for both the TCP receive window and the IPv4 address length, the field size the designers picked seemed like a good idea at the time πŸ₯Ή. The fields were more than big enough for the originally expected usage of the protocols, and they were small enough to keep headers compact and relatively easy and efficient to parse on the machines of the time πŸ–₯️. The fixed sizes were a trade-off between the protocol's scalability and the overhead and efficiency of processing. In both cases, those engineering decisions turned out to be painfully restrictive in the longer term πŸ’€.

1.2. SDNVs for DTN Protocols πŸš€

In the specs for the DTN Bundle Protocol (BP) [RFC5050] and the Licklider Transmission Protocol (LTP) [RFC5326], SDNVs get used for several fields, including identifiers, payload/header lengths, and serial (sequence) numbers 🧚. SDNVs were built for these kinds of fields so they avoid sending more bytes than needed, and so they avoid fixed sizes that might not end up being appropriate 🫢.

For example, LTP is meant mainly for long-delay interplanetary communications [RFC5325], where links may have pretty low capacity. So it's desirable to avoid the header overhead of routinely sending a 64-bit field when a 16-bit field would do 😀. Many of the nodes implementing LTP are expected to be beyond the current range of human spaceflight πŸš€. Upgrading their on-board LTP implementations to use longer values, if the defined fields turn out to be too short, would also be a problem 😬.

Also, extensions similar in mechanism to TCP's Window Scale option are unsuitable for DTN protocols. Because of high delays, DTN protocols must avoid handshaking and configuration parameter negotiation as much as possible πŸ™…β€β™€οΈ. All of these reasons make SDNVs an attractive choice for DTN protocols πŸ’–βœ¨.

1.3. SDNV Usage ✨

okay so, in short, an SDNV is just a way of representing non-negative integers (both positive integers of arbitrary size and 0) without wasting a bunch of space πŸ’… This means SDNVs can represent a lot of common protocol header fields, like:

  • Random identification fields, like the ones used in the IPsec Security Parameters Index or in IP headers for fragment reassembly (Note: the 16-bit IP ID field for fragment reassembly was recently found to be too short in some environments [RFC4963]). 😭
  • Sequence numbers, as in TCP or the Stream Control Transmission Protocol (SCTP). πŸŽ€
  • Values used in cryptographic algorithms, such as RSA keys, Diffie-Hellman key agreement, or coordinates of points on elliptic curves. πŸ”
  • Message lengths, as used in file transfer protocols. πŸ“¦
  • Nonces and cookies. πŸͺ

As any bitfield can be read as an unsigned integer, SDNVs can also encode arbitrary-length bitfields, including bitfields that represent signed integers or other data types πŸ¦‹ However, this document assumes SDNV encoding and decoding in terms of unsigned integers. Implementations may differ in the interface they provide to SDNV encoding and decoding functions, in terms of whether the values are numeric, bitfields, etc. This detail does not change the representation or the algorithms described in this document. 🫢

The nice part is that using SDNVs instead of fixed-length fields lets protocol designers ameliorate the consequences of making difficult-to-reverse field-sizing decisions πŸ‘‘ The SDNV format grows and shrinks depending on the particular value that's encoded. SDNVs don't necessarily give you optimal encodings for values of any particular length, but they help designers avoid potential blunders in assigning fixed lengths, and they remove the complexity of either negotiating field lengths or constructing protocol extensions. Still, if SDNVs are used to encode bitfields, it is essential that the sender and receiver have a consistent interpretation of the decoded value. This is discussed further in Section 2.

To our knowledge, at this time, no IETF transport or network-layer protocol designed for use outside of the DTN domain has proposed to use SDNVs. There is, however, no inherent reason not to use SDNVs more broadly in the future 🌈 The two examples cited here, of fields that have proven too small in general Internet protocols, are only a small sampling of the much larger set of similar instances the authors can think of. Outside the Internet protocols, within ASN.1 and previous ITU protocols, constructs very similar to SDNVs have been used for many years, due to engineering concerns very similar to those facing the DTNRG. ⭐

Many protocols use a Type-Length-Value method for encoding variable-length fields (for example, TCP's options format, or many of the fields in the Internet Key Exchange Protocol version 2 (IKEv2)) 🧚 An SDNV is equivalent to combining the length and value portions of this type of field, with the overhead of the length portion amortized over the bytes of the value. The penalty paid for this in an SDNV may be several extra bytes for long values (for example, 1024-bit RSA keys). See Section 4 for further discussion and a comparison.

As is shown in later sections, for large values the current SDNV scheme is fairly inefficient in terms of space (1/8 of the bits are overhead) and not particularly easy to encode or decode compared to alternatives πŸ’€ The best use of SDNVs may often be to define the Length field of a TLV structure as an SDNV whose value is the length of the TLV's Value field. That way, you avoid forcing large numbers to be directly encoded as an SDNV, and you still keep the extensibility that SDNVs give you. Main character energy πŸ‘‘


2. Definition of SDNVs 🌸

Early in the work of the DTNRG, it was agreed that the properties of an SDNV were useful for DTN protocols 🫢 The exact SDNV format the DTNRG used evolved somewhat over time before the publication of the initial RFCs on LTP and BP. An earlier version (see the initial version of the LTP Internet Draft [BRF04]) bore a resemblance to the ASN.1 [ASN1] Basic Encoding Rules (BER) [X.690] for lengths (Section 8.1.3 of X.690). The current SDNV format is the one used by ASN.1 BER for encoding tag identifiers greater than or equal to 31 (Section 8.1.2.4.2 of X.690). A comparison between the current SDNV format and the early SDNV format is made in Section 4.

The format currently used is very simple 🧠 Before encoding, an integer is represented as a left-to-right bitstring, beginning with its most significant bit and ending with its least significant bit. If the bitstring's length is not a multiple of 7, the string is left-padded with zeros. When transmitted, the bits are encoded into a series of bytes. The low-order 7 bits of each byte in the encoded format are taken left-to-right from the integer's bitstring representation. The most significant bit of each byte specifies whether it is the final byte of the encoded value (when it holds a 0), or not (when it holds a 1).

For example:

  • 1 (decimal) is represented by the bitstring "0000001" and encoded as the single byte 0x01 (in hexadecimal).
  • 128 is represented by the bitstring "10000001 00000000" and encoded as the bytes 0x81 followed by 0x00.
  • Other values can be found in the test vectors of the source code in Appendix A. πŸ“

To be perfectly clear, and to avoid potential interoperability issues (as have occurred with ASN.1 BER time values), we explicitly state two considerations regarding zero-padding. πŸ™ˆ

(1) When encoding SDNVs, any leading (most significant) zero bits in the input number might be discarded by the SDNV encoder. Protocols that use SDNVs should not rely on leading zeros being retained after encoding and decoding operations. (2) When decoding SDNVs, the relevant number of leading zeros required to pad up to a machine word or other natural data unit might be added. These are put in the most significant positions in order to not change the value of the number. Protocols using SDNVs should consider situations where lost zero-padding may be problematic. ⚠️

The issues of zero-padding are especially relevant where an SDNV is being used to represent a bitfield to be transmitted by a protocol πŸŽ€ The specification of the protocol, and any associated IANA registry, should specify the allocation and usage of bit positions within the unencoded field. Unassigned and reserved bits in the unencoded field will be treated as zeros by the SDNV encoding prior to transmission. Assuming the bit positions are numbered starting from 0 at the least significant bit position in the integer representation, then if higher-numbered positions in the field contain all zeros, the encoding process may not transmit these bits explicitly. For example, if all the bit positions numbered 7 or higher are zeros, the transmitted SDNV can consist of just one octet. On reception, the decoding process will treat any untransmitted higher-numbered bits as zeros. To ensure correct operation of the protocol, the sender and receiver must have a consistent interpretation of the width of the bitfield. This can be achieved in various ways:

  • the bitfield width is implicitly defined by the version of the protocol in use in the sender and receiver,
  • sending the width of the bitfield explicitly in a separate item,
  • the higher-numbered bits can be safely ignored by the receiver (for example, because they represent optimizations), or
  • marking the highest-numbered bit by prepending a '1' bit to the bitfield.

The protocol specification must record how the consistent interpretation is achieved πŸ“

The SDNV encoding technique is also known as Variable Byte Encoding (see Section 5.3.1 of [Manning09]) and is equivalent to Base-128 Elias Gamma Encoding (see Section 5.3.2 of [Manning09] and Section 3.5 of [Sayood02]). However, the primary motivation for SDNVs is to provide an extensible protocol framework rather than optimal data compression, which is the motivation behind the other uses of the technique. [Manning09] points out that the key feature of this encoding is that it is "prefix free", meaning that no code is a prefix of any other, which is an alternative way of expressing the self-delimiting property. πŸ¦‹


3. Basic Algorithms πŸ’–

This section describes some simple algorithms for creating and parsing SDNV fields. They may not be the most efficient algorithms possible, but they are easy to read, understand, and implement 🧁 Appendix A contains Python source code implementing the routines described here. The algorithms presented here are convenient for converting between an internal data block and the serialized data stream associated with a transmission device. Other approaches are possible, with different efficiencies and trade-offs.

3.1. Encoding Algorithm ✨

There is a very simple algorithm for the encoding operation that converts a non-negative integer (value n, of length 1+floor(log n) bits) into an SDNV. This algorithm takes n as its only argument and returns a string of bytes:

  • (Initial Step) Set a variable X to a byte sharing the least significant 7 bits of n, and with 0 in the most significant bit, and a variable Y to n, right-shifted by 7 bits.
  • (Recursion Step) If Y == 0, return X. Otherwise, set Z to the bitwise-or of 0x80 with the 7 least significant bits of Y, and append Z to X. Right-shift Y by 7 bits and repeat the Recursion Step.

This encoding algorithm has a time complexity of O(log n), since it takes a number of steps equal to ceil(n/7), and no additional space beyond the size of the result (8/7 log n) is required. One aspect of this algorithm is that it assumes strings can be efficiently appended to new bytes. One way to implement this is to allocate a buffer for the expected length of the result and fill that buffer one byte at a time from the right end. 🧩

If, for some reason, an implementation requires an encoded SDNV to be some specific length (possibly related to a machine word), any leftmost zero-padding included needs to properly set the high-order bit in each byte of padding. 🫧

3.2. Decoding Algorithm πŸŽ€

okay so decoding SDNVs is way trickier than encoding them, bestie 😭 the problem is that you don't know how big the result is gonna be until you've parsed the whole thing, and by then the value is already known. so if you pre-allocate space for the result, it's not clear whether that space will be big enough until you're 7 bits away from overflowing πŸ’€ but!! section 3.3 says protocols using SDNVs must specify the largest number of bits an implementation is expected to handle, and that mitigates the problem. slay πŸ’…

Here's the decoding routine:

  • (Initial Step) Set the result to 0. Set an index to the first byte of the encoded SDNV.
  • (Recursion Step) Shift the result left 7 bits. Add the low-order 7 bits of the value at the index to the result. If the high-order bit under the pointer is a 1, advance the index by one byte within the encoded SDNV and repeat the Recursion Step, otherwise return the current value of the result.

This decoding algorithm takes no more additional space than what is required for the result (7/8 the length of the SDNV) and the pointer. the complication is that before the result can be left-shifted in the Recursion Step, an implementation needs to first make sure that this won't cause any bits to be lost, and re-allocate a larger piece of memory for the result if required 🫠 the pure time complexity is the same as for the encoding algorithm, but if re-allocation is needed because the size of the result can't be predicted, decoding may be slower.

these decoding steps include removal of any leftmost zero-padding that might be used by an encoder to create encodings of a certain length 🧹

3.3. Limitations of Implementations 🚧

because of efficiency considerations or convenience of internal representation of decoded integers, implementations may choose to limit the number of bits in SDNVs that they will handle. to avoid interoperability problems, any protocol that uses SDNVs must specify the largest number of bits in an SDNV that an implementation of that protocol is expected to handle.

for example, Section 4.1 of [RFC5050] specifies that implementations of the DTN Bundle Protocol are not required to handle SDNVs with more than 64 bits in their unencoded value. so integer values transmitted in SDNVs have an upper limit, and SDNV-encoded flag fields must be limited to 64 bit positions in any future revisions of the protocol unless the restriction is altered πŸ”’βœ¨

4. Comparison to Alternatives πŸ”

this section compares three alternative ways of doing the concept of SDNVs: (1) the TLV scheme commonly used in the Internet family and many other families of protocols, (2) the old style of SDNVs (both the SDNV-8 and SDNV-16) defined in an early stage of LTP's development [BRF04], and (3) the current SDNV format πŸ‘€

the TLV method uses two fixed-length fields to hold the Type and Length elements, which then imply the syntax and semantics of the Value element. it's only similar to an SDNV in that the Value element can grow or shrink within the bounds that the Length field is able to convey. two fundamental differences between TLVs and SDNVs: through the Type element, TLVs also carry some notion of what their contents mean semantically, while SDNVs are simply generic non-negative integers. and protocol engineers still have to pick fixed-field lengths for the Type and Length fields in the TLV format πŸ™ˆ

some protocols use TLVs where the value conveyed in the Length field needs to be decoded into the actual length of the Value field. this can be done with simple multiplication, left-shifting, or a look-up table. either way, this tactic limits the granularity of the possible Value lengths, and it can add some bloat if Values don't fit neatly within the available decoded Lengths πŸ“

in the SDNV format originally used by LTP, parsing the first byte of the SDNV told an implementation how much space was needed to hold the contained value. there were two types of SDNVs for different ranges of use. the SDNV-8 type could hold values up to 127 in a single byte, while the SDNV-16 type could hold values up to 32,767 in 2 bytes. both formats could encode values requiring up to N bytes in N+2 bytes, where N<127. the big difference between this old SDNV format and the current one is that the new format isn't as easily decoded as the old one was, but the new format also has absolutely no limitation on its length 🌈

the old format's ease of parsing shows up in two ways: (1) the size of the value is determinable ahead of time, like parsing a TLV, and (2) the actual value is directly encoded and decoded, without shifting and masking bits like the new format requires. so the old format needs less computational overhead, but it's also very limited in that it can only hold a 1024-bit number, at maximum. according to IETF Best Current Practices, an asymmetric cryptography key needed to last for a long term requires moduli of over 1228 bits [RFC3766]. so this could be seen as a severe limitation of the old style of SDNVs, which the current style doesn't suffer from 😀πŸ”₯

Table 1 compares the maximum values that can be encoded into SDNVs of various lengths using the old SDNV-8/16 method and the current SDNV method. the only place in this table where SDNV-16 is used rather than SDNV-8 is the 2-byte row. starting with a single byte, the two methods are equivalent. but at 2 bytes, the old method is more compact by one bit. from 3 to 7 bytes though, the current SDNV format is more compact, since it only requires one bit per byte of overhead, whereas the old format used a full byte. so at 8 bytes, both schemes are equivalent in efficiency, since they both use 8 bits of overhead. up to 129 bytes, the old format is more compact than the current one, although after this limit it becomes unusable πŸ“Š

+-------+---------------+-------------+---------------+-------------+
| Bytes |   SDNV-8/16   |     SDNV    |   SDNV-8/16   |     SDNV    |
|       | Maximum Value |   Maximum   | Overhead Bits |   Overhead  |
|       |               |    Value    |               |     Bits    |
+-------+---------------+-------------+---------------+-------------+
|   1   |      127      |     127     |       1       |      1      |
|       |               |             |               |             |
|   2   |     32,767    |    16,383   |       1       |      2      |
|       |               |             |               |             |
|   3   |     65,535    |  2,097,151  |       8       |      3      |
|       |               |             |               |             |
|   4   |    2^24 - 1   |   2^28 - 1  |       8       |      4      |
|       |               |             |               |             |
|   5   |    2^32 - 1   |   2^35 - 1  |       8       |      5      |
|       |               |             |               |             |
|   6   |    2^40 - 1   |   2^42 - 1  |       8       |      6      |
|       |               |             |               |             |
|   7   |    2^48 - 1   |   2^49 - 1  |       8       |      7      |
|       |               |             |               |             |
|   8   |    2^56 - 1   |   2^56 - 1  |       8       |      8      |
|       |               |             |               |             |
|   9   |    2^64 - 1   |   2^63 - 1  |       8       |      9      |
|       |               |             |               |             |
|   10  |    2^72 - 1   |   2^70 - 1  |       8       |      10     |
|       |               |             |               |             |
|   16  |   2^120 - 1   |  2^112 - 1  |       8       |      16     |
|       |               |             |               |             |
|   32  |   2^248 - 1   |  2^224 - 1  |       8       |      32     |
|       |               |             |               |             |
|   64  |   2^504 - 1   |  2^448 - 1  |       8       |      64     |
|       |               |             |               |             |
|  128  |   2^1016 - 1  |  2^896 - 1  |       8       |     128     |
|       |               |             |               |             |
|  129  |   2^1024 - 1  |  2^903 - 1  |       8       |     129     |
|       |               |             |               |             |
|  130  |      N/A      |  2^910 - 1  |      N/A      |     130     |
|       |               |             |               |             |
|  256  |      N/A      |  2^1792 - 1 |      N/A      |     256     |
+-------+---------------+-------------+---------------+-------------+

                                 Table 1

suggested usages of the SDNV format that leverage its strengths and limit the effects of its weaknesses are discussed in Section 1.3 ✨

another part of the comparison between SDNVs and alternatives using fixed-length fields is what happens with transmission errors πŸ› οΈ bit errors in an SDNV can cause either errors in the decoded value, or parsing errors in subsequent fields of the protocol. with fixed-length fields, bit errors always cause errors in the decoded value rather than parsing errors in later fields. and if the decoded values from either type of field encoding (SDNV or fixed-length) are used as indexes, offsets, or lengths of further fields in the protocol, similar failures result 😬

5. Security Considerations πŸ”

the only security considerations with regard to SDNVs are that code that parses SDNVs should have bounds-checking logic and be able to handle cases where an SDNV's value is beyond the code's ability to parse. these precautions can prevent potential exploits involving SDNV decoding routines 🚨

Stephen Farrell noted that very early definitions of SDNVs also allowed negative integers. this was considered a potential security hole, since it could expose implementations to underflow attacks during SDNV decoding. there's a precedent for this, since many existing TLV decoders map the Length field to a signed integer and are vulnerable in this way. an SDNV decoder should be based on unsigned types and not have this issue πŸ’€πŸ”₯

6. Acknowledgements 🫢

Scott Burleigh, Manikantan Ramadas, Michael Demmer, Stephen Farrell, and other members of the IRTF DTN Research Group contributed to the development and usage of SDNVs in DTN protocols. George Jones and Keith Scott from Mitre, Lloyd Wood, Gerardo Izquierdo, Joel Halpern, Peter TB Brett, Kevin Fall, and Elwyn Davies also contributed useful comments on and criticisms of this document. DTNRG last call comments on the document were sent to the mailing list by Lloyd Wood, Will Ivancic, Jim Wyllie, William Edwards, Hans Kruse, Janico Greifenberg, Teemu Karkkainen, Stephen Farrell, and Scott Burleigh. further constructive comments from Dave Crocker, Lachlan Andrew, and Michael Welzl were incorporated πŸ’œ

work on this document was performed at NASA's Glenn Research Center, in support of the NASA Space Communications Architecture Working Group (SCAWG), NASA's Earth Science Technology Office (ESTO), and the FAA/Eurocontrol Future Communications Study (FCS) in the 2005-2007 time frame, while the editor was an employee of Verizon Federal Network Systems πŸš€πŸŒΈ

7. Informative References ✨

Okay bestie, here's the extra reading list πŸ“š These are the informative references, so they're your deep-dive picks 🫢

  • [ASN1] ITU-T Rec. X.680, "Abstract Syntax Notation One (ASN.1). Specification of Basic Notation", ISO/IEC 8824-1:2002, 2002.
  • [BRF04] Burleigh, S., Ramadas, M., and S. Farrell, "Licklider Transmission Protocol", Work in Progress, May 2004.
  • [Hain05] Hain, T., "A Pragmatic Report on IPv4 Address Space Consumption", Internet Protocol Journal Vol. 8, No. 3, September 2005.
  • [IEN21] Cerf, V. and J. Postel, "Specification of Internetwork Transmission Control Program: TCP Version 3", Internet Experimental Note 21, January 1978.
  • [Manning09] Manning, c., Raghavan, P., and H. Schuetze, "Introduction to Information Retrieval", Cambridge University Press ISBN-13: 978-0521865715, 2009, <http://informationretrieval.org/>.
  • [RFC0713] Haverty, J., "MSDTP-Message Services Data Transmission Protocol", RFC 713, April 1976.
  • [RFC0791] Postel, J., "Internet Protocol", STD 5, RFC 791, September 1981.
  • [RFC0793] Postel, J., "Transmission Control Protocol", STD 7, RFC 793, September 1981.
  • [RFC1323] Jacobson, V., Braden, B., and D. Borman, "TCP Extensions for High Performance", RFC 1323, May 1992.
  • [RFC2993] Hain, T., "Architectural Implications of NAT", RFC 2993, November 2000.
  • [RFC3766] Orman, H. and P. Hoffman, "Determining Strengths For Public Keys Used For Exchanging Symmetric Keys", BCP 86, RFC 3766, April 2004.
  • [RFC4963] Heffner, J., Mathis, M., and B. Chandler, "IPv4 Reassembly Errors at High Data Rates", RFC 4963, July 2007.
  • [RFC5050] Scott, K. and S. Burleigh, "Bundle Protocol Specification", RFC 5050, November 2007.
  • [RFC5325] Burleigh, S., Ramadas, M., and S. Farrell, "Licklider Transmission Protocol - Motivation", RFC 5325, September 2008.
  • [RFC5326] Ramadas, M., Burleigh, S., and S. Farrell, "Licklider Transmission Protocol - Specification", RFC 5326, September 2008.
  • [Sayood02] Sayood, K., "Lossless Data Compression", Academic Press ISBN-13: 978-0126208610, December 2002, <http://books.google.co.uk/books?id=LjQiGwyabVwC>.
  • [X.690] ITU-T Rec. X.690, "Abstract Syntax Notation One (ASN.1). Encoding Rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER)", ISO/IEC 8825-1:2002, 2002.

Appendix A. SDNV Python Source Code πŸ’…

Here's the Python code, and it's giving very practical πŸπŸ’– Everything is shown exactly as written, so copy-paste away.

#  This code may be freely copied.  Attribution would be appreciated.
#
# sdnv_decode() takes a string argument (s), which is assumed to be
#   an SDNV, and optionally a number (slen) for the maximum number of
#   bytes to parse from the string.  The function returns a pair of
#   the non-negative integer n that is the numeric value encoded in
#   the SDNV, and integer that is the distance parsed into the input
#   string.  If the slen argument is not given (or is not a non-zero
#   number) then, s is parsed up to the first byte whose high-order
#   bit is 0 -- the length of the SDNV portion of s does not have to
#   be pre-computed by calling code.  If the slen argument is given
#   as a non-zero value, then slen bytes of s are parsed.  The value
#   for n of -1 is returned for any type of parsing error.
#
# NOTE: In python, integers can be of arbitrary size.  In other
#   languages, such as C, SDNV-parsing routines should take
#   precautions to avoid overflow (e.g., by using the Gnu MP library,
#   or similar).
#
def sdnv_decode(s, slen=0):
  n = long(0)
  for i in range(0, len(s)):
    v = ord(s[i])
    n = n<<7
    n = n + (v & 0x7F)
    if v>>7 == 0:
      slen = i+1
      break
    elif i == len(s)-1 or (slen != 0 and i > slen):
      n = -1 # reached end of input without seeing end of SDNV
  return (n, slen)

# sdnv_encode() returns the SDNV-encoded string that represents n.
#   An empty string is returned if n is not a non-negative integer
def sdnv_encode(n):
  r = ""
  # validate input
  if n >= 0 and (type(n) in [type(int(1)), type(long(1))]):
    flag = 0
    done = False
    while not done:
      # encode lowest 7 bits from n
      newbits = n & 0x7F
      n = n>>7
      r = chr(newbits + flag) + r
      if flag == 0:

        flag = 0x80
      if n == 0:
        done = True
  return r


# test cases from LTP and BP internet-drafts, only print failures
def sdnv_test():
  tests = [(0xABC, chr(0x95) + chr(0x3C)),
           (0x1234, chr(0xA4) + chr (0x34)),
           (0x4234, chr(0x81) + chr(0x84) + chr(0x34)),
           (0x7F, chr(0x7F))]

  for tp in tests:
    # test encoding function
    if sdnv_encode(tp[0]) != tp[1]:
      print "sdnv_encode fails on input %s" % hex(tp[0])
    # test decoding function
    if sdnv_decode(tp[1])[0] != tp[0]:
      print "sdnv_decode fails on input %s, giving %s" % \
            (hex(tp[0]), sdnv_decode(tp[1]))

Authors' Addresses πŸŽ€

Here are the people behind the spec, bestie πŸ’œ Their contact details are copied exactly as written.

Wesley M. Eddy
MTI Systems
NASA Glenn Research Center
MS 500-ASRC; 21000 Brookpark Rd
Cleveland, OH  44135

Phone: 216-433-6682
EMail: wes@mti-systems.com
Elwyn Davies
Folly Consulting
Soham
UK

Phone:
EMail: elwynd@folly.org.uk
URI:
πŸ“¦ where this page comes from