| Internet-Draft | BTPU | October 2026 |
| Taylor | Expires 18 April 2027 | [Page] |
This document defines a protocol for the unidirectional transfer of large binary objects, typically Bundle Protocol version 7 bundles, between two nodes connected by a unidirectional, unreliable, frame-based link-layer protocol, without requiring IP services.¶
The protocol does not require a return path for acknowledgements, but instead supports data repetition as a mechanism to protect against data loss. It fully supports the disaggregation of flows of binary objects of different priority, preventing head-of-line blocking impacting performance.¶
The wire format of the protocol is designed to enable performant implementation in hardware or software, with the aim of enabling protocol implementations to run at the line-rate of the underlying link-layer protocol.¶
This note is to be removed before publishing as an RFC.¶
The latest revision of this draft can be found at https://ricktaylor.github.io/btpu/draft-ietf-dtn-btpu.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-dtn-btpu/.¶
Discussion of this document takes place on the Delay/Disruption Tolerant Networking Working Group mailing list (mailto:dtn@ietf.org), which is archived at https://mailarchive.ietf.org/arch/browse/dtn/. Subscribe at https://www.ietf.org/mailman/listinfo/dtn/.¶
Source for this draft and an issue tracker can be found at https://github.com/ricktaylor/btpu.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 18 April 2027.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
Bundle Protocol version 7 (BPv7) is defined in terms a layered logical architecture, detailed in [RFC9171], wherein the responsibility for the storing and routing of bundles lies with the Bundle Processing Agent (BPA), and the BPA relies upon Convergence Layer Protocols (CLAs) to provide bundle transport between nodes. CLAs provide a unified interface to the BPA, allowing BPAs to be link-layer agnostic, but still use a diverse range of Convergence Layer Protocols (CLPs) to transfer bundles between BPAs over underlying link-layer protocols.¶
In the realm of near- and deep-space communication there are a number of standardized link-layer protocols, including [USLP], [TM], [AOS], [DVB-S2X], that share a set of common properties:¶
They are unidirectional: data transfer occurs in one direction only, there is no in-band return path for data.¶
They are frame-based: the link-layer protocol will guarantee that a frame of data is either delivered to a receiver in its entirety or not at all. Frames can be of fixed or variable length.¶
They provide a single logical channel: the communication between a sender and one or more receivers of frames can be logically separated from other communication over the link-layer by an implementation, perhaps by the use of channel identifiers, circuit identifiers, or tuples of source and destination address information.¶
These characteristics provide a common baseline that allows the definition of a lightweight mechanism for transferring BPv7 bundles meeting the requirements of a BPv7 Convergence Layer Protocol, and this document describes such a protocol: Bundle Transfer Protocol - Unidirectional (BTPU), suitable for implementation over any link-layer protocol that shares these characteristics. The protocol is applicable to other link-layer technologies which share these characteristics beyond those commonly used for space communication, for example 5G Unstructured PDUs [_5G], or Ethernet [IEEE.802.3], without requiring underlying IP services. Although designed for any link-layer protocol that shares the characteristics above, additional specification or profiling might be required to map the constructs of the link-layer protocol to the mechanisms defined in this specification.¶
+----------------------+ | DTN Application | +----------------------+ | BPv7 / BPv6 | +----------------------+ | BTPU | +----------------------+ | Link-layer Protocol | +----------------------+
The driving use-case of the protocol has been the transfer of BPv7 Bundles, however it is equally capable of transferring any kind of binary data, but includes no explicit discriminator of the format of a particular block of binary data. If multiple different types of binary data are to be transferred by a single implementation, this specification considers the differentiation between different types of binary data to be a matter for the implementation. For example, both BPv6 Bundles ([RFC5050]) and BPv7 Bundles can be multiplexed without issue, as the different formats can be distinguished by simple examination of the initial octets of a received bundle by an implementation. Additionally, the segmentation mechanism enables the use of this protocol with binary data formats that do not natively support some form of fragmentation.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
Within the scope of this document, the following terms have specific meaning:¶
A higher-layer protocol data unit, typically a BPv7 Bundle as defined in [RFC9171].¶
The protocol data unit, excluding any link-layer protocol specific headers or metadata, that makes up a complete transmission unit or frame, as defined by the link-layer protocol specification.¶
In order to transfer a Bundle larger than a Link-layer PDU, Bundles can be subdivided into Segments in order to fit within a Link-layer PDU, see Section 4.¶
The context, identified by a Session ID announced by the sender in a Session Start Message (Section 8.2), within which Transfer numbers are meaningful, see Section 5.1.¶
The context in which the transmission of the Segments of a single Bundle occurs, see Section 4.¶
One of the Transfer Segment (Section 8.4), Transfer End (Section 8.5), and Transfer Cancel (Section 8.6) Messages, which carry the Transfer number of the Transfer with which they are associated, or any other Message that another specification defines to be a Transfer Message.¶
The purpose of the protocol is to transfer a series of Bundles between two nodes. Because a Bundle is of variable length, which is unlikely to be exactly the same size as a Link-layer PDU, the protocol defines a mechanism to divide Bundles into Segments as required, such that each Link-layer PDU is efficiently filled with data, and one or more Bundles can be transferred in a minimal number of Link-layer PDUs, described in more detail in Section 4.¶
This segmentation is unrelated to BPv7 bundle fragmentation as defined in Section 5.8 of [RFC9171]. Although BPv7 bundle fragmentation can be used to sub-divide oversized BPv7 bundles, the required duplication of metadata blocks can result in inefficiencies or fail to generate BPv7 bundle fragment small enough to fit in a single Link-layer PDU.¶
As a sender can prioritize the transfer of each Bundle differently, the protocol allows for the multiplexing of Bundle transfers, so that the transfer of higher priority Bundles can interrupt the transfer of other Bundles, avoiding "head of line blocking", see Section 4.1 for more detail. The bundle transfers are expected to occur over the same logical channel, rather than using a separate channel for each bundle or group of bundles that share priority. This does not preclude using multiple logical channels, but each channel is expected to be an independent instance of the protocol.¶
The basic primitive of the protocol is the Message, a self-describing unit of protocol control information of variable length. The sender is responsible for composing one or more Messages as required, and packing them into a Link-layer PDU, such that a single PDU is optimally filled. The receiving node parses the contained Messages from each received Link-layer PDU, and then processes them as individual control signals. This sequence of Messages is the logical control-plane used by the protocol. This document uses the verb "emit" to describe to the writing of a new Message to a Link-layer PDU ready for transmission, to differentiate from the the transmission of the Link-layer PDU itself, as many Messages can be emitted prior to the transmission of the containing PDU.¶
Because the size of a Bundle is not expected to exactly match the size of a Link-layer PDU, an implementation will likely need to add padding to the PDU so that the Link-layer PDU size requirements are met. Two Messages are available for this purpose: The Definite Padding Message (Section 8.7) and the Indefinite Padding Message (Section 8.8). Padding Messages are valid at any point within a Link-layer PDU.¶
It is RECOMMENDED that implementations use the Definite Padding Message to add padding to a Link-layer PDU, except when less than four octets of padding are required, as the minimum length of the Definite Padding Message is four octets.¶
When the link-layer protocol provides variable length Link-layer PDUs, implementations SHOULD take into account the mechanisms used by the link-layer protocol to support variable length Link-layer PDUs, and emit Link-layer PDUs of a suitable size for the underlying protocol. For example, if variable length Link-layer PDUs are implemented by the link-layer protocol using a sub-framing mechanism, then emitting Link-layer PDUs of a single, or whole number of sub-frames can increase reliability.¶
The algorithm used to pad and pack Messages efficiently into Link-layer PDUs is an implementation matter.¶
As described in the Protocol Overview (Section 3), in order to transfer Bundles larger than a single Link-layer PDU into multiple PDUs, Bundles are be divided into a sequence of Segments by the sender and each Segment is emitted in its own a Message. However, a complete Bundle that can fit in the next Link-layer PDU can instead be transferred without segmentation, see the Bundle Message (Section 8.1).¶
Each Segment is assigned a monotonically increasing integral Segment Index that indicates the relative position of the Segment within the total sequence of Segments, with zero (0) indicating the first segment; i.e. Segments are ordered 0 to N, where N is the Segment Index in the Transfer End Message.¶
The Segments of a Bundle, other than the final Segment, MUST be emitted by the sender as a series of Transfer Segment Messages (Section 8.4) carrying the same Transfer identifier, starting with Segment Index zero (0). The end of a transfer MUST be indicated by emitting a Transfer End Message (Section 8.5), including the index and data of the final Segment. A Transfer always consists of at least two Segments, as a Bundle that would fit in a single Segment is transferred in a Bundle Message (Section 8.1) instead.¶
In addition to a Segment Index, every Segment is associated with a Transfer that provides context to the sequence of Segments to enable the correct reassembly of the original Bundle. Each Transfer is assigned a number as an identifier, with each identified Transfer mapping to the segmentation of a single Bundle.¶
Transfer numbers are expressed as 32-bit unsigned integers. A sender MAY choose any value for the first Transfer number of a Session (Section 5.1), and each subsequent Transfer MUST use the next numeric value in the sequence. To avoid placing a limit on the total number of Transfers between peers, numbers are allowed to "roll-over" to zero and repeat, i.e. the next number in the sequence is the previous number incremented by one, modulo 2^32.¶
A receiver reassembles the transferred Bundle by concatenating the Segments that share a common Transfer number in the ascending order of their Segment Index. The Segment Index in the Transfer End Message indicates the final Segment Index (N); a transfer is complete when Segments with indices 0 through N have been received. Once all the Segments have been received and concatenated, a receiver is expected to pass the recombined Bundle to an upper layer for further processing. A receiver MUST NOT commit resources for reassembly on the basis of values declared by the sender, such as the Segment Index of a Transfer End Message or a Bundle Length Hint (Section 9.1), beyond its own local limits.¶
In order to support the transmission of Bundles with different priorities, Transfer Messages associated with different Transfers, i.e. with different Transfer numbers, MAY be interleaved. This allows senders to interrupt the emission of a sequence of Segments associated with one Transfer with one or more Segments of another Transfer, preventing a large lower priority Transfer blocking a higher priority Transfers.¶
A Transfer can be aborted by the sender while a Transfer is in progress by emitting a Transfer Cancel Message (Section 8.6) containing the identifier of the Transfer to cancel. A Transfer is also considered cancelled when its Transfer number leaves the receiver's Transfer Window (Section 5), or when a new Session (Section 5.1) starts or the current Session ends. A receiver MAY also consider any Transfer cancelled in order to protect its resources, for example to enforce local limits on reassembly memory, on the size of a Bundle, or on the time for which a Transfer can remain incomplete. When a Transfer is cancelled, a receiver MUST discard any Segments of the Transfer already received, and MUST ignore any further Messages associated with the Transfer, so that the Bundle is not delivered to an upper layer unless the Transfer was already complete.¶
Because Messages can be lost in transmission due to the loss of Link-layer PDUs, and a sender MAY emit duplicate Messages as a defense against loss, see Section 6, a sender MUST maintain a sliding Transfer Window that defines the maximum number of Transfers that can be simultaneously in progress. As Transfers are identified by a monotonically increasing number, the size of the Transfer Window also strictly defines the range of identifiers of Transfers in progress.¶
The sender MUST maintain a reference to the greatest Transfer number used in any emitted Transfer Message, and MUST NOT emit any Message with a Transfer number less than or equal to the latest minus the size of the Transfer Window, taking into account the modulo 2^32 roll-over.¶
A receiver applies the algorithm described below to every Transfer Message it receives, except an invalid (Section 7.4) Transfer Message, which is discarded, and any Transfer Message received while the receiver has no current Session (Section 5.1), which MUST be ignored. The algorithm MUST be applied, advancing the Transfer Window if required, before the content of the Message is processed, and the Message MUST be ignored if its Transfer is not then in progress. A Transfer is in progress at a receiver while its Transfer number is within the receiver's Transfer Window, whether or not any Messages associated with the Transfer have been received.¶
Each receiver MUST maintain a reference to the greatest Transfer number of the current Session, which is initialized when the Session starts, see Section 5.1. When a Transfer Message is received with a Transfer number greater than the greatest previously received, the new Transfer number is considered the greatest Transfer number, and Transfers with number less than or equal to the latest minus the size of the Transfer Window MUST be considered cancelled (Section 4.2). Because of Transfer number roll-over, a Transfer number T is greater than the greatest previously received Transfer number G if (T - G) modulo 2^32 is non-zero and less than 2^31 minus the size of the Transfer Window. This is serial number arithmetic, as defined in [RFC1982] with a SERIAL_BITS value of 32, with the range reduced by the size of the Transfer Window, so that no Transfer number that was within the Transfer Window before an advance of the greatest Transfer number can be considered greater than the new greatest Transfer number. Using half the number space allows a receiver that has experienced a temporary loss of signal to correctly resume processing, distinguishing genuinely new Transfers from those that have wrapped around the number space and are obsolete. Pseudocode for the algorithm is given in Figure 2.¶
The size of the Transfer Window is chosen by the sender, and announced to receivers in the Session Start Message (Section 8.2); a receiver MUST use the announced size for the duration of the Session. The Transfer Window size MUST be at least 4, MUST be less than 2^12, and is RECOMMENDED to be 16. 16 is an arbitrary number, and needs discussing by the WG.¶
var WINDOW_SIZE # Transfer window size, set when the session starts
var GREATEST # Greatest transfer number, set when the session starts
# Function to check if a transfer is in progress
FUNCTION isTransferInProgress(T):
# Ensure Transfer T is within the
# sliding window defined by WINDOW_SIZE
RETURN ((GREATEST - T + 2^32) MOD 2^32) < WINDOW_SIZE
# Function to check if the transfer is considered a "new" transfer
FUNCTION isNewTransfer(T):
IF T = GREATEST THEN
# A repeated Message for the greatest transfer
# is in progress, not new
RETURN FALSE
# Check if the transfer is ahead of GREATEST by less than
# half of the number space, less the window size
RETURN ((T - GREATEST + 2^32) MOD 2^32) <
(2^32 / 2) - WINDOW_SIZE
# Main function, called for every Transfer Message received
# that is not invalid, to manage the sliding window and
# process the Message
FUNCTION processTransferMessage(T):
IF isNewTransfer(T) THEN
# New transfer, update the greatest received transfer number
GREATEST ← T
# Cancel transfers that are now outside the window
CANCEL_OUTDATED_TRANSFERS()
IF isTransferInProgress(T) THEN
# Transfer is in progress, continue handling it
CONTINUE_PROCESSING(T)
ELSE
# Transfer is not in progress (outside the window),
# ignore it
IGNORE_MESSAGE(T)
Transfer numbers, and the state a receiver holds for each Transfer, are only meaningful within a Session. A sender starts a Session by emitting a Session Start Message (Section 8.2), which carries a Session ID that identifies the Session, the Transfer number of the next Transfer the sender will start, and the size of the sender's Transfer Window, which MUST NOT change during the Session.¶
A sender MUST start a new Session each time it starts or restarts, and MUST emit a Session Start Message before any Transfer Message of the Session, either earlier in the same Link-layer PDU or in an earlier Link-layer PDU. A sender MAY also start a new Session at other times, for example to change the size of its Transfer Window, but doing so causes receivers to cancel any Transfers in progress. A sender SHOULD choose the Session ID of each new Session at random, so that it differs from the Session ID of any previous Session with high probability, without requiring the sender to retain state across restarts.¶
As the Transfer Messages of a new Session could be misinterpreted by a receiver that has not received its Session Start Message, a sender SHOULD repeat the Session Start Message in several Link-layer PDUs at the start of a Session, each time preceding any Transfer Messages in the same PDU. A sender SHOULD also emit a Session Start Message periodically throughout the Session, so that a receiver that missed the start of the Session, for example because it started or restarted after the sender, can join the Session; such Messages can often be emitted in space in a Link-layer PDU that would otherwise be filled with padding. The Next Transfer Number in a Session Start Message reflects the state of the sender when the Message is emitted, so a Session Start Message emitted later in a Session is not necessarily an exact copy of an earlier one.¶
On receipt of a Session Start Message, a receiver MUST ignore the Message if it carries the Session ID of the receiver's current Session, or of the Session that the receiver most recently saw end with a Session End Message (Section 8.3), as the Message is then a repetition. Otherwise, the receiver MUST start the new Session: it considers all Transfers of any previous Session cancelled (Section 4.2); adopts the Session ID and Transfer Window size carried in the Message; and sets its greatest Transfer number to the Next Transfer Number minus one, modulo 2^32, so that the next Transfer started by the sender is considered new. As Transfer numbers are only meaningful within a Session, any Transfer Message subsequently received is associated with a Transfer of the new Session, even if its Transfer number matches that of a Transfer of a previous Session.¶
As a receiver ignores any Session Start Message for its current Session, it only processes the Hint Items (Section 7.2) of the Session Start Message that started the Session. Hint Types valid in the Session Start Message therefore SHOULD carry information that does not change during a Session.¶
A sender MAY end a Session gracefully, for example before shutting down, by emitting a Session End Message (Section 8.3) carrying the Session ID of the Session. A sender MUST NOT emit any Transfer Message of a Session after emitting a Session End Message for it, and SHOULD emit the Session End Message only after the last Messages of the Session, including any repetitions, that it intends receivers to process. As Link-layer PDUs can be lost, a sender SHOULD repeat the Session End Message in several Link-layer PDUs.¶
On receipt of a Session End Message carrying the Session ID of its current Session, a receiver MUST consider all Transfers of the Session cancelled (Section 4.2), and then has no current Session, so that it ignores Transfer Messages until a new Session starts. A receiver MUST ignore a Session End Message carrying any other Session ID. A receiver that receives no Session End Message, for example because every copy was lost, retains the state of the Session until a new Session starts, or until it cancels Transfers to protect its resources.¶
A Session Start Message from a previous Session that is received after one from the current Session, for example due to the reordering of Link-layer PDUs, causes a receiver to restart the previous Session, cancelling the Transfers in progress of the current Session, until it receives a further Session Start Message of the current Session. This is expected to be rare, as it requires Link-layer PDUs emitted before a sender restart to be delivered after those emitted following it.¶
Due to the unreliable nature of the link-layer protocol, Link-layer PDUs can be lost in transmission, resulting in the loss of the contained Messages. Because the underlying link-layer is assumed to be unidirectional, the protocol does not include a mechanism to trigger the retransmission of lost Messages; instead the protocol allows the sender to repeat the transmission of Messages.¶
A sender MAY emit any Message multiple times in different Link-layer PDUs. Although every Link-layer PDU transmitted MAY contain different Messages, any repeated Message MUST be an exact copy of an already emitted Message. A receiver MAY ignore any duplicate Message already received for an in-progress Transfer, and MUST ignore any Message associated with a Transfer that it has already completed, so that a Bundle is not delivered to an upper layer more than once. When segmenting bundles, not all Messages in a Transfer need be repeated the same number of times, and different Transfers can repeat Messages differently.¶
Although it is RECOMMENDED that segments are emitted in ascending order of Segment Index; once emitted, any Message MAY be repeated any number of times, in any order. The number of repetitions of a particular Message is an implementation matter that can be influenced by many factors, including:¶
Offline analysis of the deployed environment might require a certain amount of Message repetition to reach some required certainty of transfer.¶
A higher 'reliability' factor associated with a particular Bundle could result in more copies of each associated Transfer Message being emitted.¶
Signalling from the link-layer protocol, or some other out-of-band mechanism, might trigger increased repetition of a subset of Messages, to protect against some temporary spike in Link-layer PDU loss rate.¶
Message replication is logically separate from any facilities the underlying link-layer protocol might have to protect against information loss through redundancy and/or erasure coding, and MAY be used as required by a deployment. If a link-layer protocol receives a duplicate Link-layer PDU, it SHOULD be delivered to this protocol only once.¶
All protocol Messages except the Indefinite Padding Message (Section 8.8) follow the common "Type-Length-Value" formatting pattern, with each Message being identified by a four octet header that encodes the type of the Message, and the length of the content of the Message.¶
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Flags | Length (20-bit unsigned int) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ... Optional Hint Items ... : +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ... Content ... : +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+¶
The type of the Message, allocated from IANA "BTPU Message Types" registry, see Section 12, encoded as a 8-bit unsigned integer in network byte order.¶
A 4-bit field for flags, see Section 7.1.¶
The length of the Message in octets, excluding the 4 octets of the header itself, encoded as a 20-bit unsigned integer in network byte order. This length includes both the optional Hint Items (Section 7.2) and the Content.¶
A sequence of octets of data. Its length is the main Message Length minus the total length of any present Hint Items. The content is encoded according to the Type of the Message.¶
The Message Flags field is a 4-bit 4 bits is considered enough, as it allows a 20-bit Message Length field, and many additional flags could be better expressed with Hint Items. field, formatted as follows:¶
0 1 2 3 +-+-+-+-+ |H| RFU | +-+-+-+-+¶
To allow the transfer of optional additional information, Messages can carry extra information in the form of Hint Items. Because Messages can be lost in transmission, a Hint Item provides additional information about the entity to which the containing Message relates, for example the Transfer of a Transfer Message, the Bundle carried by a Bundle Message, or the Session started by a Session Start Message, rather than information particular to the containing Message itself, and MAY be repeated in multiple different or repeated Messages. The definition of each Hint Type specifies the Message types in which it is valid, and the definition of a Message type can specify additional Hint Types that are valid in it, see Section 7.4.¶
If the 'H' flag is set in the Message header, the header is followed by one or more Hint Items. Each item is encoded in a Type-Length-Value format, with a 2-octet header followed by a variable-length value. This format intentionally omits a flags field to prevent nested metadata.¶
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Hint Type |H| Length | ... Value ... : +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+¶
A 7-bit identifier for the Hint Item, allocated from the "BTPU Hint Types" IANA registry, see Section 12, encoded as a 7-bit unsigned integer in network byte order.¶
The 'H' (Hint) flag. If this bit is set to 1, it indicates that another Hint Item immediately follows this Hint Item. If this bit is set to 0, then the Message content immediately follows the Hint Item.¶
An 8-bit unsigned integer specifying the length of the Value field in octets. This limits the value of a single Hint Item to 255 octets.¶
The payload of the Hint Item.¶
Because all Messages, except the Indefinite Padding Message, follow the common Message format, a Message can be skipped by a receiver without knowledge of its Type-specific semantics. A receiver that parses a Message with a Type value that it does not recognize, other than the value 6 or a value in the range 0x80..0x9F, MUST ignore the Message by skipping the number of octets indicated by the Length field, and continue processing any subsequent Messages in the Link-layer PDU. This applies to every unrecognized Type value, including any allocated in the future from the range reserved for future expansion, allowing Message types defined in future documents to be introduced into deployments where not all receivers have been updated to recognize them.¶
The Type value 6 and Type values in the range 0x80..0x9F indicate that the octets encountered are not a Message at all, but an encapsulated bundle in its native format: 6 is the initial octet of a BPv6 bundle, and 0x80..0x9F are the possible initial octets of the CBOR array of a BPv7 bundle, see Section 12. Both bundle formats are self-delimiting, so a receiver that implements the corresponding format can determine the extent of the bundle, handle it as it would the content of a Bundle Message (Section 8.1), and continue processing any subsequent Messages in the Link-layer PDU. A receiver that does not implement the corresponding bundle format, or that otherwise cannot determine the extent of the bundle, for example because it is malformed, cannot distinguish the end of the bundle from any subsequent Messages or padding, and MUST discard the remainder of the Link-layer PDU, including the bundle. A sender SHOULD therefore encapsulate a Bundle in a Bundle Message (Section 8.1), rather than emitting it in its native format, unless it is known, for example by configuration, that every receiver implements the format of the Bundle.¶
Similarly, a receiver that parses a Hint Item with a Hint Type that it does not recognize MUST ignore the Hint Item by skipping the number of octets indicated by the Hint Item Length field, and continue processing any subsequent Hint Items and the Message Content. Hint Items are therefore only suitable for carrying optional information that can be safely ignored by a receiver.¶
A Message is invalid if:¶
it is truncated, i.e. the Link-layer PDU ends before the end of the four octet Message header, or before the end of the Message as indicated by its Length field;¶
the 'H' flag is set, and its Hint Items extend beyond the end of the Message as indicated by its Length field;¶
its Message Content is too short to contain the fields defined for its Message type, or otherwise does not meet the length requirements defined for its Message type; or¶
the definition of its Message type identifies it as invalid for any other reason.¶
A receiver MUST discard an invalid Message, and continue processing any subsequent Messages in the Link-layer PDU.¶
A Hint Item is invalid if it is carried in a Message of a type in which its Hint Type is not valid, or if it does not meet the other requirements defined for its Hint Type. An invalid Hint Item MUST be ignored by a receiver as if it were an unrecognized Hint Item, and does not make the containing Message invalid.¶
The following standard protocol Messages are defined:¶
The Bundle Message is used to encapsulate an entire Bundle, and SHOULD be used by an implementation when a Bundle will fit in its entirety in a single Link-layer PDU to avoid the overhead of segmentation, and reducing the risk of the total loss of a Bundle if one or more unnecessary segments of a Bundle is lost. A Bundle that is emitted in its entirety in a single Message MUST be emitted in a Bundle Message: a sender MUST NOT emit a Transfer consisting of a single Segment.¶
Because it conveys a complete Bundle, a Bundle Message is not a Transfer: it has no Transfer number and is not subject to the Transfer Window (Section 5), which bounds only the number of segmented Transfers that can be simultaneously in progress. A receiver therefore processes a Bundle Message whether or not a Session (Section 5.1) has started.¶
A Bundle Message has a type of 2. The Message Content MUST be a valid Bundle.¶
Emitting a Bundle Message with a Length field value that indicates no Bundle content (e.g., a length of 0 if no metadata is present) only adds control-plane overhead and SHOULD NOT be used as an alternative form of padding.¶
The Session Start Message is used by a sender to start a Session (Section 5.1), and to announce the parameters of the Session to receivers.¶
A Session Start Message has a type of 7. The Message Content field is formatted as follows:¶
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Session ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Next Transfer Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Transfer Window Size | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+¶
The identifier of the Session, encoded as a 32-bit unsigned integer in network byte order.¶
The Transfer number of the next Transfer the sender will start, at the time the Message is emitted, encoded as a 32-bit unsigned integer in network byte order.¶
The size of the sender's Transfer Window (Section 5) for the Session, encoded as a 16-bit unsigned integer in network byte order.¶
The Message Content of a Session Start Message, excluding any Hint Items, is exactly 10 octets in length. A Session Start Message with Message Content of any other length, or with a Transfer Window Size that does not meet the requirements of Section 5, is invalid, see Section 7.4.¶
The Session End Message is used by a sender to end a Session (Section 5.1) gracefully.¶
A Session End Message has a type of 8. The Message Content field is formatted as follows:¶
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Session ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+¶
The Session ID of the Session that is ending, encoded as a 32-bit unsigned integer in network byte order.¶
The Message Content of a Session End Message, excluding any Hint Items, is exactly 4 octets in length. A Session End Message with Message Content of any other length is invalid, see Section 7.4.¶
The Transfer Segment Message is used to encapsulate a segment of a multi-segment Bundle Transfer.¶
A Transfer Segment Message has a type of 3. The Message Content field is formatted as follows:¶
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Transfer Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Segment Index | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ... Segment Data ... : +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+¶
The numeric identifier of the Transfer that this Segment is part of, encoded as a 32-bit unsigned integer in network byte order.¶
The position of the Segment within the sequence of all Segments of a Transfer, encoded as a 32-bit unsigned integer in network byte order.¶
The octets of a Segment of the Transfer, with the length calculated as the Message content length excluding the eight (8) octets of the Transfer Number and Segment Index.¶
Transfer Segment Messages SHOULD NOT have zero octets of Segment Data, i.e. the total length of the Message SHOULD be greater than 12 octets. Such Messages only add control-plane overhead and SHOULD NOT be used as an alternative form of padding.¶
The Transfer End Message is used to indicate the completion of a multi-segment Bundle Transfer, and encapsulate the final segment.¶
A Transfer End Message has a type of 4. The Message Content field is formatted as follows:¶
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Transfer Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Segment Index | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ... Segment Data ... : +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+¶
The numeric identifier of the in-progress (Section 5) Transfer that is completing, encoded as a 32-bit unsigned integer in network byte order.¶
The Segment Index of the final Segment, encoded as a 32-bit unsigned integer in network byte order.¶
The octets of the final Segment of the Transfer, with the length calculated as the Message content length excluding the eight (8) octets of the Transfer Number and Segment Index.¶
Transfer End Messages SHOULD NOT have zero octets of Segment Data, i.e. the total length of the Message SHOULD be greater than 12 octets. Such Messages only add control-plane overhead and SHOULD NOT be used as an alternative form of padding.¶
As a Transfer always consists of at least two Segments, see Section 8.1, a Transfer End Message with a Segment Index of zero (0) is invalid, see Section 7.4.¶
The Transfer Cancel Message is used to indicate that the indicated Transfer is being aborted, and that any Segments associated with the Transfer, whether received before or after the Transfer Cancel Message, are to be discarded by a receiver, as described in Section 4.2.¶
A Transfer Cancel Message has a type of 5. The Message Content field is formatted as follows:¶
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Transfer Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+¶
The numeric identifier of the in-progress (Section 5) Transfer that is cancelled, encoded as a 32-bit unsigned integer in network byte order.¶
The Message Content of a Transfer Cancel Message, excluding any Hint Items, is exactly 4 octets in length. A Transfer Cancel Message with Message Content of any other length is invalid, see Section 7.4.¶
Like any Transfer Message, a Transfer Cancel Message is processed as described in Section 5, so a Transfer Cancel Message received before any Segment of the Transfer it cancels still cancels the Transfer.¶
The Definite Padding Message is used to add padding to a Link-layer PDU.¶
A Definite Padding Message has a type of 1. Any content it contains has no semantic meaning, and a sender SHOULD set the content to a sequence of zero (0) octets. Receivers MUST ignore any Message content.¶
It is valid for this Message to have no content, i.e. a Length field value of zero (0), adding a total of four (4) octets of padding to the Link-layer PDU.¶
An Indefinite Padding Message has a type of zero (0), and in order to support padding with a minimum total length of one octet, the Message does not include an explicit Length or Content field, and hence has the following layout:¶
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type (0) | ... Padding ... : +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+¶
The type of the Message: zero (0).¶
The Indefinite Padding Message type field is followed by a sequence of zero or more zero (0) octets, ending at the first non-zero octet, or the end of the fixed-length Link-layer PDU. The content of the Message has no meaning, and MUST be ignored by a receiver.¶
Note: When an Indefinite Padding Message terminates with a non-zero octet, the non-zero octet is the first octet of the subsequent Message.¶
The following Hint Items are defined in this document:¶
The Bundle Length Hint Item is used to signal the total length of a bundle that is being transferred in segments. This allows a receiver to pre-allocate memory to reassemble the complete bundle, within the limits described in Section 4.¶
This Hint Item is valid in Transfer Segment and Transfer End Messages.¶
The Hint Item has a Hint Type of 0, and its layout is as follows:¶
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type (0) |H| Length | ... Bundle Length ... : +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+¶
The length of the Bundle Length field. This MUST be one of 1, 2, 4, or 8.¶
The total length of the bundle being transferred, encoded as an unsigned integer in network byte order, with a size corresponding to the Length field.¶
A sender SHOULD choose the smallest possible length that can accommodate the total bundle length. For example, a bundle of 2000 octets should be encoded with a Length of 2, and a Value of 2000 encoded as a 16-bit unsigned integer.¶
This protocol does not define any measures to protect Messages or their content. There might be link-layer mechanisms to protect the transmission of frames against over-hearing and interference, and upper layer mechanisms, such as BPSec defined in [RFC9172], can be used to provide integrity and protection at a higher layer. Therefore transport-layer security is considered out of scope for the protocol, and lower and/or upper layer mechanisms MUST be used to provide security.¶
A receiver commits resources, principally memory, to each Transfer in progress until the Transfer completes or is cancelled. Although the Transfer Window (Section 5) bounds the number of Transfers that can be in progress at once, it does not bound their size or duration: a sender, or any entity able to inject Link-layer PDUs, could start Transfers and never complete them, or declare very large Bundles via a Bundle Length Hint or the Segment Index of a Transfer End Message, in order to exhaust the resources of a receiver. For this reason a receiver is permitted to cancel any Transfer to protect its resources, see Section 4.2, and must not commit resources on the basis of values declared by the sender beyond its own local limits, see Section 4. Limits on the time for which a Transfer can remain incomplete need to take account of the expected duration of disruption of the link.¶
Similarly, an injected Transfer Cancel, Session Start, or Session End Message can cause a receiver to cancel Transfers in progress. Protection against the injection of Link-layer PDUs relies on the link-layer mechanisms described above.¶
The following caveats are to be considered before deploying instances of this protocol:¶
It is unreliable. Although there might be a link-layer protocol mechanism for a receiver to be notified that a frame has been lost in transmission, due to the unidirectional nature of the link-layer there is no in-band return path suitable for higher-layer acknowledgement of transfer success. Any acknowledgement system designed to provide reliability MUST use a logically separate path from receiver back to sender.¶
It does not provide congestion control or signalling. The underlying link-layer is expected to provide an uncontested channel between sender and receivers, and hence such mechanisms are considered to be out of scope. The protocol MUST NOT be deployed in environments where congestion might occur, such as the public Internet, when the underlying link-layer does not provide suitable congestion control.¶
It requires an out-of-band mechanism for configuration. This can either be via pre-placed static configuration, a parallel dynamic control-plane protocol, or some other mechanism beyond the scope of this specification.¶
IANA is requested to create a new registry entitled "BTPU Message Types", in the existing "Bundle Protocol" registry group. The registration procedures for this registry, using terms defined in [RFC8126], is:¶
| Values | Registration Procedure |
|---|---|
| 0..0x6F | Standards Action |
| 0x70..0x7F | Private Use |
| 0xA0..0xFF | Reserved for future expansion |
Specifications defining new Message Types, including any future allocation from the range reserved for future expansion, MUST use the common Message format defined in Section 7, so that receivers that do not recognize the new Type value can process the containing Link-layer PDU as described in Section 7.3.¶
The initial values for the registry are:¶
| Type | Message | Reference |
|---|---|---|
| 0 | Indefinite Padding Message (Section 8.8) | This document |
| 1 | Definite Padding Message (Section 8.7) | This document |
| 2 | Bundle Message (Section 8.1) | This document |
| 3 | Transfer Segment Message (Section 8.4) | This document |
| 4 | Transfer End Message (Section 8.5) | This document |
| 5 | Transfer Cancel Message (Section 8.6) | This document |
| 6 | Reserved to avoid clash with BPv6 | This document |
| 7 | Session Start Message (Section 8.2) | This document |
| 8 | Session End Message (Section 8.3) | This document |
| 0x80..0x9F | Reserved to avoid clash with BPv7 Bundle (CBOR array) | This document |
The initial value of 6 is reserved to ensure that a Link-layer PDU containing a single Bundle Protocol version 6 bundle can be distinguished from BTP-U Messages.¶
IANA is requested to create a new registry entitled "BTPU Hint Types", in the existing "Bundle Protocol" registry group. The registration procedures for this registry, using terms defined in [RFC8126], is:¶
Specifications defining new Hint Types MUST specify the Message types in which the Hint is valid, see Section 7.4.¶
| Values | Registration Procedure |
|---|---|
| 0..0x6F | Standards Action |
| 0x70..0x7F | Private Use |
The initial values for the registry are:¶
| Type | Hint | Reference |
|---|---|---|
| 0 | Bundle Length (Section 9.1) | This document |
IANA is requested to create a new registry entitled "BTPU Message Flags", in the existing "Bundle Protocol" registry group. This registry governs the 4-bit Message Flags field. The registration procedures for this registry, using terms defined in [RFC8126], is Standards Action.¶
The initial values for the registry are:¶
| Bit | Name | Description | Reference |
|---|---|---|---|
| 0 (0x8) | H (Hint) | Indicates presence of Hint Items | This document |
| 1-3 | Unassigned |
Bit 0 is the most significant bit.¶
The following sections has examples of an implementation emitting Bundles into Link-layer PDUs. Although the examples demonstrate the core principles, for example Bundle Segmentation with priority, the algorithm used to pack Messages into Link-layer PDUs is just for example purposes. An implementation can use an alternate algorithm that meets this specification but suits its overall architecture, and where this is applicable is noted in each example.¶
An example of the transmission of three Bundles of varying sizes and equal priority in three Link-layer PDUs is shown in Figure 3.¶
+---------------------------+------------+-----------------+ | Bundle A | Bundle B | Bundle C | +---------------------------+------------+-----------------+ : : : : +----------------------+----+------------+----+------------+---------+ | Transfer 1 | T1 | Complete | T2 | Transfer 2 | Padding | | Segment 0 | S1 | Bundle B | S0 | Segment 1 | | +----------------------+----+------------+----+------------+---------+ : : : : +----------------------+----------------------+----------------------+ | Link-layer PDU N | Link-layer PDU N + 1 | Link-layer PDU N + 2 | +----------------------+----------------------+----------------------+
Bundle A is emitted as two Segments, included in the first and second Link-layer PDU, as Transfer 1. Bundle B fits completely in the second Link-layer PDU, and is therefore emitted without segmentation. Bundle C is emitted as two Segments split between the second and third PDU, but padding is required to fill the third PDU. An alternative algorithm could have selected to not segment Bundle C, but to pad the second PDU and include Bundle C without segmentation in the third PDU, without changing the semantics, as an implementation preference.¶
An example of the transmission of three Bundles of varying sizes and different priority in three Link-layer PDUs is shown in Figure 4.¶
+---------------------------+
| Bundle C | High Priority
+---------------------------+
+--------------+-----------------+
| Bundle A | Bundle B | Low Priority
+--------------+-----------------+
: :
: : :
+--------------+-------+----------------------+----+----------+------+
| Complete | T1 | Transfer 2 | T2 | T1 | Pad |
| Bundle A | S0 | Segment 0 | S1 | S1 | |
+--------------+-------+----------------------+----+----------+------+
: : : :
+----------------------+----------------------+----------------------+
| Link-layer PDU N | Link-layer PDU N + 1 | Link-layer PDU N + 2 |
+----------------------+----------------------+----------------------+
Bundle A is emitted without segmentation, and the Bundle B is segmented to fill the first Link-layer PDU. During the preparation of the next Link-layer PDU high priority Bundle C is queued for emission. Therefore the further emission of Bundle B is paused, and Bundle C is emitted as two Segments, with the third Link-layer PDU containing the second Segments of both Bundle B and C, plus padding. The order of emission of the second Segments of Bundle B and C makes no semantic difference.¶
An example of the transmission of two Bundles of differing required repetition in three Link-layer PDUs is shown in Figure 5.¶
+--------------+
| Bundle A | 2x repetition required
+--------------+
+-------------------------------+
| Bundle B | No repetition required
+-------------------------------+
: :
: :
+--------------+-------+--------------+-------+---------------+------+
| Complete | T1 | Complete | T1 | Transfer 1 | Pad |
| Bundle A | S0 | Bundle A | S1 | Segment 2 | |
+--------------+-------+--------------+-------+---------------+------+
: : : :
+----------------------+----------------------+----------------------+
| Link-layer PDU N | Link-layer PDU N + 1 | Link-layer PDU N + 2 |
+----------------------+----------------------+----------------------+
Bundle A is required by some higher-layer loss protection policy to be repeated twice in two separate Link-layer PDUs. Bundle A does not require additional loss protection, and can therefore be transmitted once. As Bundle A can fit in its entirety in a single Link-layer PDU, it is emitted as a Complete Bundle Message, with Bundle B emitted as a Segment Messages sized to fill the remainder of each PDU. The Complete Bundle Message of Bundle A is repeated in the second Link-layer PDU, with the remainder of the second PDU filled with the next Segment of Bundle B. The third Link-layer PDU contains the last Segment of Bundle B and padding. An alternate implementation could have segmented both Bundles, and repeated the Segments of Bundle A whilst interleaving the Segments of Bundle B.¶
The author would like to thank Erik Kline, Brian Sipos, and Chloe He for their invaluable feedback and discussion of the protocol, and this work would not exist without the excellent prior work by the TCP-CLv4 authors.¶