RFC 5326

Licklider Transmission Protocol - Specification

๐Ÿ“… published September 2008, from ietf

Licklider Transmission Protocol - Specification ๐ŸŽ€

okay bestie, RFC 5326 is giving Experimental energy ๐Ÿงชโœจ. It's by M. Ramadas (ISTRAC, ISRO), S. Burleigh (NASA/Jet Propulsion Laboratory), and S. Farrell (Trinity College Dublin), and it's dated September 2008. The title block doesn't list anything it obsoletes or updates, so it's a clean slate ๐Ÿ’….


Status of This Memo ๐Ÿ“œ

so this memo defines an Experimental Protocol for the Internet community ๐Ÿงช. it is NOT an Internet standard of any kind, no cap ๐Ÿ™…โ€โ™€๏ธ. they're literally asking for discussion and suggestions for improvement, and distribution of this memo is unlimited ๐Ÿ’Œ.


IESG Note ๐Ÿ™ˆ

this RFC is not a candidate for any level of Internet Standard ๐Ÿšซ. it represents the consensus of the Delay Tolerant Networking (DTN) Research Group of the Internet Research Task Force (IRTF) ๐ŸŒˆ. it may be considered for standardization by the IETF in the future, but the IETF disclaims any knowledge of the fitness of this RFC for any purpose ๐Ÿ’€. and in particular, they note that the decision to publish is not based on IETF review for things like security, congestion control, or inappropriate interaction with deployed protocols ๐Ÿ˜ญ. see RFC 3932 for more information ๐Ÿ“š.


Abstract ๐ŸŒธ

this document describes the Licklider Transmission Protocol (LTP) ๐Ÿฆ‹. it's designed to give you retransmission-based reliability over links with extremely long message round-trip times (RTTs) and/or frequent interruptions in connectivity ๐Ÿ›ฐ๏ธ. since communication across interplanetary space is the most prominent example of this kind of environment, LTP is mainly aimed at supporting "long-haul" reliable transmission in interplanetary space โœจ, but it has applications in other environments too ๐ŸŒ.

this document is a product of the Delay Tolerant Networking Research Group and has been reviewed by that group ๐Ÿซถ. no objections to its publication as an RFC were raised ๐ŸŽ‰.


Table of Contents ๐Ÿ—‚๏ธ

   1. Introduction ....................................................3
   2. Terminology .....................................................4
   3. Segment Structure ...............................................9
      3.1. Segment Header ............................................10
           3.1.1. Segment Type Flags .................................11
           3.1.2. Segment Type Codes .................................13
           3.1.3. Segment Class Masks ................................14
           3.1.4. Extensions Field ...................................14
      3.2. Segment Content ...........................................16
           3.2.1. Data Segment (DS) ..................................16
           3.2.2. Report Segment (RS) ................................17
           3.2.3. Report Acknowledgment Segment ......................19
           3.2.4. Session Management Segments ........................20
      3.3. Segment Trailer ...........................................20
   4. Requests from Client Service ...................................20
      4.1. Transmission Request ......................................21
      4.2. Cancellation Request ......................................22
   5. Requirements from the Operating Environment ....................23
   6. Internal Procedures ............................................24
      6.1. Start Transmission ........................................25
      6.2. Start Checkpoint Timer ....................................25
      6.3. Start RS Timer ............................................25
      6.4. Stop Transmission .........................................25
      6.5. Suspend Timers ............................................26
      6.6. Resume Timers .............................................26
      6.7. Retransmit Checkpoint .....................................27
      6.8. Retransmit RS .............................................27
      6.9. Signify Red-Part Reception ................................28
      6.10. Signify Green-Part Segment Arrival .......................28
      6.11. Send Reception Report ....................................28
      6.12. Signify Transmission Completion ..........................30
      6.13. Retransmit Data ..........................................30
      6.14. Stop RS Timer ............................................31
      6.15. Start Cancel Timer .......................................32
      6.16. Retransmit Cancellation Segment ..........................32
      6.17. Acknowledge Cancellation .................................32
      6.18. Stop Cancel Timer ........................................33
      6.19. Cancel Session ...........................................33
      6.20. Close Session ............................................33
      6.21. Handle Miscolored Segment ................................33
      6.22. Handling System Error Conditions .........................34
   7. Notices to Client Service ......................................35
      7.1. Session Start .............................................35
      7.2. Green-Part Segment Arrival ................................36
      7.3. Red-Part Reception ........................................36
      7.4. Transmission-Session Completion ...........................36
      7.5. Transmission-Session Cancellation .........................37
      7.6. Reception-Session Cancellation ............................37
      7.7. Initial-Transmission Completion ...........................37
   8. State Transition Diagrams ......................................38
      8.1. Sender ....................................................39
      8.2. Receiver ..................................................44
   9. Security Considerations ........................................48
      9.1. Denial of Service Considerations ..........................48
      9.2. Replay Handling ...........................................49
      9.3. Implementation Considerations .............................50
   10. IANA Considerations ...........................................51
      10.1. UDP Port Number for LTP ..................................51
      10.2. LTP Extension Tag Registry ...............................51
   11. Acknowledgments ...............................................51
   12. References ....................................................52
      12.1. Normative References .....................................52
      12.2. Informative References ...................................52

1. Introduction โœจ

this doc is the main protocol spec for LTP ๐Ÿ’…, and it's part of a series of documents describing LTP ๐Ÿ“š. the other docs in the series are the motivation document [LTPMTV] and the protocol extensions document [LTPEXT] ๐Ÿงš. we strongly recommend reading the protocol motivation document before this one, so you get enough background and motivation for the spec ๐Ÿ™ˆ๐Ÿ’œ.

LTP does Automatic Repeat reQuest (ARQ) of data transmissions by soliciting selective-acknowledgment reception reports ๐Ÿ”. it's stateful, and it has no negotiation or handshakes ๐ŸคโŒ. lowkey minimal, highkey iconic ๐Ÿ‘‘.

in an Interplanetary Internet setting that deploys the Bundle Protocol (being developed by the Delay Tolerant Networking Research Group) ๐Ÿช, LTP is meant to act as a reliable "convergence layer" protocol ๐ŸŒˆ. it operates in pairwise fashion between adjacent Interplanetary Internet nodes that are in direct radio frequency (RF) communication ๐Ÿ“ก. in that scenario, and possibly in some other Bundle Protocol deployments, LTP runs directly over a data-link layer protocol ๐Ÿ”—. when that's the case, forward error correction coding and/or checksum mechanisms in the underlying data-link layer protocol must ensure the integrity of the data passed between the communicating entities ๐Ÿ›ก๏ธ. (the data-link layer is doing the heavy lifting for integrity here, bestie ๐Ÿ’ช.)

no mechanisms for flow control or congestion control are included in the design of LTP ๐Ÿšซ. so this protocol is not intended or appropriate for ubiquitous deployment in the global Internet ๐ŸŒ. it's giving "not for the everyday internet" energy ๐Ÿ™…โ€โ™€๏ธ๐Ÿ’€.

when LTP is run over UDP, it must only be used for software development or in private local area networks ๐Ÿง‘โ€๐Ÿ’ป๐Ÿ . when LTP is not run over UDP, it must be run directly over a protocol (nominally a link-layer protocol) that meets the requirements specified in Section 5 ๐Ÿ”ฅ.

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 [B97] ๐ŸŽ€๐Ÿ’–.

2. Terminology โœจ

okay bestie, let's get into the vocab ๐Ÿ’… LTP has its own dictionary, and you need these words down before anything else makes sense ๐Ÿซถ

(1) Engine ID

A number that uniquely identifies a given LTP engine, within some closed set of communicating LTP engines. ๐Ÿ†” ngl, the engine ID is basically the name tag. When LTP is operating underneath the Delay-Tolerant Networking (DTN) [DTN] Bundle Protocol [BP], the convergence layer adapter mediating the two will be responsible for translating between DTN endpoint IDs and LTP engine IDs in an implementation-specific manner. So the adapter in the middle handles the translating, and how it does that is up to the implementation ๐ŸŒ‰

(2) Block

An array of contiguous octets of application data handed down by the upper layer protocol (typically Bundle Protocol) to be transmitted from one LTP client service instance to another. ๐Ÿ“ฆ A block is basically a chunk of app data.

Any subset of a block comprising contiguous octets beginning at the start of the block is termed a "block prefix", and any such subset of the block ending with the end of the block is termed a "block suffix". So a prefix starts at the front, a suffix ends at the back ๐Ÿฐ

(3) Red-Part

The block prefix that is to be transmitted reliably, i.e., subject to acknowledgment and retransmission. ๐Ÿ”ด The red-part is the protected bit, the one that gets acked and resent if it gets lost.

(4) Green-Part

The block suffix that is to be transmitted unreliably, i.e., not subject to acknowledgments or retransmissions. If present, the green-part of a block begins at the octet following the end of the red-part. ๐Ÿ’š The green-part is the chill bit: no acks, no resends. It starts right after the red-part ends.

(5) Session

A thread of LTP protocol activity conducted between two peer engines for the purpose of transmitting a block. Data flow in a session is unidirectional: data traffic flows from the sending peer to the receiving peer, while data-acknowledgment traffic flows from the receiving peer to the sending peer. ๐Ÿงต A session is one conversation about one block, and the data only goes one way while the acks come back the other way ๐Ÿ”

(6) Sender

The data sending peer of a session. ๐Ÿ“ค The one sending the data.

(7) Receiver

The data receiving peer of a session. ๐Ÿ“ฅ The one catching the data.

(8) Client Service Instance

A software entity, such as an application or a higher-layer protocol implementation, that is using LTP to transfer data. ๐Ÿงš Any app or higher-layer protocol that's using LTP to move its data counts.

(9) Segment

The unit of LTP data transmission activity. It is the data structure transmitted from one LTP engine to another in the course of a session. Each LTP segment is of one of the following types: data segment, report segment, report-acknowledgment segment, cancel segment, cancel-acknowledgment segment. ๐Ÿงฉ Segments are the little packages LTP engines pass to each other, and there are five flavours of them.

(10) Reception Claim

An assertion of reception of some number of contiguous octets of application data (a subset of a block) characterized by: the offset of the first received octet, and the number of contiguous octets received (beginning at the offset). ๐Ÿ™‹โ€โ™€๏ธ A reception claim is basically the receiver saying "yep, I got this stretch, starting here, this long."

(11) Scope

Scope identifies a subset of a block and comprises two numbers -- upper bound and lower bound.

For a data segment, lower bound is the offset of the segment's application data from the start of the block (in octets), while upper bound is the sum of the offset and length of the segment's application data (in octets). For example, a segment with a block offset of 1000 and length of 500 would have a lower bound of 1000 and upper bound of 1500. ๐Ÿ“

For a report segment, upper bound is the end of the block prefix to which the reception claims in the report apply, while lower bound is the end of the (smaller) interior block prefix to which the reception claims in the report do not apply. That is, data at any offset equal to or greater than the report's lower bound but less than its upper bound and not designated as "received" by any of the report's reception claims must be assumed not received, and therefore eligible for retransmission. For example, if a report segment carried a lower bound of 1000 and an upper bound of 5000, and the reception claims indicated reception of data within offsets 1000-1999 and 3000-4999, data within the block offsets 2000-2999 can be considered missing and eligible for retransmission. ๐Ÿ•ต๏ธโ€โ™€๏ธ This one's a vibe: anything inside the report's range that nobody claimed is treated as missing and gets resent.

Reception reports (which may comprise multiple report segments) also have scope, as defined in Section 6.11. ๐Ÿ”—

(12) End of Block (EOB)

The last data segment transmitted as part of the original transmission of a block. This data segment also indicates that the segment's upper bound is the total length of the block (in octets). ๐Ÿ The EOB is the final segment of the original send, and its upper bound tells you the block's total length.

(13) End of Red-Part (EORP)

The segment transmitted as part of the original transmission of a block containing the last octet of the block's red-part. This data segment also indicates that the segment's upper bound is the length of the block's red-part (in octets). ๐Ÿšฉ The EORP is the segment that closes out the red-part, and its upper bound is the red-part's length.

(14) Checkpoint

A data segment soliciting a reception report from the receiving LTP engine. The EORP segment must be flagged as a checkpoint, as must the last segment of any retransmission; these are "mandatory checkpoints". All other checkpoints are "discretionary checkpoints". ๐Ÿ›Ž๏ธ A checkpoint is a segment that asks the receiver for a report. The EORP and the last segment of any resend are the non-negotiable ones, and everything else is optional ๐Ÿ’…

(15) Reception Report

A sequence of one or more report segments reporting on all block data reception within some scope. ๐Ÿ“‹ A reception report is the whole collection of report segments covering what got received in a scope.

(16) Synchronous Reception Report

A reception report that is issued in response to a checkpoint. โฑ๏ธ Synchronous means it's the answer to a checkpoint.

(17) Asynchronous Reception Report

A reception report that is issued in response to some implementation-defined event other than the arrival of a checkpoint. ๐ŸŽฒ Asynchronous means it's triggered by something the implementation decides on, not by a checkpoint showing up.

(18) Primary Reception Report

A reception report that is issued in response to some event other than the arrival of a checkpoint segment that was itself issued in response to a reception report. Primary reception reports include all asynchronous reception reports and all synchronous reception reports that are sent in response to discretionary checkpoints or to the EORP segment for a session. ๐Ÿฅ‡ These are the first-line reports: all the asynchronous ones, plus the synchronous ones answering discretionary checkpoints or the EORP.

(19) Secondary Reception Report

A reception report that is issued in response to the arrival of a checkpoint segment that was itself issued in response to a reception report. ๐Ÿฅˆ A secondary report is the reply to a checkpoint that was itself sent because of a report. It's a report-about-a-report, so yes, it's a whole chain ๐Ÿ”—

(20) Self-Delimiting Numeric Value (SDNV)

The design of LTP attempts to reconcile minimal consumption of transmission bandwidth with

(a) extensibility to satisfy requirements not yet identified, and

(b) scalability across a very wide range of network sizes and transmission payload sizes.

The SDNV encoding scheme is modeled after the Abstract Syntax Notation One [ASN1] scheme for encoding Object Identifier values. In a data field encoded as an SDNV, the most significant bit (MSB) of each octet of the SDNV serves to indicate whether or not the octet is the last octet of the SDNV. An octet with an MSB of 1 indicates that it is either the first or a middle octet of a multi-octet SDNV; the octet with an MSB of 0 is the last octet of the SDNV. The value encoded in an SDNV is found by concatenating the 7 least significant bits of each octet of the SDNV, beginning at the first octet and ending at the last octet. ๐Ÿง  So LTP wants to use as few bits as possible, but still leave room for future stuff and work at any size. The MSB is the "keep going?" flag, and the last octet says "that's all, folks" ๐Ÿ›‘

The following examples illustrate the encoding scheme for various hexadecimal values.

0xABC  : 1010 1011 1100
         is encoded as

         {100 1010 1} {0 011 1100}
          -            -

         = 10010101 00111100
0x1234 : 0001 0010 0011 0100
         =  1 0010 0011 0100
         is encoded as

         {10 1 0010 0} {0 011 0100}
          -             -

         = 10100100 00110100
0x4234 : 0100 0010 0011 0100
         =100 0010 0011 0100
         is encoded as

         {1000000 1} {1 00 0010 0} {0 011 0100}
          -           -             -

         = 10000001 10000100 00110100
0x7F   : 0111 1111
         =111 1111
         is encoded as

         {0 111 1111}
          -

         = 01111111

Note:

Care must be taken to make sure that the value to be encoded is padded with zeroes at the most significant bit end (NOT at the least significant bit end) to make its bitwise length a multiple of 7 before encoding. โš ๏ธ Pad on the left, not the right, or the whole thing goes sideways.

While there is no theoretical limit on the size of an SDNV field, we note that the overhead of the SDNV scheme is 1:7, i.e., 1 bit of overhead for every 7 bits of actual data to be encoded. Thus, a 7-octet value (a 56-bit quantity with no leading zeroes) would be encoded in an 8-octet SDNV; an 8-octet value (a 64-bit quantity with no leading zeroes) would be encoded in a 10-octet SDNV. In general, an N-bit quantity with no leading zeroes would be encoded in a ceil(N/7) octet SDNV, where ceil is the integer ceiling function. Clearly, for fields that typically carry larger values such as RSA public keys, the SDNV overhead could become unacceptable. Hence, when adopting the SDNV scheme for other purposes related to this document, such as any protocol extensions, we RECOMMEND that if the typical data field value is expected to be larger than 8 octets, then the data field should be specified as a {LENGTH, VALUE} tuple, with the LENGTH parameter encoded as an SDNV followed by LENGTH octets housing the VALUE of the data field. ๐Ÿ“ The overhead is 1 bit for every 7 bits of data, so big stuff like RSA keys gets expensive fast, and that's why the RECOMMEND is to use a {LENGTH, VALUE} tuple for anything usually bigger than 8 octets.

We also note that SDNV is clearly not the best way to represent every numeric value. When the maximum possible value of a number is known without question, the cost of additional bits may not be justified. For example, an SDNV is a poor way to represent an integer whose value typically falls in the range 128 to 255. In general, though, we believe that the SDNV representation of various protocol data fields in LTP segments yields the smallest segment sizes without sacrificing scalability. ๐ŸŽฏ SDNV isn't a one-size-fits-all, but for most LTP fields it keeps segments tiny without giving up scalability.

3. Segment Structure ๐Ÿงฉ

okay so every LTP segment is made of three bits, bestie ๐ŸŽ€

  • (a) a header, in the format we're about to look at ๐Ÿ‘€
  • (b) zero or more octets of content ๐Ÿ’Œ
  • (c) zero or more octets of trailer, and how much trailer there is gets told to you by the Extensions field in the header ๐Ÿงพ

there are four general types of segment, depending on what's inside ๐Ÿ’…

  • Data segments flow from the sender to the receiver and carry the client service (application) data. the actual tea ๐Ÿต
  • A report segment flows from the receiver back to the sender. it carries the data reception claims, plus the upper and lower bounds of the block scope those claims are about ๐Ÿ“Š
  • A report-acknowledgment segment flows from the sender to the receiver and says "got your report!" ๐Ÿซถ it carries the serial number of the report it's acknowledging
  • Session management segments can be generated by both the sender and the receiver ๐Ÿค and there are two sub-types: cancellation and cancellation-acknowledgment. a cancellation segment kicks off session cancellation at the peer and carries a single byte reason-code saying why it's cancelling. a cancellation-acknowledgment just says "ok, received" and has no content ๐Ÿ™ˆ

here's the whole segment layout, visualised ๐Ÿฆ‹

    Bit    0     1     2     3     4     5     6     7
  ^     +-----+-----+-----+-----+-----+-----+-----+-----+
  |     |    Version number     |  Segment Type Flags   | Control
  |     +-----------------------+-----------------------+     -byte
  |     |                                               |
  |     /                 Session ID                    \
  |     \                                               /
Header  +-----------------------+-----------------------+
  |     | Header Extension Cnt. | Trailer Extension Cnt.| Extensions
  |     +-----------------------+-----------------------+
  |     |                                               |
  |     /              Header Extensions                \
  |     \                                               /
  V     +-----------------------------------------------+
        |                                               |
        |                                               |
        |                                               |
        |              Segment Content                  |
        /                                               \
        \                                               /
        |                                               |
        |                                               |
        |                                               |
  ^     +-----------------------------------------------+
  |     |                                               |
Trailer /              Trailer Extensions               \
  |     \                                               /
  V     +-----------------------------------------------+

3.1. Segment Header ๐ŸŽ€

the header is giving three things: a single-octet control byte, the session ID, and the Extensions field โœจ

the control byte has two parts:

  • Version number (4 bits): this MUST be set to the binary value 0000 for this version of the protocol ๐Ÿ”’
  • Segment type flags (4 bits): we get into these in Section 3.1.1 ๐Ÿ’ซ

the session ID is how you tell sessions apart. it uniquely identifies, among all transmissions between the sender and receiver, which session this segment belongs to ๐Ÿฆ‹ it has two parts:

  • Session originator (SDNV): the engine ID of the sender ๐Ÿ“ฎ
  • Session number (SDNV): usually a random number (for anti-DoS reasons ๐Ÿ›ก๏ธ), generated by the sender

how the session number is formatted and how fine-grained it is? totally private to the LTP sender, not LTP's problem ๐Ÿ’… the only requirement LTP puts on it is that every session started by an LTP engine MUST be uniquely identified by the session ID ๐Ÿ”‘

the Extensions field gets its own section, 3.1.4 ๐Ÿ‘€

3.1.1. Segment Type Flags ๐Ÿšฉ

the last 4 bits of the control byte are flags that tell you what kind of segment you're looking at. in order (most significant bit first) they're CTRL, EXC, Flag 1, and Flag 0 ๐ŸŒˆ

  • CTRL (Control): 0 means it's a data segment, 1 means it's a control segment ๐ŸŽ›๏ธ
  • EXC (Exception): for a data segment, EXC 0 makes it a red-part segment and EXC 1 makes it a green-part segment ๐ŸŸฅ๐ŸŸฉ
  • for a control segment, EXC 1 means the segment is about session cancellation activity ๐Ÿšซ
  • any data segment (red or green) with both Flag 1 and Flag 0 set to 1 means EOB (end of block) ๐Ÿ
  • any data segment (red or green) with both flags set to 0 is just data, no extra protocol drama ๐Ÿซง
  • any red-part data segment with either flag bit non-zero is a checkpoint โญ
  • any red-part data segment with Flag 1 set to 1 marks the end of red-part ๐ŸŽ€

here's the same thing in "put another way" pseudo-code, because I love a flowchart ๐Ÿง 

if (CTRL flag = 0)
   segment is a data segment if (EXC flag = 0)
      segment contains only red-part data if (Flag 1 = 1)
         segment is a checkpoint segment is the last segment in the
         red part of the block if (Flag 0 = 1)
            segment is the last segment in the block
      else // segment is not end of red-part
         if (Flag 0 = 1)
            segment is a checkpoint
   else
      segment contains only green-part data if (Flag 1 = 1)
         if (Flag 0 = 1)
            segment is the last segment in the block
else
   segment is a control segment if (EXC flag = 0)
      segment pertains to report activity if (flag 0 = 0)
         segment is a report segment
      else
         segment is an acknowledgment of a report segment
   else
      segment pertains to session cancellation activity if (Flag 1 =
      0)
         segment pertains to cancellation by block sender if (Flag 0
         = 1)
            segment is a cancellation by sender
         else
            segment is an acknowledgment of a cancellation by sender
      else
         segment pertains to cancellation by block receiver if (Flag
         0 = 1)
            segment is a cancellation by receiver
         else
            segment is an acknowledgment of a cancellation by
            receiver

3.1.2. Segment Type Codes ๐Ÿ”ข

when you combine the settings of CTRL, EXC, Flag 1, and Flag 0, you get a segment type code. it's basically a neat shorthand for what the segment is, so you don't have to say the whole thing every time ๐Ÿ’–

CTRL EXC Flag 1 Flag 0 Code  Nature of segment
---- --- ------ ------ ----  ---------------------------------------
  0   0     0      0     0   Red data, NOT {Checkpoint, EORP or EOB}
  0   0     0      1     1   Red data, Checkpoint, NOT {EORP or EOB}
  0   0     1      0     2   Red data, Checkpoint, EORP, NOT EOB
  0   0     1      1     3   Red data, Checkpoint, EORP, EOB

  0   1     0      0     4   Green data, NOT EOB
  0   1     0      1     5   Green data, undefined
  0   1     1      0     6   Green data, undefined
  0   1     1      1     7   Green data, EOB

  1   0     0      0     8   Report segment
  1   0     0      1     9   Report-acknowledgment segment
  1   0     1      0    10   Control segment, undefined
  1   0     1      1    11   Control segment, undefined

  1   1     0      0    12   Cancel segment from block sender
  1   1     0      1    13   Cancel-acknowledgment segment
                              to block sender

  1   1     1      0    14   Cancel segment from block receiver
  1   1     1      1    15   Cancel-acknowledgment segment
                              to block receiver

3.1.3. Segment Class Masks ๐ŸŽญ

some bit patterns in the flags get a fun nickname called segment classes, which are named with mnemonics. the mnemonics are meant to give you a vibe of what all the segments sharing that pattern have in common โœจ

CTRL EXC Flag 1 Flag 0  Mnemonic  Description
---- --- ------ ------  --------  ---------------------------
  0   0     -      1
     -- or --
  0   0     1      -      CP      Checkpoint

  0   0     1      -      EORP    End of red-part;
                                  red-part size = offset + length

  0   -     1      1      EOB     End of block;
                                  block size = offset + length

  1   0     0      0      RS      Report segment;
                                  carries reception claims

  1   0     0      1      RA      Report-acknowledgment segment

  1   1     0      0      CS      Cancel segment from block sender

  1   1     0      1      CAS     Cancel-acknowledgment segment
                                  to block sender

  1   1     1      0      CR      Cancel segment from block receiver

  1   1     1      1      CAR     Cancel-acknowledgment segment
                                  to block receiver

  1   1     -      0      Cx      Cancel segment (generic)

  1   1     -      1      CAx     Cancel-acknowledgment segment
                                  (generic)

3.1.4. Extensions Field ๐Ÿงฉ

the Extensions field is where you bolt on extra functionality to the basic LTP segment ๐Ÿ”ง you can add zero or more extensions, and each one is a type-length-value (TLV) thing, explained below ๐Ÿ’•

the first octet of the Extensions field is a headcount ๐Ÿ˜‚ the high-order 4 bits tell you how many extension TLVs are in the header (right after the extensions count octet, and before the segment's content). the low-order 4 bits tell you how many are in the trailer (right after the segment's content). so each segment can have anywhere from 0 to 15 extension TLVs in its header, and 0 to 15 in its trailer ๐Ÿ™Œ if there are no extension TLVs at all, all bits of this extensions count octet MUST be set to zero ๐Ÿซถ

it's totally valid for header extensions to be followed right away by trailer extensions. for example, since a CAx segment has no contents, it can have header extensions immediately followed by trailer extensions ๐Ÿฆ‹

each extension is one octet of tag (which says what type it is), then a length parameter in SDNV form, then a value of that length ๐Ÿ’…

here's what those TLVs look like, whether they're in the header or the trailer ๐ŸŽ€

+--------+----///-----///--+
|ext-tag | length  | value |
+--------+-------///-------+----------///-------+
|ext-tag |     length      |       value        |
+--------+-----///-----///-+---------////-------+
|ext-tag |   length |   value  |
+--------+----------+----------+

the IANA keeps an LTP Extension Tag registry, which looks like this ๐Ÿ“‹ for how code points get assigned in the Unassigned range, check the IANA considerations section further down ๐Ÿ‘€

Extension tag     Meaning
-------------     -------
0x00              LTP authentication extension [LTPEXT]
0x01              LTP cookie extension [LTPEXT]
0x02-0xAF         Unassigned
0xB0-0xBF         Reserved
0xC0-0xFF         Private / Experimental Use
โš ๏ธ heads up, bestie: since the last quarter of the extension-tag space is for experimental use, implementations should be aware that collisions for these tags are possible ๐Ÿ’€

3.2. Segment Content ๐Ÿ’Œ

3.2.1. Data Segment (DS) ๐Ÿ’–

okay so the data segment is where the real good stuff lives ๐ŸŽ€ It carries the client service data and the metadata the receiving client service needs to actually receive and use that data โœจ

Client service ID (SDNV) ๐ŸŒธ This says which upper-level service the receiver should deliver the segment to. It's kinda like a TCP port number, bestie. If there are multiple instances of the client service at the destination, the client service itself must do the multiplexing, based on info encoded in the transmitted block.

Offset (SDNV) ๐Ÿฆ‹ Offset tells you where the segment's client service data sits inside the session's transmitted block. It's the number of bytes in the block that come before the byte the segment's first octet was copied from.

Length (SDNV) ๐Ÿ’… The length of the client service data that follows, in octets.

If the data segment is a checkpoint, it MUST also include these two serial numbers (checkpoint serial number and report serial number) so retransmission stays efficient ๐Ÿงš Data segments that aren't checkpoints MUST NOT have these two fields in the header, and they MUST go straight on into the client service data ๐Ÿ™ˆ

Checkpoint serial number (SDNV) ๐Ÿ”ฅ This uniquely identifies the checkpoint among all the checkpoints the block sender issues in a session. The first checkpoint the sender issues MUST have this serial number chosen randomly for security reasons, and it is RECOMMENDED that the sender use the guidelines in [ESC05] for this. Any later checkpoints MUST have the serial number found by incrementing the prior checkpoint serial number by 1. When a checkpoint segment is retransmitted, though, its serial number MUST be the same as when it was originally transmitted. The checkpoint serial number MUST NOT be zero.

Report serial number (SDNV) ๐Ÿ‘‘ If the checkpoint was queued for transmission because of an RS (Section 6.13) reception, then its value MUST be the report serial number value of the RS that caused the data segment to be queued for transmission.

Otherwise, the value of report serial number MUST be zero.

Client service data (array of octets) ๐ŸŒˆ This is a copy of a subset of the bytes in the original client service data block, starting at the indicated offset.

3.2.2. Report Segment (RS) ๐ŸŒธ

The content of an RS is one or more data reception claims, plus the upper and lower bounds of the scope within the data block that those claims are about. It also has two serial numbers to support efficient retransmission โœจ

Report serial number (SDNV) ๐Ÿ’œ This uniquely identifies the report among all reports the receiver issues in a session. The first report the receiver issues MUST have this serial number chosen randomly for security reasons, and it is RECOMMENDED that the receiver use the guidelines in [ESC05] for this. Any subsequent RS the receiver issues MUST have the serial number found by incrementing the last report serial number by 1. When an RS is retransmitted, however, its serial number MUST be the same as when it was originally transmitted. The report serial number MUST NOT be zero.

Checkpoint serial number (SDNV) ๐Ÿฆ‹ The value MUST be zero if the report segment is NOT a response to reception of a checkpoint, i.e., the reception report is asynchronous. Otherwise, it MUST be the checkpoint serial number of the checkpoint that caused the RS to be issued.

Upper bound (SDNV) ๐Ÿงš The upper bound of a report segment is the size of the block prefix that the segment's reception claims pertain to.

Lower bound (SDNV) ๐Ÿซถ The lower bound of a report segment is the size of the (interior) block prefix that the segment's reception claims do NOT pertain to.

Reception claim count (SDNV) ๐Ÿ“ The number of data reception claims in this report segment.

Reception claims ๐Ÿ’… Each reception claim has two elements: offset and length.

Offset (SDNV) โœจ The offset indicates successful reception of data beginning at the indicated offset from the lower bound of the RS. You can work out the offset within the entire block by adding this offset to the lower bound of the RS.

Length (SDNV) ๐ŸŒŸ The length of a reception claim is the number of contiguous octets of block data, starting at the indicated offset, that have been successfully received.

Reception claims MUST conform to the following rules:

  • A reception claim's length shall never be less than 1 and shall never exceed the difference between the upper and lower bounds of the report segment.
  • The offset of a reception claim shall always be greater than the sum of the offset and length of the prior claim, if any.
  • The sum of a reception claim's offset and length and the lower bound of the report segment shall never exceed the upper bound of the report segment.

Implied requests for retransmission of client service data can be inferred from an RS's data reception claims. However, nothing can be inferred about reception of block data at any offset equal to or greater than the segment's upper bound, or at any offset less than the segment's lower bound ๐Ÿ™ˆ

For example, if the scope of a report segment has lower bound 0 and upper bound 6000, and the report contains a single data reception claim with offset 0 and length 6000, then the report signifies successful reception of the first 6000 bytes of the block. If the total length of the block is 6000, then the report additionally signifies successful reception of the entire block ๐ŸŽ‰

If, on the other hand, the scope of a report segment has lower bound 1000 and upper bound 6000, and the report contains two data reception claims, one with offset 0 and length 2000 and the other with offset 3000 and length 500, then the report signifies successful reception only of bytes 1000-2999 and 4000-4499 of the block. From this we can infer that bytes 3000-3999 and 4500-5999 of the block need to be retransmitted. But we cannot infer anything about reception of the first 1000 bytes, or of any subsequent data beginning at block offset 6000 ๐Ÿ˜ญ

3.2.3. Report Acknowledgment Segment ๐Ÿฆ‹

The content of an RA is simply the report serial number of the RS that the segment was generated in response to โœจ

Report serial number (SDNV) ๐ŸŽ€ This field returns the report serial number of the RS being acknowledged.

3.2.4. Session Management Segments ๐Ÿ’œ

Cancel segments (Cx) carry a single byte reason-code with the following semantics ๐Ÿ‘‘

Reason-Code    Mnemonic    Semantics
-----------    --------    ---------------------------------------
    00         USR_CNCLD   Client service canceled session.

    01         UNREACH     Unreachable client service.

    02         RLEXC       Retransmission limit exceeded.

    03         MISCOLORED  Received either a red-part data segment
                           at block offset above any green-part
                           data segment offset or a green-part
                           data segment at block offset below any
                           red-part data segment offset.

    04         SYS_CNCLD   A system error condition caused
                           unexpected session termination.

    05         RXMTCYCEXC  Exceeded the Retransmission-Cycles limit.

   06-FF       Reserved

The Cancel-acknowledgments (CAx) have no content ๐ŸŒธ

Note: the reason we use different cancel segment types for the originator and the recipient is to let a loopback mode work without disturbing any replay protection mechanism in use ๐Ÿ”


3.3. Segment Trailer ๐ŸŒˆ

The segment trailer is a sequence of zero to 15 extension TLVs, as described in Section 3.1.4 above ๐Ÿงš

4. Requests from Client Service โœจ

In all cases, how request parameters are represented is a local implementation matter. So are validating parameter values and notifying the client service when a request turns out to be invalid ๐Ÿ’…

4.1. Transmission Request ๐Ÿš€

To request transmission of a block of client service data, the client service MUST provide the following parameters to LTP:

  • Destination client service ID.
  • Destination LTP engine ID.
  • Client service data to send, as an array of bytes.
  • Length of the data to be sent.
  • Length of the red-part of the data. This value MUST be in the range from zero to the total length of data to be sent.

On reception of a valid transmission request from a client service, LTP proceeds as follows ๐Ÿ’–

First, the array of data to be sent is subdivided as necessary, with each subdivision serving as the client service data of a single new LTP data segment. The algorithm used for subdividing the data is a local implementation matter. It's expected that any data size constraints imposed by the underlying communication service will be accommodated in this algorithm ๐ŸŒธ

The last (and only the last) of the resulting data segments must be marked as the EOB (end of block) ๐Ÿ

Note that segment type indicates whether the client service data in a given LTP segment is or isn't in the red-part of the block. To prevent segment type ambiguity, each data segment MUST contain either only red-part data or only green-part data. So when the length of the block's red-part is N, the total length of the block is M, and N is not equal to M, the (N+1)th byte of the block SHOULD be the first byte of client service data in a green-part data segment. This means that at the red-part boundary, LTP may send a segment smaller than the link MTU size. For bandwidth efficiency reasons, implementations MAY choose instead to mark the entire segment (within which the red-part boundary falls) as red-part, causing any green-part data falling within the segment to also be treated as red-part ๐Ÿฆ‹

โš ๏ธ Heads up: the red-part/green-part boundary is the tricky bit here, so keep those SHOULD and MAY choices straight when you implement this!

If the length of the block's red-part is greater than zero, then the last data segment containing red-part data must be marked as the EORP (end of red-part) segment, by setting the appropriate segment type flag bits (Section 3.1.2). Zero or more preceding data segments containing red-part data (selected according to an algorithm that is a local implementation matter) MAY additionally be marked as a CP (Checkpoint), serving as additional discretionary checkpoints (Section 3.1.2) ๐Ÿงš

All data segments are appended to the (conceptual) application data queue bound for the destination engine, for subsequent transmission ๐Ÿ“ฌ

Finally, a session start notice (Section 7.1) is sent back to the client service that requested the transmission ๐ŸŽ€

4.2. Cancellation Request โœจ

okay so, bestie ๐Ÿฅบ cancelling a session can be done by either the sender or the receiver of the associated data block, and the client service has to hand over the session ID of the session it wants gone ๐Ÿ’…

When LTP gets a valid cancellation request from a client service, it does the following, in this order ๐Ÿซถ

First, it invokes the internal "Cancel Session" procedure (Section 6.19) ๐ŸŒธ

Next, it checks who's doing the cancelling. If it's the sender (meaning the session originator part of the session ID in the request is the local LTP engine ID) ๐Ÿ‘‘:

  • If none of the data segments queued for this session have been de-queued and transmitted yet, the destination engine can't possibly know this session exists ๐Ÿ’€ so the session just gets closed, and the "Close Session" procedure (Section 6.20) is invoked.
  • Otherwise, a CS (cancel by block sender) segment with the reason-code USR_CNCLD MUST be queued for transmission to the destination LTP engine specified in the transmission request that started this session ๐Ÿ“จ

Otherwise (so the receiver is the one cancelling) ๐Ÿ™ˆ:

  • If there's no transmission queue-set bound for the sender (maybe the local LTP engine is running on a receive-only device ๐Ÿ“ก), then the session is simply closed, and the "Close Session" procedure (Section 6.20) is invoked.
  • Otherwise, a CR (cancel by block receiver) segment with reason-code USR_CNCLD MUST be queued for transmission to the block sender.

5. Requirements from the Operating Environment ๐ŸŒˆ

okay so, LTP is built to run directly over a data-link layer protocol ๐Ÿ”—

LTP MUST only be deployed directly over UDP, for software development purposes or for use in private local area networks, for example, in a sparse sensor network where the link, when available, is only used for LTP traffic ๐Ÿ›ฐ๏ธ

Either way, the protocol sitting right underneath LTP is called the "local data-link layer" for the purposes of this spec ๐Ÿงฑ

When the local data-link layer protocol is UDP, (a) the content of each UDP datagram MUST be an integral number of LTP segments and (b) the LTP authentication [LTPEXT] extension SHOULD be used unless the end-to-end path is one in which either the likelihood of datagram content corruption is negligible or the consequences of receiving and processing corrupt LTP segments are insignificant (as during software development). In addition, the LTP authentication [LTPEXT] extension SHOULD be used to ensure data integrity unless the end-to-end path is one in which either the likelihood of datagram content corruption is negligible (as in some private local area networks) or the consequences of receiving and processing corrupt LTP segments are insignificant (as perhaps during software development).

When the local data-link layer protocol is not UDP, the content of each local data-link layer protocol frame MUST be an integral number of LTP segments.

The local data-link layer protocol MUST be a protocol that, together with the operating environment in which that protocol is implemented, satisfies the following requirements:

  • It is required to inform LTP whenever the link to a specific LTP destination is brought up or torn down. Similarly, it is required to inform the local LTP engine whenever it is known that a remote LTP engine is set to begin or stop communication with the local engine based on the engines' operating schedules.
  • It is required to provide link state cues to LTP upon transmission of the CP, RS (report), EORP, EOB, and Cx (cancel) segments so that timers can be started.
  • It is required to provide, upon request, the current distance (in light seconds) to any peer engine in order to calculate timeout intervals.

A MIB (Management Information Base) with the above parameters, updated periodically by the local data-link layer and the operating environment, should be made available to the LTP engine for its operations. The details of the MIB are, however, beyond the scope of this document. ๐Ÿ“š

The underlying data-link layer is required to never deliver incompletely received LTP segments to LTP. In the absence of the use of LTP authentication [LTPEXT], LTP also requires the underlying local data-link layer protocol to perform data integrity checking of the segments received. Specifically, the local data-link layer protocol is required to detect any corrupted segments received and to silently discard them. ๐Ÿคซ


6. Internal Procedures ๐Ÿ•ต๏ธโ€โ™€๏ธ

This section is all about the internal procedures that get triggered when various events happen during the lifetime of an LTP session โœจ

Whenever the content of any field in the header of a received LTP segment doesn't conform to this specification document, the segment is assumed to be corrupt and MUST be discarded immediately and processed no further. This procedure supersedes all other procedures described below. ๐Ÿšซ

All internal procedures described below that are triggered by the arrival of a data segment are superseded by the following procedure in the event that the client service identified by the data segment does not exist at the local LTP engine:

  • If there is no transmission queue-set bound for the block sender (possibly because the local LTP engine is running on a receive-only device), then the received data segment is simply discarded.
  • Otherwise, if the data segment contains data from the red-part of the block, a CR with reason-code UNREACH MUST be enqueued for transmission to the block sender. A CR with reason-code UNREACH SHOULD be similarly enqueued for transmission to the data sender even if the data segment contained data from the green-part of the block; note however that (for example) in the case where the block receiver knows that the sender of this green-part data is functioning in a "beacon" (transmit-only) fashion, a CR need not be sent. In either case, the received data segment is discarded.

6.1. Start Transmission ๐Ÿš€

This procedure is triggered by the arrival of a link state cue indicating the start of transmission to a specified remote LTP engine.

Response: the de-queuing and delivery of segments to the LTP engine specified in the link state cue begins.

6.2. Start Checkpoint Timer โฑ๏ธ

This procedure is triggered by the arrival of a link state cue indicating the de-queuing (for transmission) of a CP segment.

Response: the expected arrival time of the RS segment that will be produced on reception of this CP segment is computed, and a countdown timer is started for this arrival time. However, if it is known that the remote LTP engine has ceased transmission (Section 6.5), then this timer is immediately suspended, because the computed expected arrival time may require an adjustment that cannot yet be computed.

6.3. Start RS Timer โณ

This procedure is triggered by the arrival of a link state cue indicating the de-queuing (for transmission) of an RS segment.

Response: the expected arrival time of the RA (report acknowledgment) segment in response to the reception of this RS segment is computed, and a countdown timer is started for this arrival time. However, as in Section 6.2, if it is known that the remote LTP engine has ceased transmission (Section 6.5), then this timer is immediately suspended, because the computed expected arrival time may require an adjustment that cannot yet be computed.

6.4. Stop Transmission ๐Ÿ›‘

This procedure is triggered by the arrival of a link state cue indicating the cessation of transmission to a specified remote LTP engine.

Response: the de-queuing and delivery to the underlying communication system of segments from traffic queues bound for the LTP engine specified in the link state cue ceases.

6.5. Suspend Timers โธ๏ธ

This procedure is triggered by the arrival of a link state cue indicating the cessation of transmission from a specified remote LTP engine to the local LTP engine. Normally, this event is inferred from advance knowledge of the remote engine's planned transmission schedule.

Response: countdown timers for the acknowledging segments that the remote engine is expected to return are suspended as necessary based on the following procedure.

The nominal remote engine acknowledge transmission time is computed as the sum of the transmission time of the original segment (to which the acknowledging segment will respond) and the one-way light time to the remote engine, plus N seconds of "additional anticipated latency" (AAL) encompassing anticipated transmission delays other than signal propagation time. N is determined in an implementation-specific manner. For example, when LTP is deployed in deep-space vehicles, the one-way light time to the remote engine may be very large while N may be relatively small, covering processing and queuing delays. N may be a network management parameter, for which 2 seconds seems like a reasonable default value. As another example, when LTP is deployed in a terrestrial "data mule" environment, one-way light time latency is effectively zero while N may need to be some dynamically computed function of the data mule circulation schedule.

If the nominal remote engine acknowledge transmission time is greater than or equal to the current time (i.e., the acknowledging segment may be presented for transmission during the time that transmission at the remote engine is suspended), then the countdown timer for this acknowledging segment is suspended.

6.6. Resume Timers โ–ถ๏ธ

This procedure is triggered by the arrival of a link state cue indicating the start of transmission from a specified remote LTP engine to the local LTP engine. Normally, this event is inferred from advance knowledge of the remote engine's planned transmission schedule.

Response: expected arrival time is adjusted for every acknowledging segment that the remote engine is expected to return, for which the countdown timer has been suspended. First, the transmission delay interval is calculated as follows:

  • The nominal remote engine acknowledge transmission time is computed as the sum of the transmission time of the original segment (to which the acknowledging segment will respond) and the one-way light time to the remote engine, plus N seconds of AAL Section 6.5.
  • If the nominal remote engine acknowledge transmission time is greater than the current time, i.e., the remote engine resumed transmission prior to presentation of the acknowledging segment for transmission, then the transmission delay interval is zero.
  • Otherwise, the transmission delay interval is computed as the current time less the nominal remote engine acknowledge transmission time.

The expected arrival time is increased by the computed transmission delay interval for each of the suspended countdown timers, and the timers are resumed. ๐Ÿ’–

6.7. Retransmit Checkpoint ๐Ÿ’–

okay so this one gets triggered when the countdown timer attached to a CP segment runs out โฐ that's the whole trigger, bestie ๐Ÿ’…

Response: if this CP segment has already been queued for transmission more times than the checkpoint retransmission limit that network management set for the local LTP engine ๐Ÿซ , then the session it belongs to gets canceled ๐Ÿ™…โ€โ™€๏ธ. The "Cancel Session" procedure (Section 6.19) gets invoked, a CS with reason-code RLEXC gets appended to the (conceptual) application data queue, and a transmission-session cancellation notice (Section 7.5) gets sent back to the client service that requested the transmission.

Otherwise, a new copy of the CP segment gets appended to the (conceptual) application data queue for the destination LTP engine ๐Ÿฆ‹


6.8. Retransmit RS ๐ŸŒธ

this one is triggered in two ways ๐Ÿ‘€ either (a) the countdown timer for an RS segment expires, or (b) a CP segment shows up when one or more RS segments were already issued for it. that second one is a redundantly retransmitted checkpoint, and it's giving dรฉjร  vu ๐Ÿ™ˆ

Response: if any affected RS segment has been queued for transmission more times than the report retransmission limit that network management set for the local LTP engine, then the session it belongs to gets canceled ๐Ÿ’€. The "Cancel Session" procedure (Section 6.19) gets invoked, a CR segment with reason-code RLEXC gets queued for transmission to the LTP engine that originated the session, and a reception-session cancellation notice (Section 7.6) gets sent to the client service identified in each of the data segments received in this session.

Otherwise, a new copy of each affected RS segment gets queued for transmission to the LTP engine that originated the session ๐Ÿงš


6.9. Signify Red-Part Reception โœจ

this is triggered when a CP segment arrives and the EORP for this session has already been received ๐ŸŽ€ that way the size of the data block's red-part is known (and yes, this includes the case where the CP segment itself is the EORP segment). it also needs all the data in the red-part of the block being transmitted in this session to have arrived. no cap, it's a big moment ๐Ÿ‘‘

Response: a red-part reception notice (Section 7.3) gets sent to the specified client service.


6.10. Signify Green-Part Segment Arrival ๐Ÿ“

triggered when a data segment shows up with content that's part of a block's green-part ๐ŸŒˆ

Response: a green-part segment arrival notice (Section 7.2) gets sent to the specified client service.


6.11. Send Reception Report ๐ŸŽ€

okay this one is a whole thing, so get comfy ๐Ÿซถ it's triggered by either (a) the original reception of a CP segment (the checkpoint serial number identifying this CP is new) (b) an implementation-specific circumstance that matters for a block reception session where no EORP has arrived yet. that second one is called "asynchronous" reception reporting, and it's lowkey iconic ๐Ÿ”ฅ

Response: if the number of reception problems detected for this session goes over a limit that network management set for the local LTP engine, then the affected session gets canceled ๐Ÿ’€. The "Cancel Session" procedure (Section 6.19) gets invoked, a CR segment with reason-code RLEXC gets issued and is, in concept, appended to the queue of internal operations traffic bound for the LTP engine that originated the session, and a reception-session cancellation notice (Section 7.6) gets sent to the client service identified in each of the data segments received in this session. One possible limit on reception problems would be the maximum number of reception reports that can be issued for any single session ๐Ÿง

If that limit hasn't been reached, a reception report gets issued as follows โœจ

If production of the reception report was triggered by reception of a checkpoint:

  • The upper bound of the report SHOULD be the upper bound (the sum of the offset and length) of the checkpoint data segment, to minimize unnecessary retransmission. Note: If a discretionary checkpoint is lost but subsequent segments are received, then by the time the retransmission of the lost checkpoint is received the receiver would have segments at block offsets beyond the upper bound of the checkpoint. For deployments where bandwidth economy is not critical, the upper bound of a synchronous reception report MAY be the maximum upper bound value among all red-part data segments received so far in the affected session.
  • If the checkpoint was itself issued in response to a report segment, then this report is a "secondary" reception report. In that case, the lower bound of the report SHOULD be the lower bound of the report segment to which the triggering checkpoint was itself a response, to minimize unnecessary retransmission. Note: For deployments where bandwidth economy is not critical, the lower bound of the report MAY instead be zero.
  • If the checkpoint was not issued in response to a report segment, this report is a "primary" reception report. The lower bound of the first primary reception report issued for any session MUST be zero. The lower bound of each subsequent primary reception report issued for the same session SHOULD be the upper bound of the prior primary reception report issued for the session, to minimize unnecessary retransmission. Note: For deployments where bandwidth economy is not critical, the lower bound of every primary reception report MAY be zero.

If production of the reception report is "asynchronous" as noted above:

  • The upper bound of the report MUST be the maximum upper bound among all red-part data segments received so far for this session.
  • The lower bound of the first asynchronous reception report issued for any session for which no other primary reception reports have yet been issued MUST be zero. The lower bound of each subsequent asynchronous reception report SHOULD be the upper bound of the prior primary reception report issued for the session, to minimize unnecessary retransmission. Note: For deployments where bandwidth economy is not critical, the lower bound of every asynchronous reception report MAY be zero.

In all cases, if the applicable lower bound of the scope of a report is determined to be greater than or equal to the applicable upper bound (for example, due to out-of-order arrival of discretionary checkpoints) then the reception report MUST NOT be issued. Otherwise:

As many RS segments must be produced as are needed in order to report on all data reception within the scope of the report, given whatever data size constraints are imposed by the underlying communication service. The RS segments are, in concept, appended to the queue of internal operations traffic bound for the LTP engine that originated the indicated session. The lower bound of the first RS segment of the report MUST be the reception report's lower bound. The upper bound of the last RS segment of the report MUST be the reception report's upper bound ๐Ÿ’–


6.12. Signify Transmission Completion ๐Ÿ’…

this gets triggered at the earliest moment that (a) all data in the block is known to have been transmitted and (b) the entire red-part of the block (if it's non-zero length) is known to have been successfully received ๐Ÿ™Œ condition (a) is signaled when a link state cue shows the EOB segment for the block being de-queued for transmission. condition (b) is signaled when an RS segment arrives whose reception claims, taken together with the reception claims of all other RS segments previously received in this session, show complete reception of the red-part of the block โœจ

Response: a transmission-session completion notice (Section 7.4) gets sent to the local client service associated with the session, and the session gets closed. The "Close Session" procedure (Section 6.20) gets invoked ๐ŸŽ‰


6.13. Retransmit Data ๐Ÿงš

triggered by the reception of an RS segment ๐Ÿซ 

Response: first, an RA segment with the same report serial number as the RS segment gets issued and is, in concept, appended to the queue of internal operations traffic bound for the receiver. If the RS segment is redundant (aka the indicated session is unknown, for example because the RS segment got received after the session was already completed or canceled, or the RS segment's report serial number matches one that was already received and processed), then no further action is taken. Otherwise, the procedure below gets followed ๐Ÿ‘€

If the report's checkpoint serial number is not zero, then the countdown timer associated with the indicated checkpoint segment gets deleted.

Note: All retransmission buffer space occupied by data whose reception is claimed in the report segment can (in concept) be released.

If the segment's reception claims indicate incomplete data reception within the scope of the report segment:

  • If the number of transmission problems for this session goes over a limit that network management set for the local LTP engine, then the session it belongs to gets canceled ๐Ÿ™…โ€โ™€๏ธ. The "Cancel Session" procedure (Section 6.19) gets invoked, a CS with reason-code RLEXC gets appended to the transmission queue specified in the transmission request that started this session, and a transmission-session cancellation notice (Section 7.5) gets sent back to the client service that requested the transmission. One possible limit on transmission problems would be the maximum number of retransmission CP segments that may be issued for any single session.
  • If the number of transmission problems for this session hasn't gone over any limit, new data segments encapsulating all block data whose non-reception is implied by the reception claims get appended to the transmission queue bound for the receiver. The last -- and only the last -- data segment must be marked as a CP segment carrying a new CP serial number (obtained by incrementing the last CP serial number used) and the report serial number of the received RS segment ๐ŸŒธ

6.14. Stop RS Timer โญ

triggered by the reception of an RA ๐Ÿ’œ

Response: the countdown timer associated with the original RS segment (identified by the report serial number of the RA segment) gets deleted. If no other countdown timers associated with RS segments exist for this session, then the session gets closed. The "Close Session" procedure (Section 6.20) gets invoked ๐Ÿซถ


6.15. Start Cancel Timer ๐Ÿ’œ

this one's triggered when a link state cue shows a Cx segment being de-queued for transmission ๐Ÿฆ‹

Response: the expected arrival time of the CAx segment that will be produced on reception of this Cx segment gets computed, and a countdown timer for that arrival time gets started. However, if it's known that the remote LTP engine has ceased transmission (Section 6.5), then this timer gets immediately suspended, because the computed expected arrival time may need an adjustment that can't be computed yet ๐Ÿฅบ

6.16. Retransmit Cancellation Segment ๐Ÿ”

This procedure gets triggered when a countdown timer attached to a Cx segment runs out โฐ.

Response: if this Cx segment has already been queued for transmission more times than the cancellation retransmission limit that network management set for the local LTP engine, then the session it's one token of gets simply closed. The "Close Session" procedure (Section 6.20) is invoked ๐Ÿ’….

Otherwise, a copy of the cancellation segment (keeping the same reason-code) is queued for transmission to the appropriate LTP engine ๐Ÿ“ฆ.

6.17. Acknowledge Cancellation ๐Ÿซถ

This procedure is triggered by the reception of a Cx segment.

Response: in the case of a CS segment where there is no transmission queue-set bound for the sender (possibly because the receiver is a receive-only device), then no action is taken. Otherwise:

  • If the received segment is a CS segment, a CAS (cancel acknowledgment to block sender) segment is issued and is, in concept, appended to the queue of internal operations traffic bound for the sender.
  • If the received segment is a CR segment, a CAR (cancel acknowledgment to block receiver) segment is issued and is, in concept, appended to the queue of internal operations traffic bound for the receiver.

It's possible that the Cx segment got retransmitted because a previous responding acknowledgment CAx (cancel acknowledgment) segment was lost ๐Ÿ˜ฌ. In that case there's no longer any record of the session it's one token of, so no further action is taken.

Otherwise, the "Cancel Session" procedure (Section 6.19) is invoked, and a reception-session cancellation notice (Section 7.6) is sent to the client service identified in each of the data segments received in this session. Finally, the session is closed: the "Close Session" procedure (Section 6.20) is invoked ๐Ÿ‘‹.

6.18. Stop Cancel Timer โน๏ธ

This procedure is triggered by the reception of a CAx segment.

Response: the timer associated with the Cx segment is deleted, and the session it's one token of is closed, i.e., the "Close Session" procedure (Section 6.20) is invoked โœจ.

6.19. Cancel Session ๐Ÿงน

This procedure is triggered internally by one of the other procedures described above.

Response: all segments of the affected session that are currently queued for transmission can be deleted from the outbound traffic queues. All countdown timers currently associated with the session are deleted.

Note: If the local LTP engine is the sender, then all remaining data retransmission buffer space allocated to the session can be released ๐Ÿซง.

6.20. Close Session ๐Ÿšช

This procedure is triggered internally by one of the other procedures described above.

Response: any remaining countdown timers associated with the session are deleted. The session state record (SSR|RSR) for the session is deleted, and existence of the session is no longer recognized. It's gone, bestie ๐Ÿ‘ป.

6.21. Handle Miscolored Segment ๐ŸŽจ

This procedure is triggered by the arrival of either (a) a red-part data segment whose block offset begins at an offset higher than the block offset of any green-part data segment previously received for the same session, or (b) a green-part data segment whose block offset is lower than the block offset of any red-part data segment previously received for the same session. The arrival of a segment matching either of the above checks is a violation of the protocol requirement of having all red-part data as the block prefix and all green-part data as the block suffix ๐Ÿ™ˆ.

Response: the received data segment is simply discarded.

The Cancel Session procedure (Section 6.19) is invoked, and a CR segment with reason-code MISCOLORED SHOULD be enqueued for transmission to the data sender.

Note: If there is no transmission queue-set bound for the sender (possibly because the local LTP engine is running on a receive-only device), or if the receiver knows that the sender is functioning in a "beacon" (transmit-only) fashion, a CR segment need not be sent ๐Ÿ“ก.

A reception-session cancellation notice (Section 7.6) is sent to the client service.

6.22. Handling System Error Conditions ๐Ÿ’ฅ

It's possible (especially for long-lived LTP sessions) that an unexpected operating system error condition may occur during the lifetime of an LTP session. An example is when the system faces a severe memory crunch, forcing LTP sessions into a scenario similar to TCP SACK [SACK] reneging. But unlike TCP SACK reception reports, which are advisory, LTP reception reports are binding, and reneging is NOT permitted on previously made reception claims. No take-backsies ๐Ÿšซ.

Under any such irrecoverable system error condition, the following response is to be initiated: the Cancel Session procedure (Section 6.19) is invoked. If the error condition is observed on the sender, a CS segment with reason-code SYS_CNCLD SHOULD be enqueued for transmission to the receiver, and a transmission-session cancellation notice (Section 7.5) is sent to the client service. On the other hand, if it's observed on the receiver, a CR segment with the same reason-code SYS_CNCLD SHOULD be enqueued for transmission to the sender, and a reception-session cancellation notice (Section 7.6) is sent to the client service.

Note that, as in (Section 6.21), if there is no transmission queue-set bound for the sender (possibly because the local LTP engine is running on a receive-only device), or if the receiver knows that the sender of this green-part data is functioning in a "beacon" (transmit-only) fashion, a CR segment need not be sent ๐Ÿ›ฐ๏ธ.

There may be other implementation-specific limits that may cause an LTP implementation to initiate session-cancellation procedures. One such limit is the maximum number of retransmission-cycles seen. A retransmission cycle at the LTP Sender comprises two related events: the transmission of all outstanding CP segments from the sender, and the reception of all RS segments issued from the receiver in response to those CP segments. A similar definition would apply at the LTP Receiver, but would relate to the reception of the CP segments and the transmission of all RS segments in response. Note that the retransmitted CP and RS segments remain part of their original retransmission-cycle. Also, a single CP segment may cause multiple RS segments to be generated if a reception report would not fit in a single data link-MTU-sized RS segment. All RS segments that are part of a reception report belong to the same retransmission cycle to which the CP segment belongs.

In the presence of severe channel error conditions, many retransmission cycles may elapse before red-part transmission is deemed successful. An implementation may therefore impose a retransmission-cycle limit to shield itself from a resource-crunch situation ๐Ÿ›ก๏ธ. If an LTP sender notices the retransmission-cycle limit being exceeded, it SHOULD initiate the Cancel Session procedure (Section 6.19), queuing a CS segment with reason-code RXMTCYCEXC and sending a transmission-session cancellation notice (Section 7.5) to the client service.

7. Notices to Client Service ๐Ÿ“จ

In all cases, the representation of notice parameters is a local implementation matter.

7.1. Session Start ๐ŸŽฌ

The Session Start notice returns the session ID identifying a newly created session.

At the sender, the session start notice informs the client service of the initiation of the transmission session. On receiving this notice, the client service may, for example, release resources of its own that are allocated to the block being transmitted, or remember the session ID so that the session can be canceled in the future if necessary. At the receiver, this notice indicates the beginning of a new reception session, and it's delivered upon arrival of the first data segment carrying a new session ID.

7.2. Green-Part Segment Arrival ๐Ÿ€

The following parameters are provided by the LTP engine when a green-part segment arrival notice is delivered:

  • Session ID of the transmission session.
  • Array of client service data bytes contained in the data segment.
  • Offset of the data segment's content from the start of the block.
  • Length of the data segment's content.
  • Indication as to whether or not the last byte of this data segment's content is also the end of the block.
  • Source LTP engine ID.

7.3. Red-Part Reception ๐Ÿ”ด

The following parameters are provided by the LTP engine when a red-part reception notice is delivered:

  • Session ID of the transmission session.
  • Array of client service data bytes that constitute the red-part of the block.
  • Length of the red-part of the block.
  • Indication as to whether or not the last byte of the red-part is also the end of the block.
  • Source LTP engine ID.

7.4. Transmission-Session Completion ๐Ÿ

The sole parameter provided by the LTP engine when a transmission-session completion notice is delivered is the session ID of the transmission session.

A transmission-session completion notice informs the client service that all bytes of the indicated data block have been transmitted and that the receiver has received the red-part of the block. Yay, we did it ๐Ÿฅณ.

7.5. Transmission-Session Cancellation ๐Ÿ›‘

The parameters provided by the LTP engine when a transmission-session cancellation notice is delivered are:

  • Session ID of the transmission session.
  • The reason-code sent or received in the Cx segment that initiated the cancellation sequence.

A transmission-session cancellation notice informs the client service that the indicated session was terminated, either by the receiver or else due to an error or a resource quench condition in the local LTP engine. There is no assurance that the destination client service instance received any portion of the data block ๐Ÿ’”.

7.6. Reception-Session Cancellation ๐Ÿ™…

The parameters provided by the LTP engine when a reception cancellation notice is delivered are:

  • Session ID of the transmission session.
  • The reason-code explaining the cancellation.

A reception-session cancellation notice informs the client service that the indicated session was terminated, either by the sender or else due to an error or a resource quench condition in the local LTP engine. No subsequent delivery notices will be issued for this session ๐Ÿ”‡.

7.7. Initial-Transmission Completion ๐Ÿš€

The session ID of the transmission session is included with the initial-transmission completion notice.

This notice informs the client service that all segments of a block (both red-part and green-part) have been transmitted. This notice only indicates that original transmission is complete; retransmission of any lost red-part data segments may still be necessary ๐Ÿ”โœจ.

8. State Transition Diagrams โœจ

okay so before we dive in, bestie, here are the mnemonics the sender and receiver state diagrams use ๐Ÿงš

      TE      Timer Expiry
      RDS     Regular Red Data Segment (NOT {CP|EORP|EOB})
      GDS     Regular Green Data Segment (NOT EOB)
      RL EXC  Retransmission Limit Exceeded
      RP        Red-Part
      GP        Green-Part
      FG        Fully-Green

Quick reading guide ๐Ÿฆ‹: blocks drawn as rectangles are real states, like this one,

      +---------+
      | FG_XMIT |
      +---------+

and blocks with jagged edges, like this one,

       /\/\/\/\
      | Cncld |
       \/\/\/\/

are either pointers to a state or placeholders for a whole sequence of state transitions. Keep that in your back pocket, it makes the diagrams SO much easier to read ๐Ÿ’œ

8.1. Sender ๐Ÿš€

Here's the LTP sender's whole vibe in one diagram. It's a lot, but we'll walk through it together ๐Ÿซถ

                 LTP Sender State Transition Diagram

                                  /\/\/\/\
                                 | Cncld |
                                  \/\/\/\/
                       +--------+    |     +------+
              Rcv CR;  |        V    V     V      | Rcv RS;
              Snd CAR  |       +-------------+    | Snd RA
                       +-------+   CLOSED    +----+
 +---------------------------->+------+------+
 |                                    | Blk. Trans. Req
 |                       Zero RP      +
 |  Xmit     ________________________/ \  Non-Zero RP
 |  GDS;    /                           \
 | +---+   |       +------------------+  |  +------+
 | |   V   V       |   /\/\   Rcv RS   V  V  V      |
 | |  +---------+  +<-| RX |<---+   +---------+    |
 | +<-+ FG_XMIT |  |   \/\/     +---+         +--->+ Xmit RDS;
 |    +----+----+  |                | RP_XMIT |    |
 |         |       |   /\/\     +---+         +--->+ Xmit {RDS, CP};
 +<--------+       +<-| CP |<---+   +-----+---+      Start CP Tmr
 |    Xmit             \/\/   CP TE       |    \
 | {GDS, EOB};                            |     |
 |                  Xmit {RDS, CP, EORP}; |     +-------+
 |                  Start CP Tmr          |             |
 |                                        |             |
 |                 +------------------+   |  +---+      | Xmit {RDS,
 |                 |   /\/\  Rcv RS   V   V  V   |      | CP, EORP,
 |                 +<-| RX |<---+   +---------+  |      | EOB};
 |                 |   \/\/     +---+         |  |      | Start
 |                 |                | GP_XMIT +->+      | CP Tmr
 |                 |   /\/\     +---+         | Xmit    |
 |                 +<-| CP |<---+   +-----+---+ GDS;    |
 |                     \/\/  CP TE        |             |
 |                                        |             |
 |                       Xmit {GDS, EOB}; |   +---------+
 |                                        |   |
 |                 +------------------+   |   |
 |                 |   /\/\  Rcv RS   V   V   V
 |                 +<-| RX |<---+   +-------------+
 |                 |   \/\/     +---+             |
 |                 |                | WAIT_RP_ACK |
 |                 |   /\/\     +---+             |
 |                 +<-| CP |<---+   +-----+-------+
 |                     \/\/  CP TE        | RP acknowledged fully;
 |                                        V
 +----------------------------------------+

          LTP Sender State Transition Diagram (contd.)

         /\/\                               /\/\
         |CP|                               |CX |
         \/\/                               \/\/
          | |                                 | Snd CS,
          | | RL EXC;                         | Start CS Tmr;
          | |                                 |
          | |        /\/\                     |  +---+
          | +------>| CX |                    V  V   |
          |          \/\/                +---------+ | CS TE,
          |                              | CS_SENT | | RL NOT EXC;
          V  RL NOT EXC;                 +-+--+--+-+ | Rxmt CS,
             Rxmt CP,                      |  |  |   | Restart
             Start CP Tmr;         CS TE,  |  |  +---+ CS Tmr
                                   RL EXC; |  |
                                           |  | Rcv CAS;
                                           V  V
                                           /\/\/\/\
                                          | Cncld  |
                                           \/\/\/\/

             /\/\
            | RX |
             \/\/
               |  Cncl CP Tmr (if any)
               V  Snd RA
         +---------+                                +----+
         | CHK_RPT |                                |    |
         +-+--+----+       RP in scope              V    |
           |  |     \     NOT rcvd. fully   +---------+  | Rxmt
 Redundant |  | RP   +--------------------->| RP_RXMT |  | missing
 RS rcvd;  |  | in scope                    +----+--+-+  | RDS;
           |  | rcvd. fully                      |  |    |
           V  V                    Rxmt last     |  +----+
                                   missing RDS   |
                                   (marked CP)   |
                                   Start CP Tmr; |
                                                 V

Okay, the cancel story first ๐Ÿ’… A cancel request can show up from the local client service while the LTP sender is in literally any state on that chart. If the sender wasn't already partway through the sequence starting at the CX marker, it runs the internal Cancel Session procedure (Section 6.19), then hops into the CX sequence and cancels with reason-code USR_CNCLD. From CX, a CS segment goes out with the right reason-code (USR_CNCLD or RLEXC, depending on how it got there), and the sender lands in the Cancel-from-Sender Sent (CS_SENT) state. The cancel timer starts once a link state cue says the CS segment is actually being sent (Section 6.15). When the CAS comes back from the receiver, the sender goes to CLOSED through the 'Cncld' pointer. Iconic, right? ๐Ÿ˜ญ

If the CS timer expires, the sender runs the internal Retransmit Cancellation Segment procedure (Section 6.16):

  • If the network management set retransmission limit is exceeded, the session just closes and the sender follows the Cncld marker to CLOSED. If the limit isn't exceeded, though, the CS segment gets queued for retransmission and the sender stays in CS_SENT. The CS timer restarts once a link state cue says real transmission is beginning, per the internal Start Cancel Timer procedure (Section 6.15).

Cancellation can also come from the receiver, as a CR segment, while the sender is in any state. When that happens, the internal Acknowledge Cancellation procedure (Section 6.17) kicks in: the sender sends a CAR segment back and returns to CLOSED ๐Ÿฆ‹

The sender then chills in CLOSED until a Block Transmission Request (Blk. Trans. Req) shows up from the client service instance. Then it picks its lane: FG_XMIT if none of the block was requested to go out as red, or RP_XMIT if a non-zero block-prefix was requested in red ๐ŸŒˆ

In FG_XMIT, the block gets chopped into multiple green LTP data segments that respect the link MTU size, and they're queued up for the remote engine. The last one is marked EOB, and then the sender goes back to CLOSED ๐ŸŽ€

RP_XMIT is similar but with red data segments, still respecting the link MTU size. The sender may optionally mark some red data segments as asynchronous checkpoints, and the internal Start Checkpoint Timer procedure (Section 6.2) runs once a link state cue says those checkpoints are being transmitted. If the request has a non-zero green part, the last red data segment gets marked CP and EORP, and the sender moves on to GP_XMIT once it's queued. If the request was fully red, though, the last red segment gets marked CP, EORP, and EOB, and the sender jumps straight to WAIT_RP_ACK. Either way, the Start Checkpoint Timer procedure (Section 6.2) runs once a link state cue shows the queued CP segments are being transmitted. In GP_XMIT, the green part gets chopped into green data segments and queued for the receiver, with the very last one marked EOB. After that, the sender moves to WAIT_RP_ACK ๐Ÿ’œ

Now, while the sender is in RP_XMIT, GP_XMIT, or WAIT_RP_ACK, it can get interrupted by these events:

  1. An RS might come in from the LTP receiver, either as a reply to a CP segment that was already sent or as an async nudge for faster retransmission. The sender then follows the state transitions starting at the RX marker (second part of the diagram) and retransmits data if needed, following the internal Retransmit Data procedure (Section 6.13). First, if the RS had a non-zero CP serial number, the matching CP timer gets canceled. Then an RA segment acknowledging the RS gets queued for the receiver, and the sender moves to the Check Report state (CHK_RPT). If the RS was a redundant one from the receiver (maybe the last RA got lost, or the receiver's RS timer went off too early), the sender does nothing more and goes back to whatever state it was interrupted in. Same deal if all the red data within the RS's scope is already reported as received: nothing to do, back to the interrupted state. But if the RS says some red data within its scope is still incomplete, the sender moves to the Red-Part Retransmit state (RP_RXMT), where the missing red data segments in scope get queued. The last one is marked as a CP, and the sender returns to the interrupted state. The internal procedure (Section 6.2) runs once a link state cue says the CP segment is being transmitted ๐Ÿ”ฅ
  2. A previously set CP timer might expire. Now the LTP sender follows the states beginning at the CP marker (second part of the diagram), and follows the internal procedure Retransmit Checkpoint (Section 6.7):

Okay so if the CP Retransmission Limit that network management set for the session has already been blown past ๐Ÿ’€, the LTP sender goes ahead and starts canceling the session with reason-code RLEXC ๐Ÿ™…โ€โ™€๏ธ, following the state transitions after the CX marker. ๐Ÿงจ

If the limit isn't exceeded yet ๐Ÿฅน, the CP segment just gets queued up for retransmission and the LTP sender drops back into the interrupted state ๐Ÿ”„. The internal procedure Start Checkpoint Timer (Section 6.2) gets kicked off again once a link state cue shows up saying transmission of that segment has begun โฑ๏ธโœจ.

The LTP sender stays parked at WAIT_RP_ACK ๐Ÿซถ once it lands there, and it keeps waiting until the red-part data is fully acknowledged as received by the receiver LTP. Then it heads back to CLOSED by way of the internal procedure Close Session (Section 6.20) ๐Ÿฆ‹.

Now, this part is giving main character energy ๐Ÿ‘‘ because even while the sender is chilling in CLOSED, it can still get an RS segment ๐Ÿ˜ญ. That happens if the last RA segment sent before the session closed got lost in transit, or if the LTP receiver resent the RS segment way too early ๐Ÿ™ˆ. When that happens, the sender retransmits an acknowledging RA segment and stays right where it is in CLOSED ๐Ÿ’….

Same deal if the receiver canceled the session by sending a CR segment ๐ŸŒธ. The receiver might resend that CR segment (maybe prematurely, or because the acknowledging CAR segment got lost ๐Ÿฅฒ). In that case the LTP sender retransmits the acknowledging CAR segment and, yep, stays in CLOSED ๐ŸŽ€. Periodt ๐Ÿ’œ.

8.2. Receiver ๐Ÿฆ‹

                  LTP Receiver State Transition Diagram

                                             /\/\/\/\
                          +----+       +----+ Cncld  |
                  Rcv CS; |    V       V     \/\/\/\/
                  Snd CAS |  +-------------+
                          +--+    CLOSED   +<--------------------------+
                             +------+------+                           |
                            +----+  | Rcv first DS                     |
                 Rcv RA;    |    V  V                                  |
                Cncl RS Tmr |   +--------+                             |
                            +---+ DS_REC |                             |
 +----------------------------->+-+--+-+-+<----------------------+---+ |
 |          Svc. does not exist   |  | | RS TE                   |   | |
 |   /\/\  or Rcv miscolored seg. |  | |               /\/\      |   | |
 |  | CX |<-----------------------+  | +------------->| RX |---->+   | |
 |   \/\/                            |                 \/\/          | |
 |                        Rcv RDS;   |   Rcv GDS;                    | |
 |                       +-----------+------------+                  | |
 |                       V                        V                  | |
 |   /\/\  RS TE +--------------+             +--------+             | |
 +<-| RX |<------+    RCV_RP    |             | RCV_GP |             | |
 |   \/\/        +-+----+--+--+-+             +--+-+-+-+             | |
 |                 |    |  |  |                  | | |               | |
 |    Rcvd RDS;    |    |  |  | Rcvd {RDS, CP,   | | | RS TE  /\/\   | |
 |                 |    |  |  | EORP, EOB};      | | +------>| RX |->+ |
 +<----------------+    |  |  | Snd RS,          | |          \/\/   | |
 |                      |  |  | Start RS Tmr     | | Rcvd GDS;       | |
 | Rcvd {RDS, CP};      |  |  |                  | +---------------->+ |
 | Snd RS, Start RS Tmr |  |  +-------+    +-----+                     |
 +<---------------------+  |          |    | Rcvd {GDS, EOB};          |
 |                         |          |    |                           |
 |                         | +-----+  |    |   +------+                |
 | Rcvd {RDS, CP, EORP};   | |     V  V    V   V      |                |
 | Snd RS, Start RS Tmr    | |   +----------------+   | Rcv RDS;       |
 |                         | |   |                +-->+                |
 |                         | |   |   WAIT_RP_REC  |   | Rcv {RDS, CP}; |
 |                         | |   |                +-->+ Snd RS, Start  |
 +<------------------------+ |   +---+--+-+-+-----+   |        RS Tmr  |
                             | RS TE |  | | | Rcv RA; |                |
                             |       V  | | | Cncl    |                |
                             |    /\/\  | | | RS Tmr  |                |
                             +---| RX | | | +-------->+                |
                                  \/\/  | |                            |
          /\/\                          | |                            |
         | CX |<------------------------+ |  RP rcvd. fully            |
          \/\/      Rcv miscolored seg.   +--------------------------->+
 Receiver State Transition Diagram (contd.)

               /\/\
              | RX |
               \/\/
               |  |
               |  | RL EXC;    /\/\
  RL NOT EXC;  |  +---------->| CX |
  Rxmt RS,     |               \/\/
  Start RS Tmr |
               V

               /\/\
              | CX |
               \/\/
                 | Snd CR,
                 | Start CR Tmr;
                 |
                 |  +----+
                 V  V    |
             +---------+ | CR TE,
             | CR_SENT | | RL NOT EXC;
             +-+--+--+-+ | Rxmt CR,
               |  |  |   | Restart
       CR TE,  |  |  +---+ CR Tmr
       RL EXC; |  |
               |  | Rcv CAR;
               V  V
               /\/\/\/\
              | Cncld  |
               \/\/\/\/

Okay so async cancel requests get handled kinda like how the LTP sender handles them ๐Ÿ’… If the cancel came from your own local client service instance and the receiver wasn't already chilling in CR_SENT, a CR segment with reason-code USR_CNCLD SHOULD be sent to the LTP sender, following the transitions that start at the CX marker, just like we covered up above. But if the cancel request comes FROM the LTP sender, the receiver sends a CAS segment and dips straight to CLOSED no matter what state it was in ๐Ÿซถ

The LTP receiver starts out at CLOSED and hops into the Data Segment Reception (DS_REC) state the moment it gets the first data segment โœจ If the client service ID in that data segment doesn't exist, a Cx segment with reason-code UNREACH SHOULD be sent to the LTP sender through the Cancellation sequence that starts at the CX marker (the second part of the diagram) ๐Ÿ™ˆ If the segment turns out to be miscolored, the internal procedure Handle Miscolored Segment (Section 6.21) gets followed, and a CX segment with reason-code MISCOLORED SHOULD be sent to the LTP sender with the Cancellation sequence starting at the CX marker. Bestie, that's a whole vibe check ๐Ÿ˜ญ

Otherwise, the receiver goes into either the Receive Red-Part state (RCV_RP) or the Receive Green-Part state (RCV_GP), depending on whether the segment was red or green, respectively ๐ŸŒˆ

In RCV_RP, the receiver checks what kind of red DS it got ๐Ÿ‘‘ If it's a regular red data segment, the receiver just pops right back to DS_REC. For red data segments that are marked as CP, and also as CP & EORP, a responding RS segment gets queued up to send back to the sender. Which procedure handles that depends on whether the CP segment was a retransmission (meaning an RS segment matching the checkpoint serial number in the CP segment was already issued before). If yes, it's Retransmit RS (Section 6.8). If no, it's Send Reception Report (Section 6.11). Then the receiver goes back to DS_REC. Now, if the block transmission was fully red and the segment was marked CP, EORP, and EOB, the receiver enters the Wait-for-Red-Part-Reception state (WAIT_RP_REC) ๐Ÿ’œ No matter what, the internal procedure Start RS Timer (Section 6.3) gets followed when the link state cues say the RS segments are starting to transmit.

In RCV_GP, if the green data segment wasn't marked EOB, the receiver goes back to DS_REC. But if it was marked EOB, it moves into WAIT_RP_REC to fully receive the red-part of the block ๐Ÿ“

Now, a previously set RS timer can expire and interrupt the receiver while it's in DS_REC, RCV_RP, RCV_GP, or WAIT_RP_REC. When that happens, the internal procedure Retransmit RS (Section 6.8) runs through the states starting at the RX marker (shown in the second part of the diagram), and then the receiver goes back to whatever state it got interrupted in โฐ

  • Here's the check: the receiver looks at whether the retransmission limit set by network management has been exceeded for the number of RSs sent in the session. If it has, a CR segment with reason-code RLEXC SHOULD be sent to the LTP sender and the sequence marked by the CX marker gets followed. If it hasn't, the RS segment gets queued for retransmission and its RS timer starts through the internal procedure Start RS Timer (Section 6.3), once a link state cue says its transmission has begun ๐Ÿฆ‹

The receiver might also get RA segments from the sender in response to the RS segments it sent while it was in DS_REC. If that happens, the RS timer matching the report serial number in the RA segment gets canceled through the internal procedure Stop RS Timer (Section 6.14) โœจ

The receiver stays in WAIT_RP_REC until the entire red-part of the block has arrived, and only then does it move to CLOSED ๐Ÿซถ While it's in this state, every red-part data segment gets checked to see if its block offset is higher than any green-part data segment received so far. If it is, the internal procedure Handle Miscolored Segment (Section 6.21) runs, the transitions starting at the CX marker get followed, and a CX segment with reason-code MISCOLORED SHOULD be sent to the LTP sender with the Cancellation sequence beginning at the CX marker. Iykyk, and now you do too ๐Ÿ’€

Heads up, this one's a little plot twist ๐ŸŒธ If no red data segments have been received in the session yet, that includes sessions that were fully green, and also the pathological case where the whole red-part of the block gets lost while the green data segment marked EOB still shows up. The receiver has no way to tell whether the session had a red-part transmission at all, so it just assumes the "RP rcvd. fully" condition is true and goes from WAIT_RP_REC straight to CLOSED ๐Ÿงš

Back in WAIT_RP_REC, the receiver might get retransmitted red data segments โœจ When it gets red data segments marked CP, it queues the responding RS segment for transmission. Which procedure runs depends on whether that CP was found to be a retransmission: Retransmit RS (Section 6.8) if yes, or Send Reception Report (Section 6.11) if no. The internal procedure Start RS Timer gets invoked once a link state cue says the RS segment is actually going out. If an RA segment shows up, the RS timer for the report segment it mentions gets canceled, and the receiver just keeps waiting until the whole red-part is in ๐Ÿ’…

Now for the cancel stuff ๐Ÿ™ˆ In the sequence of transitions that start at the CX marker, the CR segment with the right reason-code (which depends on how you got there) gets queued for transmission. The CR timer starts once the link state cue confirms it's actually sending, through the internal procedure Start Cancel Timer (Section 6.15). If the CAR segment comes in from the LTP sender, the receiver goes back to CLOSED through the Cncld marker, using the internal procedure Stop Cancel Timer (Section 6.18). And if the CR timer expires on its own, the internal procedure Retransmit Cancellation Segment (Section 6.16) runs:

  • Okay so the receiver checks whether the retransmission limit set by network management for the number of CR segments per session has been exceeded. If it has, the receiver goes back to CLOSED through the Cncld marker. If it hasn't, a CR segment gets scheduled for retransmission, and its CR timer starts through the internal procedure Start Cancel Timer (Section 6.15) once a link state cue says it's actually transmitting ๐ŸŽ€

Last but not least, the receiver might get a retransmitted CS segment while it's already in CLOSED ๐Ÿ’– That can happen if the CAS segment it sent earlier got lost, or if the CS timer expired too early at the LTP sender. When it does, the CAS gets scheduled for retransmission, and that's the tea โ˜•


9. Security Considerations ๐Ÿ”

9.1. Denial of Service Considerations ๐Ÿ’€

okay bestie, this part is a little scary ๐Ÿ˜ญ but we need it. Implementers SHOULD consider how likely each of these Denial of Service (DoS) attacks is:

  • A fake Cx could be inserted, which brings down a session ๐Ÿ’”
  • Acknowledgment segments (RA, RS, etc.) could be deleted. That makes timers expire and could shut down communication completely if the attacker knows the communications schedule. They could pull this off by DoSing a lower-layer service so it can't send the acknowledgment, or by just jamming the transmission. Both are more likely for terrestrial LTP ๐Ÿ“ก
  • An attacker might corrupt some bits, which is basically the same as deleting that segment ๐Ÿฅฒ
  • An attacker might flood an LTP engine with segments for its internal operations queue, so legitimate data segments can't get sent ๐Ÿšซ
  • An attacker could try to fill up an engine's storage by sending it lots of large messages. In terrestrial LTP applications this could be way more serious, because the extra traffic may not be visible from any network management point ๐Ÿ‘€

If any of the DoS attacks above seem likely, then one or more of these anti-DoS mechanisms ought to be used ๐Ÿ›ก๏ธโœจ

  • Session numbers SHOULD be partly random, which makes it harder to insert valid segments ๐ŸŽฒ
  • An engine that thinks it or its peer is under DoS attack could checkpoint its data segments more often (if it's the sender), or send asynchronous RSs (if it's the receiver). That gets the peer to respond sooner, or lets the engine time out sooner if the attacker never responds ๐Ÿƒโ€โ™€๏ธ
  • Serial numbers (checkpoint serial numbers and report serial numbers) MUST begin each session anew using random numbers, not from 0 ๐ŸŒธ
  • The authentication header [LTPEXT] ๐Ÿ”

9.2. Replay Handling ๐Ÿ”

The following algorithm is given as an example of how an LTP implementation MAY handle replays. It's a cute little recipe ๐Ÿ“

  1. When an LTP segment arrives, check it against a cache for replays. If it's a replay and a pre-cooked response is available (stored the last time this segment was processed), send that pre-cooked response. If there's no pre-cooked response, silently drop the inbound segment. All of this can happen without trying to decode the buffer ๐Ÿง
  2. If the inbound segment doesn't decode correctly, silently drop it. If it decodes properly, add its hash to the replay cache and return a handle to that entry ๐Ÿ”‘
  3. When a pre-cooked response should be stored, store it using the handle from the previous step. These cases include:
    • (a) when the inbound packet is a CP segment, the RS segment sent in response gets stored as pre-cooked,
    • (b) when the Incoming packet is an RS segment, the RA segment is stored as pre-cooked, and
    • (c) when the incoming packet is a Cx segment, the CAx segment sent in response gets stored pre-cooked.
  4. Occasionally clean out the replay cache -- how often this happens is up to the implementation ๐Ÿงน

The downside is that receiving a totally bogus segment still means a replay cache search and an attempted LTP decode. It isn't clear it's possible to do much better, though. An attacker only has to tweak a single bit in the inbound segment each time to get past the replay cache. That's way cheaper than the hash+lookup+decode combo, but also way more expensive than just sending the same octets over and over ๐Ÿ™ƒ

The benefit is that implementers don't have to analyze lots of bugs and attacks based on replayed packets. Combined with LTP authentication, this should defeat a lot of attempted DoS attacks ๐Ÿ’ชโœจ

9.3. Implementation Considerations ๐Ÿ› ๏ธ

SDNV

Implementations SHOULD make sanity checks on SDNV length fields, and SHOULD check that no SDNV field is too long compared with the overall segment length ๐Ÿ“

Implementations SHOULD check that SDNV values are within suitable ranges where possible ๐ŸŽฏ

Byte ranges

Various report and other segments contain offset and length fields. Implementations MUST ensure these are consistent and sane ๐Ÿง

Randomness

Various fields in LTP (for example, serial numbers) MUST be initialized using random values. Good sources of randomness that aren't easily guessable SHOULD be used [ESC05]. Random values can collide because of the birthday paradox. That means a collision is likely after roughly the square root of the space has been seen (for example, 2^16 for a 32-bit random value). Not okay for a protocol, bestie ๐Ÿ˜ฌ

Implementers MUST ensure they use random values that are long enough that the birthday paradox doesn't cause a problem in their environment ๐ŸŒˆ

10. IANA Considerations โœจ

10.1. UDP Port Number for LTP

The UDP port number 1113 with the name "ltp-deepspace" has been reserved for LTP deployments ๐Ÿฆ‹ An LTP implementation may be implemented to operate over UDP datagrams using this port number for study and testing over the Internet.

10.2. LTP Extension Tag Registry

IANA has created and now maintains a registry for known LTP Extension Tags (as indicated in Section 3.1). The registry was populated using the initial values given in Section 3.1 above. IANA may assign LTP Extension Tag values from the range 0x02-0xAF (inclusive) using the Specification Required rule [GUIDE]. The specification can be an RFC (Standards Track, Experimental, or Informational), or a specification from any other standards development organization recognized by IANA or with a liaison with the IESG. That specifically includes CCSDS (http://www.ccsds.org/). Any use of Reserved values (0xB0-0xBF, inclusive) requires an update to this specification ๐Ÿ”’

11. Acknowledgments ๐Ÿซถ

Many thanks to Tim Ray, Vint Cerf, Bob Durst, Kevin Fall, Adrian Hooke, Keith Scott, Leigh Torgerson, Eric Travis, and Howie Weiss for their thoughts on this protocol and its role in Delay-Tolerant Networking architecture. Iconic squad ๐Ÿ‘‘

Part of the research described in this document was carried out at the Jet Propulsion Laboratory, California Institute of Technology, under a contract with the National Aeronautics and Space Administration. This work was performed under DOD Contract DAA-B07-00-CC201, DARPA AO H912; JPL Task Plan No. 80-5045, DARPA AO H870; and NASA Contract NAS7-1407. ๐Ÿš€

Thanks are also due to Shawn Ostermann, Hans Kruse, Dovel Myers, and Jayram Deshpande at Ohio University for their suggestions and advice in making various design decisions. This work was done when Manikantan Ramadas was a graduate student at the EECS Dept., Ohio University, in the Internetworking Research Group Laboratory. ๐ŸŽ“

Part of this work was carried out at Trinity College Dublin as part of the SeNDT contract funded by Enterprise Ireland's research innovation fund. ๐Ÿ‡ฎ๐Ÿ‡ช

12. References ๐Ÿ“š

12.1. Normative References

[B97]    Bradner, S., "Key words for use in RFCs to Indicate
         Requirement Levels", BCP 14, RFC 2119, March 1997.

[GUIDE]  Narten, T. and H. Alvestrand, "Guidelines for Writing an
         IANA Considerations Section in RFCs", BCP 26, RFC 5226, May
         2008.

[LTPMTV] Burleigh, S., Ramadas, M., and S. Farrell,"Licklider
         Transmission Protocol - Motivation", RFC 5325, September
         2008.

[LTPEXT] Farrell, S., Ramadas, M., and S. Burleigh, "Licklider
         Transmission Protocol - Security Extensions", RFC 5327,
         September 2008.

12.2. Informative References

[ASN1]   Abstract Syntax Notation One (ASN.1). ASN.1 Encoding Rules:
         Specification of Basic Encoding Rules (BER), Canonical
         Encoding Rules (CER), and Distinguished Encoding Rules
         (DER). ITU-T Rec. X.690 (2002) | ISO/IEC 8825-1:2002.

[BP]     Scott, K. and S. Burleigh, "Bundle Protocol Specification",
         RFC 5050, November 2007.

[DTN]    K. Fall, "A Delay-Tolerant Network Architecture for
         Challenged Internets", In Proceedings of ACM SIGCOMM 2003,
         Karlsruhe, Germany, Aug 2003.

[ESC05]  D. Eastlake, J. Schiller and S. Crockerr, "Randomness
         Recommendations for Security", RFC 4086, June 2005.

[SACK]   M. Mathis, J. Mahdavi, S. Floyd, and A. Romanow, "TCP
         Selective Acknowledgement Options", RFC 2018, October 1996.

Authors' Addresses ๐Ÿ–Š๏ธ

Manikantan Ramadas
ISRO Telemetry Tracking and Command Network (ISTRAC)
Indian Space Research Organization (ISRO)
Plot # 12 & 13, 3rd Main, 2nd Phase
Peenya Industrial Area
Bangalore 560097
India
Telephone: +91 80 2364 2602
EMail: mramadas@gmail.com

Scott C. Burleigh
Jet Propulsion Laboratory
4800 Oak Grove Drive
M/S: 301-490
Pasadena, CA 91109-8099
Telephone: +1 (818) 393-3353
Fax: +1 (818) 354-1075
EMail: Scott.Burleigh@jpl.nasa.gov

Stephen Farrell
Computer Science Department
Trinity College Dublin
Ireland
Telephone: +353-1-896-1761
EMail: stephen.farrell@cs.tcd.ie

Copyright (C) The IETF Trust (2008).

This document is subject to the rights, licenses and restrictions contained in BCP 78 and at http://www.rfc-editor.org/copyright.html, and except as set forth therein, the authors retain all their rights.

This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM 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.

Intellectual Property ๐Ÿงพ

The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document, or the extent to which any license under such rights might or might not be available. Nor does it represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79.

Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification, can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.

The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org.

๐Ÿ“ฆ where this page comes from