RFC 5050

Bundle Protocol Specification

๐Ÿ“… published November 2007, from ietf

RFC 5050: Bundle Protocol Specification ๐ŸŽ€

okay so this is RFC 5050, and it's the doc that defines the Bundle Protocol for Delay Tolerant Networking (DTN) ๐Ÿฆ‹

Here's the title block tea โ˜•

  • RFC number: 5050
  • Title: Bundle Protocol Specification
  • Authors: K. Scott (The MITRE Corporation) and S. Burleigh (NASA Jet Propulsion Laboratory)
  • Category: Experimental
  • Date: November 2007
  • Obsoletes / Updates: the header doesn't list anything it obsoletes or updates

Status of This Memo ๐Ÿ“

this memo defines an Experimental Protocol for the Internet community ๐Ÿงช it's not an Internet standard of any kind. The authors are literally asking for discussion and suggestions for improvement, so speak up bestie ๐Ÿ—ฃ๏ธ distribution of this memo is unlimited โœจ

IESG Note ๐Ÿ™ˆ

This RFC is not a candidate for any level of Internet Standard. The IETF disclaims any knowledge of the fitness of this RFC for any purpose, and it specifically notes that the decision to publish was not based on IETF review for things like security, congestion control, or inappropriate interaction with deployed protocols. The RFC Editor chose to publish this document at its discretion. Readers should exercise caution when evaluating its value for implementation and deployment. See RFC 3932 for more information.

Abstract ๐ŸŒˆ

this doc walks through the end-to-end protocol, the block formats, and the abstract service description for swapping messages (called bundles) in Delay Tolerant Networking (DTN) ๐Ÿ’Œ

it was produced inside the IRTF's Delay Tolerant Networking Research Group (DTNRG), and it represents the consensus of all the active contributors in that group. For more info, check http://www.dtnrg.org ๐Ÿซถ

Table of Contents ๐Ÿ—‚๏ธ

   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
   2.  Requirements Notation  . . . . . . . . . . . . . . . . . . . .  4
   3.  Service Description  . . . . . . . . . . . . . . . . . . . . .  5
     3.1.  Definitions  . . . . . . . . . . . . . . . . . . . . . . .  5
     3.2.  Implementation Architectures . . . . . . . . . . . . . . .  9
     3.3.  Services Offered by Bundle Protocol Agents . . . . . . . . 11
   4.  Bundle Format  . . . . . . . . . . . . . . . . . . . . . . . . 11
     4.1.  Self-Delimiting Numeric Values (SDNVs) . . . . . . . . . . 12
     4.2.  Bundle Processing Control Flags  . . . . . . . . . . . . . 13
     4.3.  Block Processing Control Flags . . . . . . . . . . . . . . 15
     4.4.  Endpoint IDs . . . . . . . . . . . . . . . . . . . . . . . 16
     4.5.  Formats of Bundle Blocks . . . . . . . . . . . . . . . . . 17
       4.5.1.  Primary Bundle Block . . . . . . . . . . . . . . . . . 19
       4.5.2.  Canonical Bundle Block Format  . . . . . . . . . . . . 22
       4.5.3.  Bundle Payload Block . . . . . . . . . . . . . . . . . 23
     4.6.  Extension Blocks . . . . . . . . . . . . . . . . . . . . . 24
     4.7.  Dictionary Revision  . . . . . . . . . . . . . . . . . . . 24
   5.  Bundle Processing  . . . . . . . . . . . . . . . . . . . . . . 24
     5.1.  Generation of Administrative Records . . . . . . . . . . . 25
     5.2.  Bundle Transmission  . . . . . . . . . . . . . . . . . . . 26
     5.3.  Bundle Dispatching . . . . . . . . . . . . . . . . . . . . 26
     5.4.  Bundle Forwarding  . . . . . . . . . . . . . . . . . . . . 27
       5.4.1.  Forwarding Contraindicated . . . . . . . . . . . . . . 28
       5.4.2.  Forwarding Failed  . . . . . . . . . . . . . . . . . . 29
     5.5.  Bundle Expiration  . . . . . . . . . . . . . . . . . . . . 29
     5.6.  Bundle Reception . . . . . . . . . . . . . . . . . . . . . 30
     5.7.  Local Bundle Delivery  . . . . . . . . . . . . . . . . . . 31
     5.8.  Bundle Fragmentation . . . . . . . . . . . . . . . . . . . 32
     5.9.  Application Data Unit Reassembly . . . . . . . . . . . . . 33
     5.10. Custody Transfer . . . . . . . . . . . . . . . . . . . . . 34
       5.10.1. Custody Acceptance . . . . . . . . . . . . . . . . . . 34
       5.10.2. Custody Release  . . . . . . . . . . . . . . . . . . . 35
     5.11. Custody Transfer Success . . . . . . . . . . . . . . . . . 35
     5.12. Custody Transfer Failure . . . . . . . . . . . . . . . . . 35
     5.13. Bundle Deletion  . . . . . . . . . . . . . . . . . . . . . 36
     5.14. Discarding a Bundle  . . . . . . . . . . . . . . . . . . . 36
     5.15. Canceling a Transmission . . . . . . . . . . . . . . . . . 36
     5.16. Polling  . . . . . . . . . . . . . . . . . . . . . . . . . 36
   6.  Administrative Record Processing . . . . . . . . . . . . . . . 37
     6.1.  Administrative Records . . . . . . . . . . . . . . . . . . 37
       6.1.1.  Bundle Status Reports  . . . . . . . . . . . . . . . . 38
       6.1.2.  Custody Signals  . . . . . . . . . . . . . . . . . . . 41
     6.2.  Generation of Administrative Records . . . . . . . . . . . 44
     6.3.  Reception of Custody Signals . . . . . . . . . . . . . . . 44

   7.  Services Required of the Convergence Layer . . . . . . . . . . 44
     7.1.  The Convergence Layer  . . . . . . . . . . . . . . . . . . 44
     7.2.  Summary of Convergence Layer Services  . . . . . . . . . . 45
   8.  Security Considerations  . . . . . . . . . . . . . . . . . . . 45
   9.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 47
   10. References . . . . . . . . . . . . . . . . . . . . . . . . . . 47
     10.1. Normative References . . . . . . . . . . . . . . . . . . . 47
     10.2. Informative References . . . . . . . . . . . . . . . . . . 47
   Appendix A.  Contributors  . . . . . . . . . . . . . . . . . . . . 49
   Appendix B.  Comments  . . . . . . . . . . . . . . . . . . . . . . 49

1. Introduction ๐ŸŒธ

okay so this doc describes version 6 of the Delay Tolerant Networking (DTN) "bundle" protocol (BP). DTN is an end-to-end architecture for communicating in and/or through highly stressed environments ๐Ÿฅบ we're talking intermittent connectivity, large and/or variable delays, and high bit error rates. To pull this off, BP sits at the application layer of some number of constituent internets and forms a store-and-forward overlay network ๐Ÿงš

the key capabilities of BP are giving main character energy:

  • Custody-based retransmission
  • Ability to cope with intermittent connectivity
  • Ability to take advantage of scheduled, predicted, and opportunistic connectivity (in addition to continuous connectivity)
  • Late binding of overlay network endpoint identifiers to constituent internet addresses

if you want the vibes and the reasoning behind all this, check out [ARCH] and [SIGC]. [TUT] is a tutorial-level overview of DTN concepts, so start there if you're new ๐Ÿ“

this is an experimental protocol, produced within the IRTF's Delay Tolerant Networking Research Group (DTNRG), and it represents the consensus of all the active contributors to that group. if this protocol gets used on the Internet, IETF standard protocols for security and congestion control should be used ๐Ÿ” literally non-negotiable energy ๐Ÿ’€

BP's spot in the standard protocol stack is shown in Figure 1 ๐Ÿฆ‹ BP uses the "native" internet protocols for communications within a given internet. Quick note: "internet" here is used in a general sense and doesn't necessarily mean TCP/IP. The interface between the common bundle protocol and a specific internetwork protocol suite is called a "convergence layer adapter". Figure 1 shows three distinct transport and network protocols (denoted T1/N1, T2/N2, and T3/N3).

   +-----------+                                         +-----------+
   |   BP app  |                                         |   BP app  |
   +---------v-|   +->>>>>>>>>>v-+     +->>>>>>>>>>v-+   +-^---------+
   |    BP   v |   | ^    BP   v |     | ^    BP   v |   | ^   BP    |
   +---------v-+   +-^---------v-+     +-^---------v-+   +-^---------+
   | Trans1  v |   + ^  T1/T2  v |     + ^  T2/T3  v |   | ^  Trans3 |
   +---------v-+   +-^---------v +     +-^---------v +   +-^---------+
   | Net1    v |   | ^  N1/N2  v |     | ^  N2/N3  v |   | ^  Net3   |
   +---------v-+   +-^---------v +     +-^---------v-+   +-^---------+
   |         >>>>>>>>^         >>>>>>>>>>^         >>>>>>>>^         |
   +-----------+   +-------------+     +-------------+   +-----------+
   |                      |                   |                      |
   |<--- An internet  --->|                   |<--- An internet  --->|
   |                      |                   |                      |

                  Figure 1: The Bundle Protocol Sits at
                the Application Layer of the Internet Model

this doc describes the format of the protocol data units (called bundles) passed between entities taking part in BP communications. Those entities are called "bundle nodes" ๐Ÿซง this doc does not cover:

  • Operations in the convergence layer adapters that bundle nodes use to transport data through specific types of internets. (However, the doc does talk about the services that each adapter must provide at the convergence layer.)
  • The bundle routing algorithm.
  • Mechanisms for populating the routing or forwarding information bases of bundle nodes.

2. Requirements Notation ๐Ÿ“

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 [RFC2119]. Those capitalised words are the ones that carry the real weight, so don't skip them ๐Ÿง

3. Service Description ๐Ÿ’…

3.1. Definitions ๐Ÿ“–

Bundle ๐ŸŽ A bundle is a protocol data unit of the DTN bundle protocol. Each bundle is made of a sequence of two or more "blocks" of protocol data, and those blocks serve various purposes. Multiple instances of the same bundle (the same unit of DTN protocol data) might exist at once in different parts of a network, possibly in different representations, in the memory of one or more bundle nodes and/or in transit between nodes. From the point of view of a bundle node, a bundle is an instance of some bundle in the network that is in that node's local memory.

Bundle payload ๐Ÿ’Œ A bundle payload (or simply "payload") is the application data whose delivery to the bundle's destination is the reason the bundle is sent. The terms "bundle content", "bundle payload", and "payload" are used interchangeably in this document. The "nominal" payload for a bundle forwarded in response to a bundle transmission request is the application data unit whose location is given as a parameter to that request. The nominal payload for a bundle forwarded in response to reception of that bundle is the payload of the received bundle.

Fragment โœ‚๏ธ A fragment is a bundle whose payload block contains a fragmentary payload. A fragmentary payload is either the first N bytes or the last N bytes of some other payload (either a nominal payload or a fragmentary payload) of length M, such that 0 < N < M.

Bundle node ๐Ÿงšโ€โ™€๏ธ A bundle node (or, in the context of this document, simply a "node") is any entity that can send and/or receive bundles. In the most familiar case, a bundle node runs as a single process on a general-purpose computer, but the definition is meant to be broader. A bundle node might instead be a thread, an object in an object-oriented operating system, a special-purpose hardware device, and so on. Each bundle node has three conceptual components, defined below: a "bundle protocol agent", a set of zero or more "convergence layer adapters", and an "application agent".

Bundle protocol agent ๐Ÿงš Okay bestie, the BPA is the node component that offers the BP services and runs the bundle protocol procedures. How it does that is wholly an implementation matter ๐Ÿ’…. It could be coded into each node on its own, or be a shared library that a bunch of bundle nodes on one computer all use, or a daemon that nodes call through inter-process or network communication, or even hardware. Totally up to whoever builds it โœจ

Convergence layer adapters ๐Ÿฆ‹ A CLA sends and receives bundles on behalf of the BPA by using the services of some 'native' internet protocol that's supported in one of the internets the node is functionally located in. The way a CLA sends and receives is wholly an implementation matter, exactly like the BPA ๐Ÿซถ

Application agent ๐ŸŒธ The AA is the node component that uses the BP services to get communication done for some purpose. It has two elements: an administrative element and an application-specific element. The application-specific element builds, requests transmission of, accepts delivery of, and processes application-specific application data units, and the only way it talks to the BPA is through the BP service interface ๐Ÿ’œ The administrative element builds and requests transmission of administrative records (status reports and custody signals), and it accepts delivery of and processes any custody signals the node receives. On top of the BP service interface, there's also a (conceptual) private control interface between the BPA and the administrative element, so each one can tell the other to take action under specific circumstances. ๐ŸŽ€

If a node is just acting as a "router" in the overlay network, the AA might not have an application-specific element at all ๐ŸŒˆ Other nodes' application-specific elements can do arbitrarily complex stuff, maybe even offering multiplexed DTN communication services to a bunch of other applications. Same as the BPA, how the AA does its job is wholly an implementation matter. The administrative element could be built right into the library, daemon, or hardware that runs the BPA, and the application-specific element could be software or hardware. Iconic flexibility, no cap ๐Ÿ‘‘

Bundle endpoint ๐Ÿ“ A bundle endpoint (or just "endpoint") is a set of zero or more bundle nodes that all identify themselves for BP purposes using one single text string, called a "bundle endpoint ID" (or, in this doc, just "endpoint ID"; we get into endpoint IDs in detail in Section 4.4 below) โœจ An endpoint that never has more than one node is a "singleton" endpoint, and every bundle node has to be a member of at least one singleton endpoint ๐Ÿ”ฅ Singletons are the most familiar kind, but the endpoint idea is meant to be way broader. Like, the nodes in a sensor network could all share one common endpoint ID and form a single bundle endpoint, which is literally so cool ๐Ÿงš Also, note that a single bundle node can identify itself with multiple endpoint IDs, which means it can be in multiple bundle endpoints at once ๐Ÿ’…

Forwarding ๐Ÿ’– When a node's BPA decides a bundle needs to be "forwarded" to an endpoint, it sends the bundle to all the nodes the BPA currently believes are in that endpoint's "minimum reception group." The minimum reception group can be any one of these:

  • (a) ALL of the nodes registered in an endpoint that's allowed to have multiple nodes. Forwarding to it is kind of like "multicast" in the Internet, though it might be super different under the hood ๐Ÿฆ‹
  • (b) ANY N of the nodes registered in an endpoint that's allowed to have multiple nodes, where N is anywhere from zero up to the endpoint's cardinality. Forwarding here is kind of like "anycast" in the Internet ๐ŸŒธ
  • (c) THE SOLE NODE registered in a singleton endpoint. Forwarding here is kind of like "unicast" in the Internet ๐ŸŽ€

You can figure out the minimum reception group from the endpoint's ID (again, see Section 4.4 below) ๐Ÿ‘‘ For some endpoint ID "schemes," it's fixed, in a way the scheme defines, for every endpoint under that scheme. For other schemes, it's shown by some lexical feature of the "scheme-specific part" of the endpoint ID, in a way the scheme defines too ๐ŸŒˆ


Registration ๐Ÿซถ A registration is the state machine that describes a given node's membership in a given endpoint. Lots of registrations can be linked to one endpoint at the same time, and lots can be linked to one node at the same time ๐Ÿ’œ Any single registration has to be in one of two states at any time: Active or Passive. Every registration also has a "delivery failure action," which is what happens when a bundle that's "deliverable" (see below) under that registration shows up while the registration is Passive. The delivery failure action has to be one of these:

  • defer "delivery" (see below) of the bundle under this registration until (a) this bundle is the least recently received of all bundles currently deliverable under this registration and (b) either the registration gets polled or the registration is in the Active state; or
  • "abandon" (see below) delivery of the bundle under this registration.

A registration can also optionally have an extra implementation-specific delivery deferral procedure attached ๐Ÿ”ฅ While the registration is Active, getting a deliverable bundle must make it get delivered automatically once it's the least recently received bundle that's currently deliverable under the registration. While the registration is Passive, getting a deliverable bundle must make its delivery either abandoned or deferred, whichever the registration's current delivery failure action says. If it's deferred, then any extra deferral procedure attached to the registration has to run too ๐Ÿงš

Delivery ๐Ÿ“ When a bundle gets sent to a node, what happens next depends on whether the receiving node is registered in the bundle's destination endpoint. If it is, and the bundle's payload is non-fragmentary (which could happen because payload reassembly from fragmentary payloads worked, including the original payload of the bundle that came in), then the bundle is normally "delivered" to the node's AA under the registration that describes the node's membership in that endpoint โœจ A bundle counts as delivered at a node under a registration as soon as the application data unit that's the payload, along with the value of the bundle's "Acknowledgement by application is requested" flag and any other relevant metadata (which is an implementation matter, bestie), has been handed to the node's AA in a way that matches the registration's state and, where it applies, its delivery failure action ๐Ÿ’…

Deliverability, Abandonment ๐Ÿ’œ A bundle is "deliverable" under a registration if and only if (a) the bundle's destination endpoint is the endpoint the registration is linked to, (b) the bundle hasn't been delivered under this registration yet, and (c) delivery of the bundle under this registration hasn't been abandoned ๐Ÿ˜ญ To "abandon" delivery of a bundle under a registration just means declaring it no longer deliverable under that registration. Normally, only a registration's delivery failure action causes an abandonment ๐Ÿ™ˆ

Deletion, Discarding ๐ŸŒธ A BPA "discards" a bundle by just ceasing all operations on it and functionally erasing every reference to it. The exact steps for that are an implementation matter ๐Ÿฆ‹ Bundles get discarded silently, meaning discarding one does not create an administrative record. "Retention constraints" are bits of the bundle state that stop a bundle from being discarded, so a bundle can't be discarded while it has any retention constraints ๐Ÿ”ฅ A BPA "deletes" a bundle when some anomalous condition happens. It does that by notifying the bundle's report-to endpoint about the deletion (only if that notification is warranted, see Section 5.13 for the details) and then arbitrarily removing all of the bundle's retention constraints, which makes it discardable ๐Ÿ’€

Transmission ๐ŸŽ€ A transmission is a sustained effort by a node's BPA to get a bundle sent to all the nodes in the minimum reception group of some endpoint. That endpoint could be the bundle's destination or an intermediate forwarding endpoint. It happens in response to a transmission request from the node's AA ๐Ÿ‘‘ A BPA can have any number of transmissions going at once, periodt ๐ŸŒˆโœจ

Okay so, custody ๐ŸŽ€ is basically a promise. When you accept custody of a bundle, you're agreeing to keep a copy and maybe send it again if needed, until that custody gets "released" ๐Ÿ’…. For a bundle headed to a singleton endpoint, custody gets released when (a) you hear that some other node has accepted custody of the same bundle, (b) you hear the bundle was delivered to the (sole) node registered in its destination endpoint, or (c) the bundle gets explicitly deleted for some reason, like its lifetime expiring โณ. Bundles going to a non-singleton endpoint? The spec doesn't define when custody can be released for those ๐Ÿคทโ€โ™€๏ธ. To refuse custody just means deciding not to take custody of the bundle ๐Ÿ™…โ€โ™€๏ธ. A "custodial node" is a node that has accepted custody and hasn't released it yet ๐Ÿซถ. And a "custodian" is a singleton endpoint whose only member is one of the bundle's custodial nodes โœจ.

3.2. Implementation Architectures

Okay this part is so cool ๐Ÿงš. The definitions above are written so the protocol operations don't lock you into one particular implementation architecture ๐Ÿฆ‹. Four example architectures are described below to show the range of interoperable models that could conform to this spec ๐ŸŒˆ.

  1. Bundle protocol application server ๐Ÿ’–

A single bundle protocol application server, which is one bundle node, runs as a daemon process on each computer. The daemon does everything: all the bundle protocol agent functions, all convergence layer adapters, and both the administrative and application-specific parts of the application agent ๐Ÿ”ฅ. The application-specific part works as a server over a local area network. It answers remote procedure calls from application processes (on the same computer and/or remote computers) that need to talk over the bundle protocol ๐Ÿ“ก. To support its clients, the server creates a new (conceptual) node for each one and registers each node in a client-specified endpoint. These conceptual nodes act as the clients' bundle protocol service access points ๐ŸŽ€.

  1. Peer application nodes ๐Ÿ‘ฏโ€โ™€๏ธ

Any number of bundle protocol application processes, each one being a single bundle node, run in an ad-hoc way on each computer โœจ. The bundle protocol agent functions, all convergence layer adapters, and the administrative part of the application agent come from a library that each node process gets dynamically linked to at run time ๐Ÿ’œ. The application-specific part of each node's application agent is node-specific application code ๐Ÿ’….

  1. Sensor network nodes ๐ŸŒธ

Every node in the sensor network is a self-contained implementation of a single bundle node ๐Ÿค–. All bundle protocol agent functions, all convergence layer adapters, and the administrative part of the application agent are built in simplified form into Application-Specific Integrated Circuits (ASICs) ๐Ÿ”Œ. The application-specific part of each node's application agent runs on a programmable microcontroller ๐Ÿง . Forwarding is pretty basic: every bundle goes out on a hard-coded default route ๐Ÿ›ค๏ธ.

  1. Dedicated bundle router ๐Ÿ‘‘

Each computer is a single bundle node that does one job: high-performance bundle forwarding ๐Ÿš€. Lots of the standard bundle protocol agent functions, the convergence layer adapters, and the administrative part of the application agent are in ASICs, but some functions run on a high-speed processor so they can be reprogrammed when needed ๐Ÿ”ง. The node's application agent has no application-specific part ๐Ÿ™ˆ. It gets substantial non-volatile storage, and arbitrarily complex forwarding algorithms are supported ๐Ÿ“.

3.3. Services Offered by Bundle Protocol Agents

The bundle protocol agent of each node is expected to offer these services to the node's application agent ๐Ÿ’โ€โ™€๏ธ:

  • commencing a registration (registering a node in an endpoint) ๐ŸŽŸ๏ธ
  • terminating a registration ๐Ÿ›‘
  • switching a registration between Active and Passive states ๐Ÿ”„
  • transmitting a bundle to an identified bundle endpoint ๐Ÿ“ฆ
  • canceling a transmission โŒ
  • polling a registration that is in the passive state ๐Ÿ—ณ๏ธ
  • delivering a received bundle ๐Ÿ’Œ

4. Bundle Format ๐Ÿ“ฆโœจ

Okay the bundle format is where it gets really serious ๐Ÿ˜ค. Each bundle SHALL be a concatenated sequence of at least two block structures. The first block in the sequence MUST be a primary bundle block, and no bundle MAY have more than one primary bundle block ๐Ÿซถ. Additional bundle protocol blocks of other types MAY follow the primary block to support extensions to the bundle protocol, such as the Bundle Security Protocol [BSP] ๐Ÿ”. At most one of the blocks in the sequence MAY be a payload block ๐ŸŽ. The last block in the sequence MUST have the "last block" flag (in its block processing control flags) set to 1. For every other block in the bundle after the primary block, this flag MUST be set to zero ๐Ÿšฉ.

4.1. Self-Delimiting Numeric Values (SDNVs)

The bundle protocol is designed to balance two goals: using as little transmission bandwidth as possible, while also staying ๐Ÿงƒ:

  • extensible, so it can handle requirements nobody has identified yet, and
  • scalable across a wide range of network sizes and payload sizes ๐Ÿ“ˆ.

The big strategic move here is self-delimiting numeric values (SDNVs) ๐ŸŒŸ. The SDNV encoding is closely adapted from the Abstract Syntax Notation One Basic Encoding Rules for subidentifiers within an object identifier value [ASN1] ๐Ÿงฉ. An SDNV is a numeric value encoded in N octets. The last octet has its most significant bit (MSB) set to zero, and the MSB of every other octet in the SDNV MUST be set to 1 ๐ŸŽฏ. The value is the unsigned binary number you get by joining the 7 least significant bits of each octet of the SDNV into one bit string ๐Ÿงฎ.

Here are some examples of the encoding for different hexadecimal values ๐Ÿ‘€:

0xABC  : 1010 1011 1100
         is encoded as
         {1 00 10101} {0 0111100}
         = 10010101 00111100

0x1234 : 0001 0010 0011 0100
       =    1 0010 0011 0100
         is encoded as
         {1 0 100100} {0 0110100}
         = 10100100 00110100

0x4234 : 0100 0010 0011 0100
       =  100 0010 0011 0100
         is encoded as
         {1 000000 1} {1 0000100} {0 0110100}
         = 10000001 10000100 00110100

0x7F   : 0111 1111
       =  111 1111
         is encoded as
         {0 1111111}
         = 01111111

                       Figure 2: SDNV Example
Care must be taken to make sure that the value to be encoded is (in concept) padded with high-order zero bits to make its bitwise length a multiple of 7 before encoding ๐Ÿง. Also, while there is no theoretical limit on the size of an SDNV field, the overhead of the SDNV scheme is 1:7, meaning one bit of overhead for every 7 bits of actual data ๐Ÿ’€. So 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, with one octet holding the high-order bit of the value padded with six leading zero bits, followed by nine octets holding the remaining 63 bits of the value ๐Ÿคฏ. Encoding a 1024-bit RSA encryption key directly in an SDNV would use up 148 bits of overhead ๐Ÿ˜ญ. In general, an N-bit quantity with no leading zeroes is encoded in an SDNV occupying ceil(N/7) octets, where ceil is the integer ceiling function ๐Ÿง .

Implementations of the bundle protocol MAY handle as an invalid numeric value any SDNV that encodes an integer larger than (2^64 - 1) ๐Ÿšซ.

An SDNV can represent both very large and very small integer values ๐ŸŒ. But SDNV is clearly not the best way to represent every numeric value ๐Ÿ™ƒ. For example, an SDNV is a poor way to represent an integer whose value typically falls in the range 128 to 255 ๐Ÿซ . Still, in general, we believe that SDNV representation of numeric values in bundle blocks gives the smallest block sizes without sacrificing scalability ๐Ÿ’–.

4.2. Bundle Processing Control Flags ๐Ÿ’…

okay bestie, the bundle processing control flags field in the primary bundle block of every bundle is an SDNV ๐ŸŽ€. The value inside that SDNV is a string of bits that switches on selected bundle processing features โœจ. heads up: the bit labels count from least significant (0) up to most significant within the decoded bit string, NOT the bits as they sit on the wire ๐Ÿ™ˆ. so this section and the next one don't follow the usual RFC bit-0-on-the-left thing. the reason is future-proofing: if new fields get added, the SDNV grows to the left, and this numbering keeps every reference valid ๐Ÿงš

            2                   1                   0
            0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |Status Report|Class of Svc.|   General   |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

           Figure 3: Bundle Processing Control Flags Bit Layout

positions 0 through 6 are the flags that describe the bundle:

  • 0 -- Bundle is a fragment. ๐Ÿงฉ
  • 1 -- Application data unit is an administrative record. ๐Ÿ“œ
  • 2 -- Bundle must not be fragmented. ๐Ÿšซ
  • 3 -- Custody transfer is requested. ๐Ÿค
  • 4 -- Destination endpoint is a singleton. ๐ŸŽฏ
  • 5 -- Acknowledgement by application is requested. ๐Ÿ’Œ
  • 6 -- Reserved for future use. ๐Ÿ”’

positions 7 through 13 are for the bundle's class of service ๐Ÿ‘‘. positions 8 and 7 together make a two-bit priority field, and higher values mean higher priority: 00 = bulk, 01 = normal, 10 = expedited, and 11 is reserved for future use โšก. inside this field, bit 8 is the most significant bit. positions 9 through 13 are reserved for future use ๐ŸŒธ

positions 14 through 20 are the status report request flags. these are how you ask for status reports ๐Ÿ“ฌ:

  • 14 -- Request reporting of bundle reception.
  • 15 -- Request reporting of custody acceptance.
  • 16 -- Request reporting of bundle forwarding.
  • 17 -- Request reporting of bundle delivery.
  • 18 -- Request reporting of bundle deletion.
  • 19 -- Reserved for future use.
  • 20 -- Reserved for future use.

now the rules, and they're important ๐Ÿฅน. if the bundle processing control flags say the application data unit is an administrative record, then the custody transfer requested flag must be zero and all status report request flags must be zero. if the custody transfer requested flag is 1, the sending node is asking the receiving node to accept custody of the bundle ๐Ÿซถ. and if the bundle's source endpoint ID is "dtn:none" (see below), the bundle can't be uniquely identified, so every bundle protocol feature that relies on bundle identity has to be turned off ๐Ÿ’€. that means the custody transfer requested flag must be zero, the "Bundle must not be fragmented" flag must be 1, and all status report request flags must be zero.


4.3. Block Processing Control Flags ๐Ÿฆ‹

the block processing control flags field is in every block except the primary bundle block, and it's an SDNV too ๐Ÿ’œ. the value in it is a string of bits that switches on selected block processing features. here's what each position means, counting from least significant (labeled '0') up to most significant (labeled '6') within the decoded bit string ๐Ÿ”:

                        0
            6 5 4 3 2 1 0
           +-+-+-+-+-+-+-+
           |   Flags     |
           +-+-+-+-+-+-+-+

            Figure 4: Block Processing Control Flags Bit Layout
  • 0 - Block must be replicated in every fragment. ๐Ÿชž
  • 1 - Transmit status report if block can't be processed. ๐Ÿ“ฃ
  • 2 - Delete bundle if block can't be processed. ๐Ÿ—‘๏ธ
  • 3 - Last block. ๐Ÿ
  • 4 - Discard block if it can't be processed. ๐Ÿซง
  • 5 - Block was forwarded without being processed. โžก๏ธ
  • 6 - Block contains an EID-reference field. ๐Ÿ”—

for every bundle whose primary block's bundle processing control flags say the application data unit is an administrative record, the "Transmit status report if block can't be processed" flag in every other block's block processing flags field must be zero ๐Ÿ™…โ€โ™€๏ธ. and the 'Block must be replicated in every fragment' bit must be set to zero on all blocks that come after the payload block ๐Ÿ’….


4.4. Endpoint IDs ๐ŸŒˆ

bundles are sent to bundle endpoints, and those are identified by text strings called "endpoint IDs" (see Section 3.1) ๐Ÿ“ฎ. every endpoint ID carried in any bundle block is a Uniform Resource Identifier (URI; [URI]), so it always has this general shape โœจ:

< scheme name > : < scheme-specific part, or "SSP" >

for bundle protocol purposes, neither the scheme name nor the SSP can go over 1023 bytes. that's the cap, no cap ๐Ÿงข.

bundle blocks cite a bunch of endpoint IDs for different jobs ๐Ÿง . a lot of them (though not necessarily all) live in the "dictionary" byte array in the bundle's primary block. the dictionary is basically just the scheme names and SSPs strung together, each one null-terminated ๐Ÿ“š.

"Endpoint ID references" are how blocks point at endpoint IDs stored in the dictionary. every endpoint ID citation in the primary bundle block is an endpoint ID reference, and other blocks can have them too. each reference is an ordered pair of SDNVs:

  • The first SDNV is the offset within the dictionary of the first character of the referenced endpoint ID's scheme name.
  • The second SDNV is the offset within the dictionary of the first character of the referenced endpoint ID's SSP.

this gives you a little bit of compression, and it's giving efficiency ๐Ÿฅฐ. for example, if a bundle's source and report-to are the same endpoint, that ID's text can be cited twice but only shows up once in the dictionary ๐ŸŽ€.

the scheme named by the < scheme name > is a set of syntax and semantic rules that explain how to parse and interpret the SSP. the list of allowable schemes is effectively unlimited ๐ŸŒ. any scheme that conforms to [URIREG] can be used in a bundle protocol endpoint ID. on top of that, this document defines one more scheme ๐Ÿ’–:

  • The "dtn" scheme, which is used at minimum to represent the null endpoint ID "dtn:none". forwarding a bundle to the null endpoint is never contraindicated, and the minimum reception group for the null endpoint is the empty set ๐Ÿซฅ.

one last thing: endpoint IDs in bundle blocks are written as URIs, but implementations of the BP service interface may support expressing endpoint IDs in some internationalized way (for example, Internationalized Resource Identifiers (IRIs); see [RFC3987]) ๐ŸŒโœจ

4.5. Formats of Bundle Blocks โœจ

okay so this section is where we finally get the actual shapes of the primary block and the payload block ๐Ÿงš the rules for processing these blocks live in Section 5 of this document, so if things feel a little cliffhanger-y here, that's on purpose ๐Ÿ’…

Note that supplementary DTN protocol specifications (including, but not restricted to, the Bundle Security Protocol [BSP]) may require that BP implementations conforming to those protocols construct and process additional blocks. ๐Ÿ”ฅ so these two blocks are not the whole story, bestie

The format of the two basic BP blocks is shown in Figure 5 below ๐ŸŽ€

Primary Bundle Block
+----------------+----------------+----------------+----------------+
|    Version     |                  Proc. Flags (*)                 |
+----------------+----------------+----------------+----------------+
|                          Block length (*)                         |
+----------------+----------------+---------------------------------+
|   Destination scheme offset (*) |     Destination SSP offset (*)  |
+----------------+----------------+----------------+----------------+
|      Source scheme offset (*)   |        Source SSP offset (*)    |
+----------------+----------------+----------------+----------------+
|    Report-to scheme offset (*)  |      Report-to SSP offset (*)   |
+----------------+----------------+----------------+----------------+
|    Custodian scheme offset (*)  |      Custodian SSP offset (*)   |
+----------------+----------------+----------------+----------------+
|                    Creation Timestamp time (*)                    |
+---------------------------------+---------------------------------+
|             Creation Timestamp sequence number (*)                |
+---------------------------------+---------------------------------+
|                           Lifetime (*)                            |
+----------------+----------------+----------------+----------------+
|                        Dictionary length (*)                      |
+----------------+----------------+----------------+----------------+
|                  Dictionary byte array (variable)                 |
+----------------+----------------+---------------------------------+
|                      [Fragment offset (*)]                        |
+----------------+----------------+---------------------------------+
|              [Total application data unit length (*)]             |
+----------------+----------------+---------------------------------+


Bundle Payload Block
+----------------+----------------+----------------+----------------+
|  Block type    | Proc. Flags (*)|        Block length(*)          |
+----------------+----------------+----------------+----------------+
/                     Bundle Payload (variable)                     /
+-------------------------------------------------------------------+

Figure 5: Bundle Block Formats

(*) Notes:

The bundle processing control ("Proc.") flags field in the Primary Bundle Block is an SDNV and is therefore variable length. A three-octet SDNV is shown here for convenience in representation.

The block length field of the Primary Bundle Block is an SDNV and is therefore variable length. A four-octet SDNV is shown here for convenience in representation.

Each of the eight offset fields in the Primary Bundle Block is an SDNV and is therefore variable length. Two-octet SDNVs are shown here for convenience in representation.

The Creation Timestamp time field in the Primary Bundle Block is an SDNV and is therefore variable length. A four-octet SDNV is shown here for convenience in representation.

The Creation Timestamp sequence number field in the Primary Bundle Block is an SDNV and is therefore variable length. A four-octet SDNV is shown here for convenience in representation.

The Lifetime field in the Primary Bundle Block is an SDNV and is therefore variable length. A four-octet SDNV is shown here for convenience in representation.

The dictionary length field of the Primary Bundle Block is an SDNV and is therefore variable length. A four-octet SDNV is shown here for convenience in representation.

The fragment offset field of the Primary Bundle Block is present only if the Fragment flag in the block's processing flags byte is set to 1. It is an SDNV and is therefore variable length; a four-octet SDNV is shown here for convenience in representation.

The total application data unit length field of the Primary Bundle Block is present only if the Fragment flag in the block's processing flags byte is set to 1. It is an SDNV and is therefore variable length; a four-octet SDNV is shown here for convenience in representation.

The block processing control ("Proc.") flags field of the Payload Block is an SDNV and is therefore variable length. A one-octet SDNV is shown here for convenience in representation.

The block length field of the Payload Block is an SDNV and is therefore variable length. A two-octet SDNV is shown here for convenience in representation.

4.5.1. Primary Bundle Block

The primary bundle block is the one with all the basic info a bundle needs to get routed to where it's going ๐Ÿฆ‹ Here are its fields:

  • Version: A 1-byte field that tells you which version of the bundle protocol built this block. This document describes version 0x06 of the bundle protocol. ๐Ÿ’œ
  • Bundle Processing Control Flags: An SDNV holding the bundle processing control flags we talked about in Section 4.2 above. ๐ŸŒธ
  • Block Length: An SDNV holding the total length of all the remaining fields in the block. ๐Ÿ“
  • Destination Scheme Offset: The offset, inside the dictionary byte array, of the scheme name for the endpoint ID of the bundle's destination. That's the endpoint with the node(s) where the bundle is supposed to be delivered. ๐ŸŽฏ
  • Destination SSP Offset: The offset, inside the dictionary byte array, of the scheme-specific part of that same destination endpoint ID. โœจ
  • Source Scheme Offset: The offset, inside the dictionary byte array, of the scheme name for the endpoint ID of the bundle's nominal source. That's the endpoint nominally containing the node the bundle was first sent from. ๐ŸŒˆ
  • Source SSP Offset: The offset, inside the dictionary byte array, of the scheme-specific part of the nominal source's endpoint ID. ๐Ÿซถ
  • Report-to Scheme Offset: The offset, inside the dictionary byte array, of the scheme name for the ID of the endpoint where status reports about forwarding and delivering this bundle get sent. ๐Ÿ“ฌ
  • Report-to SSP Offset: The offset, inside the dictionary byte array, of the scheme-specific part of that report-to endpoint ID. ๐Ÿ“ฌ
  • Custodian Scheme Offset: So the "current custodian endpoint ID" of a primary bundle block is an endpoint whose membership includes the node that most recently accepted custody of the bundle when it got forwarded. This field holds the offset, inside the dictionary byte array, of the scheme name for that current custodian endpoint ID. ๐Ÿ›ก๏ธ
  • Custodian SSP Offset: The offset, inside the dictionary byte array, of the scheme-specific part of the current custodian endpoint ID. ๐Ÿ›ก๏ธ
  • Creation Timestamp: This is a pair of SDNVs that, together with the source endpoint ID (and, if the bundle is a fragment, the fragment offset and payload length), basically identify the bundle. The first SDNV is the bundle's creation time, and the second is its creation timestamp sequence number. ๐Ÿ•ฐ๏ธ The creation time is the number of seconds since the start of the year 2000, on the Coordinated Universal Time (UTC) scale [UTC], at which the transmission request that created the bundle was received. The sequence count is the latest value (as of the moment that request came in) of a monotonically increasing positive integer counter, managed by the source node's bundle protocol agent. It may be reset to zero whenever the current time goes up by one second. ๐Ÿ”ข A source Bundle Protocol Agent must never create two distinct bundles with the same source endpoint ID and bundle creation timestamp. That combo of source endpoint ID and bundle creation timestamp is what identifies one single transmission request, so the receiving application can acknowledge it (as long as the source endpoint ID isn't dtn:none). ๐Ÿ’–
  • Lifetime: An SDNV that says when the bundle's payload stops being useful, written as a number of seconds past the creation time. Once the current time is greater than the creation time plus the lifetime, bundle nodes don't need to keep or forward the bundle anymore, and it may be deleted from the network. โณ๐Ÿ’€
  • Dictionary Length: An SDNV holding the length of the dictionary byte array. ๐Ÿ“–
  • Dictionary: An array of bytes made by concatenating the null-terminated scheme names and SSPs of every endpoint ID referenced by any field in this primary block. It can also include other endpoint IDs referenced by fields in other TBD DTN protocol blocks. Its length is whatever the Dictionary Length field says. ๐Ÿ“š
  • Fragment Offset: If the Bundle Processing Control Flags of this primary block say the bundle is a fragment, this is an SDNV showing how far from the start of the original application data unit the bytes in this bundle's payload were located. If the bundle isn't a fragment, this field gets left out of the block. ๐Ÿงฉ
  • Total Application Data Unit Length: If the Bundle Processing Control Flags of this primary block say the bundle is a fragment, this is an SDNV holding the total length of the original application data unit that this bundle's payload is part of. If the bundle isn't a fragment, this field gets left out of the block. ๐Ÿ“โœจ

4.5.2. Canonical Bundle Block Format

okay so every bundle block that is NOT the primary block has the same fields, in this exact order ๐Ÿงฉโœจ

  • Block type code: an 8-bit unsigned binary integer ๐ŸŽ€. Block type code 1 means it's a bundle payload block. Codes 192 through 255 aren't defined by this spec, so they're free for private and/or experimental use ๐Ÿงช. Every other value is reserved for future use, so hands off ๐Ÿ™…โ€โ™€๏ธ
  • Block processing control flags: an unsigned integer written as an SDNV. Each bit switches on a particular block processing feature ๐Ÿ”ฅ
  • Block EID reference count and EID references (optional): this one only shows up if and only if the block points at EID elements in the primary block's dictionary ๐Ÿ‘€. When that's the case, the 'block contains an EID-reference field' flag gets set to 1, and the block has this field: a count of EID references (as an SDNV), followed by the references themselves. Each reference is a pair of SDNVs. The first SDNV holds the offset of a scheme name in the primary block's dictionary, and the second holds the offset of a scheme-specific part in that same dictionary ๐Ÿ’…
  • Block data length: an unsigned integer written as an SDNV. It tells you the total length of all the remaining fields in the block, aka the block-type-specific data fields ๐Ÿ“
  • Block-type-specific data fields: the format and order depend on the block type, and their total length in octets is whatever the block data length says ๐ŸŒธ. Any multi-byte field here is in network byte order ๐ŸŒ

Here's the vibe in pictures:

+-----------+-----------+-----------+-----------+
|Block type | Block processing ctrl flags (SDNV)|
+-----------+-----------+-----------+-----------+
|            Block length  (SDNV)               |
+-----------+-----------+-----------+-----------+
/          Block body data (variable)           /
+-----------+-----------+-----------+-----------+

   Figure 6: Block Layout without EID Reference List


+-----------+-----------+-----------+-----------+
|Block Type | Block processing ctrl flags (SDNV)|
+-----------+-----------+-----------+-----------+
|        EID Reference Count  (SDNV)            |
+-----------+-----------+-----------+-----------+
|  Ref_scheme_1 (SDNV)  |    Ref_ssp_1 (SDNV)   |
+-----------+-----------+-----------+-----------+
|  Ref_scheme_2 (SDNV)  |    Ref_ssp_2 (SDNV)   |
+-----------+-----------+-----------+-----------+
|            Block length  (SDNV)               |
+-----------+-----------+-----------+-----------+
/          Block body data (variable)           /
+-----------+-----------+-----------+-----------+

   Figure 7: Block Layout Showing Two EID References

4.5.3. Bundle Payload Block

the payload block has four fields, and they go like this ๐Ÿ“ฆ

Block Type: a 1-byte field that tells you what kind of block this is ๐Ÿท๏ธ. For the bundle payload block, it's always the value 1.

Block Processing Control Flags: an SDNV holding the block processing control flags we talked about in Section 4.3 above ๐ŸŽ›๏ธ.

Block Length: an SDNV with the total length of all the remaining fields in the block. Basically, that's the length of the bundle's payload ๐Ÿ“.

Payload: the application data this bundle is carrying ๐Ÿ’Œ.

So payload blocks follow the canonical format from the previous section, with one twist: the 'block contains an EID-reference field' bit in the block processing control flags is never set ๐Ÿ™…โ€โ™€๏ธ. The block body data for a payload block is just the application data the bundle is carrying ๐Ÿซถ.

4.6. Extension Blocks

"Extension blocks" are every block that isn't the primary or payload block ๐Ÿงš. Since this spec doesn't define extension blocks, not every node that follows this spec will necessarily have Bundle Protocol code that can process all of them (recognizing, parsing, acting on, and/or producing them) ๐Ÿคทโ€โ™€๏ธ. So it's totally possible for a node to get a bundle with extension blocks it just can't handle, and that's okay, it happens ๐Ÿ’…

Here's the rule: whenever a bundle gets forwarded with one or more extension blocks that couldn't be processed, the "Block was forwarded without being processed" flag MUST be set to 1 in the block processing flags of each one of those blocks ๐Ÿšฉ. Later, another node that gets the bundle and CAN process that block MAY optionally clear the flag (set it back to zero) ๐Ÿงน. The specs for each extension block are expected to say when, if ever, that flag is allowed to be cleared ๐Ÿ“œ.

4.7. Dictionary Revision

any strings in a bundle's dictionary (scheme names and SSPs) that aren't referenced from the primary block or from the block EID reference field of any extension block MAY be removed from the dictionary when the bundle gets forwarded ๐Ÿ—‘๏ธโœจ.

BUT here's the catch ๐Ÿ‘€: whenever removing a string shifts the offsets (within the dictionary byte array) of any other strings, all the endpoint ID references pointing at those strings MUST be adjusted at the very same time ๐Ÿ”ง. These references can live in the primary block, in the block EID reference fields of extension blocks, or both, so keep track of them all ๐Ÿซถ.

5. Bundle Processing

the bundle processing procedures in this section and in Section 6 are the rules for how the Bundle Protocol Agent and the Application Agent administrative element of each bundle node behave ๐ŸŽ€. They aren't the full story and they aren't the only story ๐Ÿ“–. Supplementary DTN protocol specs (including, but not limited to, the Bundle Security Protocol [BSP]) MAY require extra steps at certain points in these procedures ๐Ÿ”. Those extra steps SHALL NOT override or supersede the mandated bundle protocol procedures ๐Ÿ™…โ€โ™€๏ธ. The one exception is that they MAY, in some cases, make these procedures moot, for example by requiring that an implementation stop processing a particular incoming or outgoing bundle because the supplementary protocol spotted a fault condition ๐Ÿ’€.

5.1. Generation of Administrative Records

all the initial transmission of bundles happens because an application agent asked for it ๐Ÿ’Œ. When a node is required to "generate" an administrative record (a bundle status report or a custody signal), the bundle protocol agent is the one who has to make sure a new bundle gets sent out carrying that record ๐Ÿ“ฌ. In theory, it does this by telling the administrative element of the node's application agent to build the record and request its transmission, as Section 6 explains ๐Ÿง . How exactly that happens in practice is up to each implementation, as long as the constraints in Section 6 are followed ๐ŸŒˆ.

okay so requesting status reports could flood the network with way too much bundle traffic ๐Ÿ˜ญ. That's why generating status reports is mandatory in only one case: deleting a bundle that has custody transfer requested ๐Ÿ—‘๏ธ. Everywhere else, the bundle protocol agent gets to decide whether to generate a requested status report ๐Ÿซถ. Things that could help with that decision, like pre-arranged agreements allowing status reports under certain circumstances, are out of scope for this spec ๐Ÿ™ˆ.

Notes on administrative record terminology ๐Ÿ“:

  • A "bundle reception status report" is a bundle status report with the "reporting node received bundle" flag set to 1 ๐Ÿ“ฅ.
  • A "custody acceptance status report" is a bundle status report with the "reporting node accepted custody of bundle" flag set to 1 ๐Ÿค.
  • A "bundle forwarding status report" is a bundle status report with the "reporting node forwarded the bundle" flag set to 1 โžก๏ธ.
  • A "bundle delivery status report" is a bundle status report with the "reporting node delivered the bundle" flag set to 1 ๐ŸŽ‰.
  • A "bundle deletion status report" is a bundle status report with the "reporting node deleted the bundle" flag set to 1 ๐Ÿ—‘๏ธ.
  • A "Succeeded" custody signal is a custody signal with the "custody transfer succeeded" flag set to 1 โœ….
  • A "Failed" custody signal is a custody signal with the "custody transfer succeeded" flag set to zero โŒ.
  • The "current custodian" of a bundle is the endpoint identified by the current custodian endpoint ID in the bundle's primary block ๐Ÿ‘‘.

5.2. Bundle Transmission

here are the steps for handling a bundle transmission request ๐Ÿš€:

Step 1: if custody transfer is requested for this bundle transmission AND custody acceptance by the source node is required, then the bundle protocol agent MUST commit to accepting custody of the bundle. If it does, processing moves on to Step 2 ๐Ÿค. If it can't, the request can't be honored, and all the remaining steps of this procedure MUST be skipped ๐Ÿ™…โ€โ™€๏ธ. The bundle protocol agent MUST NOT commit to accepting custody of a bundle if the conditions for accepting custody of that bundle aren't met ๐Ÿšซ. This spec doesn't define the conditions under which a node may accept custody of a bundle whose destination isn't a singleton endpoint ๐Ÿคทโ€โ™€๏ธ.

Step 2: transmission of the bundle starts ๐ŸŽฌ. An outbound bundle MUST be created using the parameters from the bundle transmission request, with the current custodian endpoint ID set to the null endpoint ID "dtn:none" and with the retention constraint "Dispatch pending" โณ. The bundle's source endpoint ID MUST be either the ID of an endpoint the node is a member of, or the null endpoint ID "dtn:none" ๐Ÿ’œ.

Step 3: processing continues from Step 1 of Section 5.4 ๐ŸŒŸ.

5.3. Bundle Dispatching

here are the steps for dispatching a bundle ๐Ÿ“ฎ:

Step 1: if the bundle's destination endpoint is an endpoint the node is a member of, the bundle delivery procedure from Section 5.7 MUST be followed ๐ŸŽ€.

Step 2: processing continues from Step 1 of Section 5.4 โœจ.

5.4. Bundle Forwarding โœจ

okay so forwarding is where the bundle actually starts moving, and it's giving main character ๐Ÿฆ‹ Here are the steps, bestie:

Step 1: Add the retention constraint "Forward pending" to the bundle, and remove the bundle's "Dispatch pending" retention constraint. ๐Ÿ’…

Step 2: The bundle protocol agent has to figure out whether forwarding is contraindicated for any of the reasons in Figure 12. Specifically:

  • The bundle protocol agent must determine which endpoint(s) to forward the bundle to. It may either forward the bundle straight to its destination endpoint (if that's possible) or forward it to some other endpoint(s) for further forwarding. How it decides can depend on the scheme name in the destination endpoint ID, but that part is beyond the scope of this document ๐Ÿงš If the agent can't pick any endpoint(s) at all, then forwarding is contraindicated.
  • Once the agent has picked its endpoint(s), it must select the convergence layer adapter(s) that will let the node send the bundle to the nodes of the minimum reception group of each selected endpoint. How those adapters get chosen can depend on the scheme name in the destination endpoint ID, and that's also beyond the scope of this document ๐ŸŒธ If the agent can't select any convergence layer adapters to use, then forwarding is contraindicated.

Step 3: If forwarding is contraindicated for any of the reasons in Figure 12, then the Forwarding Contraindicated procedure defined in Section 5.4.1 must be followed. The remaining steps of Section 5 get skipped for now ๐Ÿซถ

Step 4: If the bundle's custody transfer requested flag (in the bundle processing flags field) is set to 1, then the custody transfer procedure defined in Section 5.10.2 must be followed. ๐Ÿ”ฅ

Step 5: For each endpoint selected for forwarding, the bundle protocol agent must use the selected convergence layer adapter(s) to send the bundle to the nodes in that endpoint's minimum reception group. When each adapter actually sends it is an implementation matter, so that's up to whoever builds it โœจ

Now, bundle security is delicate, so listen up ๐Ÿ™ˆ To keep from possibly breaking it, the order of the blocks in a forwarded bundle must not change as it transits a node. Received blocks have to go out in the same relative order they came in. Blocks can be added as the bundle passes through intermediate nodes, but removing a block that doesn't have its 'Discard block if it can't be processed' flag in the block processing control flags set to 1 may cause security to fail. ๐Ÿ’€

Step 6: When every selected convergence layer adapter has told the bundle protocol agent that it's finished its data sending procedures for this bundle:

  • If the "request reporting of bundle forwarding" flag in the bundle's status report request field is set to 1, then a bundle forwarding status report should be generated, destined for the bundle's report-to endpoint ID. If the bundle has the retention constraint "custody accepted" and every node in the minimum reception group of the endpoint selected for forwarding is known to be unable to send bundles back to this node, then the reason code on this report must be "forwarded over unidirectional link". Otherwise, the reason code must be "no additional information". ๐Ÿ“
  • The bundle's "Forward pending" retention constraint must be removed. ๐Ÿ‘‘

5.4.1. Forwarding Contraindicated ๐ŸŽ€

so when forwarding is contraindicated, here's the drama, iykyk ๐Ÿ˜ญ

Step 1: The bundle protocol agent must decide whether to declare failure in forwarding the bundle for this reason. Note: that decision is likely to be influenced by the reason forwarding was contraindicated โœจ

Step 2: If forwarding failure is declared, then the Forwarding Failed procedure defined in Section 5.4.2 must be followed. Otherwise:

  • (a) if the bundle's custody transfer requested flag (in the bundle processing flags field) is set to 1, then the custody transfer procedure defined in Section 5.10 must be followed;
  • (b) when, at some future time, forwarding of this bundle stops being contraindicated, processing proceeds from Step 5 of Section 5.4. ๐Ÿฆ‹

5.4.2. Forwarding Failed ๐Ÿ’”

and this is the part where the failure gets handled, no cap ๐Ÿ˜ค

Step 1: If the bundle's custody transfer requested flag (in the bundle processing flags field) is set to 1, then custody transfer failure must be handled. Procedures for handling custody transfer failure for a bundle whose destination is not a singleton endpoint are not defined in this specification. For a bundle whose destination is a singleton endpoint, the bundle protocol agent must handle the custody transfer failure by generating a "Failed" custody signal for the bundle, destined for the bundle's current custodian. That custody signal must contain a reason code matching the reason forwarding was determined to be contraindicated. (Note that discarding the bundle won't delete it from the network, since the current custodian still has a copy. ๐Ÿซถ)

Step 2: If the bundle's destination endpoint is an endpoint the node is a member of, then the bundle's "Forward pending" retention constraint must be removed. Otherwise, the bundle must be deleted: the bundle deletion procedure defined in Section 5.13 must be followed, citing the reason forwarding was determined to be contraindicated. ๐Ÿ—‘๏ธ


5.5. Bundle Expiration โฐ

a bundle expires when the current time is greater than its creation time plus its lifetime, as set in the primary bundle block. Expiration can happen at any point while the bundle is being processed, so keep an eye on it ๐Ÿ‘€ When a bundle expires, the bundle protocol agent must delete it for the reason "lifetime expired", and the bundle deletion procedure defined in Section 5.13 must be followed. โญ


5.6. Bundle Reception ๐ŸŒˆ

this is what happens when a bundle shows up from another node. Here's the whole routine:

Step 1: Add the retention constraint "Dispatch pending" to the bundle. ๐Ÿ’œ

Step 2: If the "request reporting of bundle reception" flag in the bundle's status report request field is set to 1, then a bundle reception status report with reason code "No additional information" should be generated, destined for the bundle's report-to endpoint ID. ๐Ÿงพ

Step 3: For each block in the bundle that is an extension block the bundle protocol agent cannot process:

  • If the block processing flags in that block indicate that a status report is requested in this event, then a bundle reception status report with reason code "Block unintelligible" should be generated, destined for the bundle's report-to endpoint ID.
  • If the block processing flags in that block indicate that the bundle must be deleted in this event, then the bundle protocol agent must delete the bundle for the reason "Block unintelligible". The bundle deletion procedure defined in Section 5.13 must be followed, and all remaining steps of the bundle reception procedure must be skipped. ๐Ÿšซ
  • If the block processing flags in that block do NOT indicate that the bundle must be deleted in this event, but do indicate that the block must be discarded, then the bundle protocol agent must remove this block from the bundle. ๐Ÿงน
  • If the block processing flags in that block indicate NEITHER that the bundle must be deleted NOR that the block must be discarded, then the bundle protocol agent must set to 1 the "Block was forwarded without being processed" flag in the block processing flags of the block. ๐Ÿฌ

Step 4: If the bundle's custody transfer requested flag (in the bundle processing flags field) is set to 1, and the bundle has the same source endpoint ID, creation timestamp, and (if the bundle is a fragment) fragment offset and payload length as another bundle that (a) has not been discarded and (b) currently has the retention constraint "Custody accepted", then custody transfer redundancy must be handled. Otherwise, processing proceeds from Step 5. Procedures for handling redundancy in custody transfer for a bundle whose destination is not a singleton endpoint are not defined in this specification. For a bundle whose destination is a singleton endpoint, the bundle protocol agent must handle custody transfer redundancy by generating a "Failed" custody signal for this bundle with reason code "Redundant reception", destined for this bundle's current custodian, and then removing this bundle's "Dispatch pending" retention constraint. ๐Ÿ”

Step 5: Processing proceeds from Step 1 of Section 5.3. ๐ŸŽ€

5.7. Local Bundle Delivery โœจ

okay so this is the bit where a bundle has arrived at a node that's a member of its destination endpoint, and we need to hand it over to the app. bestie, the steps go like this ๐Ÿ’…

Step 1: If the received bundle is a fragment, the application data unit reassembly procedure described in Section 5.9 must be followed. If this procedure results in reassembly of the entire original application data unit, processing of this bundle (whose fragmentary payload has been replaced by the reassembled application data unit) proceeds from Step 2. Otherwise, the retention constraint "Reassembly pending" must be added to the bundle and all remaining steps of this procedure are skipped. ๐Ÿงฉ

Step 2: Delivery depends on the state of the registration whose endpoint ID matches that of the destination of the bundle:

  • If the registration is in the Active state, then the bundle must be delivered subject to this registration (see Section 3.1 above) as soon as all previously received bundles that are deliverable subject to this registration have been delivered. ๐Ÿš€
  • If the registration is in the Passive state, then the registration's delivery failure action must be taken (see Section 3.1 above). ๐Ÿ˜ฌ

Step 3: As soon as the bundle has been delivered:

  • If the "request reporting of bundle delivery" flag in the bundle's status report request field is set to 1, then a bundle delivery status report should be generated, destined for the bundle's report-to endpoint ID. Note that this status report only states that the payload has been delivered to the application agent, not that the application agent has processed that payload. ๐Ÿ“ฌ
  • If the bundle's custody transfer requested flag (in the bundle processing flags field) is set to 1, custodial delivery must be reported. Procedures for reporting custodial delivery for a bundle whose destination is not a singleton endpoint are not defined in this specification. For a bundle whose destination is a singleton endpoint, the bundle protocol agent must report custodial delivery by generating a "Succeeded" custody signal for the bundle, destined for the bundle's current custodian. ๐Ÿซถ

5.8. Bundle Fragmentation ๐Ÿงฉ

okay sometimes a bundle is just too chunky to get where it's going, so the bundle protocol agents need to shrink it. ngl this happens a lot when the endpoint is only reachable through super short contacts and no upcoming contact is long enough to fit the whole bundle through ๐Ÿฅฒ

It may at times be necessary for bundle protocol agents to reduce the sizes of bundles in order to forward them. This might be the case, for example, if the endpoint to which a bundle is to be forwarded is accessible only via intermittent contacts and no upcoming contact is long enough to enable the forwarding of the entire bundle.

So the size of a bundle can be reduced by "fragmenting" it. Fragmenting a bundle whose payload is of size M means replacing it with two "fragments" (new bundles with the same source endpoint ID and creation timestamp as the original bundle) whose payloads are the first N and the last (M - N) bytes of the original bundle's payload, where 0 < N < M. Fragments can themselves be fragmented, so fragmentation may in effect replace the original bundle with more than two fragments. (However, there is only one 'level' of fragmentation, as in IP fragmentation.) ๐Ÿชž

Any bundle whose primary block's bundle processing flags do NOT indicate that it must not be fragmented may be fragmented at any time, for any purpose, at the discretion of the bundle protocol agent. โœจ

Fragmentation shall be constrained as follows:

  • The concatenation of the payloads of all fragments produced by fragmentation must always be identical to the payload of the bundle that was fragmented. Note that the payloads of fragments resulting from different fragmentation episodes, in different parts of the network, may be overlapping subsets of the original bundle's payload.
  • The bundle processing flags in the primary block of each fragment must be modified to indicate that the bundle is a fragment, and both fragment offset and total application data unit length must be provided at the end of each fragment's primary bundle block.
  • The primary blocks of the fragments will differ from that of the fragmented bundle as noted above.
  • The payload blocks of fragments will differ from that of the fragmented bundle as noted above.
  • All blocks that precede the payload block at the time of fragmentation must be replicated in the fragment with the lowest offset.
  • All blocks that follow the payload block at the time of fragmentation must be replicated in the fragment with the highest offset.
  • If the 'Block must be replicated in every fragment' bit is set to 1, then the block must be replicated in every fragment.
  • If the 'Block must be replicated in every fragment' bit is set to zero, the block should be replicated in only one fragment.
  • The relative order of all blocks that are present in a fragment must be the same as in the bundle prior to fragmentation.

5.9. Application Data Unit Reassembly ๐Ÿชก

this is the glow-up where the fragments get stitched back together into the original application data unit. the vibe is very puzzle-piece ๐Ÿงฉ๐Ÿ’–

If the concatenation (as informed by fragment offsets and payload lengths) of the payloads of all previously received fragments with the same source endpoint ID and creation timestamp as this fragment, together with the payload of this fragment, forms a byte array whose length is equal to the total application data unit length in the fragment's primary block, then:

  • This byte array (the reassembled application data unit) must replace the payload of this fragment.
  • The "Reassembly pending" retention constraint must be removed from every other fragment whose payload is a subset of the reassembled application data unit.
Note: reassembly of application data units from fragments occurs at destination endpoints as necessary. An application data unit may also be reassembled at some other endpoint on the route to the destination. ๐Ÿ‘€

5.10. Custody Transfer ๐Ÿซถ

custody is basically a node saying "i've got this one, bestie, i'll take it from here." it's a whole commitment ๐Ÿฅน

The conditions under which a node may accept custody of a bundle whose destination is not a singleton endpoint are not defined in this specification.

The decision as to whether or not to accept custody of a bundle whose destination is a singleton endpoint is an implementation matter that may involve both resource and policy considerations. However, if the bundle protocol agent has committed to accepting custody of the bundle (as described in Step 1 of Section 5.2), then custody must be accepted. ๐Ÿค

If the bundle protocol agent elects to accept custody of the bundle, then it must follow the custody acceptance procedure defined in Section 5.10.1.


5.10.1. Custody Acceptance ๐Ÿ’Œ

Procedures for acceptance of custody of a bundle whose destination is not a singleton endpoint are not defined in this specification.

Procedures for acceptance of custody of a bundle whose destination is a singleton endpoint are defined as follows.

The retention constraint "Custody accepted" must be added to the bundle.

If the "request reporting of custody acceptance" flag in the bundle's status report request field is set to 1, a custody acceptance status report should be generated, destined for the report-to endpoint ID of the bundle. However, if a bundle reception status report was generated for this bundle (Step 1 of Section 5.6), then this report should be generated by simply turning on the "Reporting node accepted custody of bundle" flag in that earlier report's status flags byte. ๐Ÿ“จ

The bundle protocol agent must generate a "Succeeded" custody signal for the bundle, destined for the bundle's current custodian. ๐ŸŽ‰

The bundle protocol agent must assert the new current custodian for the bundle. It does so by changing the current custodian endpoint ID in the bundle's primary block to the endpoint ID of one of the singleton endpoints in which the node is registered. This may entail appending that endpoint ID's null-terminated scheme name and SSP to the dictionary byte array in the bundle's primary block, and in some case it may also enable the (optional) removal of the current custodian endpoint ID's scheme name and/or SSP from the dictionary. ๐Ÿ‘‘

The bundle protocol agent may set a custody transfer countdown timer for this bundle. Upon expiration of this timer prior to expiration of the bundle itself and prior to custody transfer success for this bundle, the custody transfer failure procedure detailed in Section 5.12 must be followed. The manner in which the countdown interval for such a timer is determined is an implementation matter. โฐ

The bundle should be retained in persistent storage if possible. ๐Ÿ’พ


5.10.2. Custody Release ๐Ÿฆ‹

Procedures for release of custody of a bundle whose destination is not a singleton endpoint are not defined in this specification.

When custody of a bundle is released, where the destination of the bundle is a singleton endpoint, the "Custody accepted" retention constraint must be removed from the bundle and any custody transfer timer that has been established for this bundle must be destroyed. ๐Ÿ•Š๏ธ


5.11. Custody Transfer Success ๐ŸŽ€

the happy ending of custody: the node that handed the bundle off gets a "Succeeded" signal, and then it can finally let go ๐Ÿฅณ

Procedures for determining custody transfer success for a bundle whose destination is not a singleton endpoint are not defined in this specification.

Upon receipt of a "Succeeded" custody signal at a node that is a custodial node of the bundle identified in the custody signal, where the destination of the bundle is a singleton endpoint, custody of the bundle must be released as described in Section 5.10.2. ๐ŸŒˆ


5.12. Custody Transfer Failure ๐Ÿฅ€

and now the plot twist. sometimes custody doesn't go smoothly, so we need to figure out that it failed and then decide what to do about it ๐Ÿ˜ญ

Procedures for determining custody transfer failure for a bundle whose destination is not a singleton endpoint are not defined in this specification. Custody transfer for a bundle whose destination is a singleton endpoint is determined to have failed at a custodial node for that bundle when either (a) that node's custody transfer timer for that bundle (if any) expires or (b) a "Failed" custody signal for that bundle is received at that node. ๐Ÿšจ

Upon determination of custody transfer failure, the action taken by the bundle protocol agent is implementation-specific and may depend on the nature of the failure. For example, if custody transfer failure was inferred from expiration of a custody transfer timer or was asserted by a "Failed" custody signal with the "Depleted storage" reason code, the bundle protocol agent might choose to re-forward the bundle, possibly on a different route (Section 5.4). Receipt of a "Failed" custody signal with the "Redundant reception" reason code, on the other hand, might cause the bundle protocol agent to release custody of the bundle and to revise its algorithm for computing countdown intervals for custody transfer timers. ๐Ÿ”


5.13. Bundle Deletion ๐Ÿ—‘๏ธ

last but not least, here's how a bundle gets deleted. there are a couple of ways it can happen, so pay attention, bestie ๐Ÿ‘€

The steps in deleting a bundle are:

Step 1: If the retention constraint "Custody accepted" currently prevents this bundle from being discarded, and the destination of the bundle is a singleton endpoint, then:

  • Custody of the node is released as described in Section 5.10.2.
  • A bundle deletion status report citing the reason for deletion must be generated, destined for the bundle's report-to endpoint ID.

Otherwise, if the "request reporting of bundle deletion" flag in the bundle's status report request field is set to 1, then a bundle deletion status report citing the reason for deletion should be generated, destined for the bundle's report-to endpoint ID.

Step 2: All of the bundle's retention constraints must be removed. ๐Ÿงน๐Ÿ’…

5.14. Discarding a Bundle ๐Ÿ—‘๏ธ

okay so the moment a bundle has no retention constraints left, it bestie can be discarded. no more holding on to it, it's giving free real estate ๐Ÿ’…

5.15. Canceling a Transmission ๐Ÿšซ

when someone asks to cancel a specific transmission, and the bundle made when that transmission started hasn't been discarded yet, the bundle protocol agent must delete that bundle for the reason "transmission cancelled". to do it, you have to follow the procedure in Section 5.13. no shortcuts, bestie ๐Ÿซถ

5.16. Polling ๐Ÿ“ฌ

when someone asks to poll a registration that's in the Passive state, the bundle protocol agent must immediately deliver the least recently received bundle that's deliverable for that registration, if there is one. so it's basically first in, first out, and it's instant โšก

6. Administrative Record Processing ๐ŸŽ€

6.1. Administrative Records ๐Ÿ“œ

administrative records are the standard app data units that the Bundle Protocol uses to make some of its features work โœจ right now there are two types: bundle status reports and custody signals.

every administrative record starts with a four-bit record type code, then four bits of administrative record flags, then the record content in a format that depends on the type. here are the record type codes:

        +---------+--------------------------------------------+
        |  Value  |                  Meaning                   |
        +=========+============================================+
        |  0001   |  Bundle status report.                     |
        +---------+--------------------------------------------+
        |  0010   |  Custody signal.                           |
        +---------+--------------------------------------------+
        | (other) |  Reserved for future use.                  |
        +---------+--------------------------------------------+

                Figure 8: Administrative Record Type Codes


        +---------+--------------------------------------------+
        |  Value  |                  Meaning                   |
        +=========+============================================+
        |  0001   |  Record is for a fragment; fragment        |
        |         |  offset and length fields are present.     |
        +---------+--------------------------------------------+
        | (other) |  Reserved for future use.                  |
        +---------+--------------------------------------------+

                   Figure 9: Administrative Record Flags

all time values in administrative records are UTC times written in "DTN time" format ๐Ÿ•ฐ๏ธ a DTN time is an SDNV counting the seconds since the start of the year 2000, followed by another SDNV counting the nanoseconds since the start of that second. very precise, very iconic ๐Ÿ’–

the contents of each type of administrative record are described below โœจ

6.1.1. Bundle Status Reports ๐Ÿ“ฃ

sending 'bundle status reports' under specific conditions is an option you can turn on when you request a bundle transmission ๐Ÿ™Œ these reports give you the tea on how bundles are moving through the system, including receipt, custody transfer, forwarding, final delivery, and deletion. they get sent to the Report-to endpoints of the bundles.

+----------------+----------------+----------------+----------------+
|  Status Flags  |  Reason code   |      Fragment offset (*) (if
+----------------+----------------+----------------+----------------+
    present)     |      Fragment length (*) (if present)            |
+----------------+----------------+----------------+----------------+
|       Time of receipt of bundle X (a DTN time, if present)        |
+----------------+----------------+----------------+----------------+
|  Time of custody acceptance of bundle X (a DTN time, if present)  |
+----------------+----------------+----------------+----------------+
|     Time of forwarding of bundle X (a DTN time, if present)       |
+----------------+----------------+----------------+----------------+
|      Time of delivery of bundle X (a DTN time, if present)        |
+----------------+----------------+----------------+----------------+
|      Time of deletion of bundle X (a DTN time, if present)        |
+----------------+----------------+----------------+----------------+
|          Copy of bundle X's Creation Timestamp time (*)           |
+----------------+----------------+----------------+----------------+
|     Copy of bundle X's Creation Timestamp sequence number (*)     |
+----------------+----------------+----------------+----------------+
|      Length of X's source endpoint ID (*)        |   Source
+----------------+---------------------------------+                +
                     endpoint ID of bundle X (variable)             |
+----------------+----------------+----------------+----------------+

              Figure 10: Bundle Status Report Format

(*) Notes:

the Fragment Offset field, if it's there, is an SDNV, so its length varies. a three-octet SDNV is drawn here just for convenience โœ๏ธ

the Fragment Length field, if it's there, is also an SDNV with variable length. again, a three-octet SDNV is drawn just for convenience โœ๏ธ

the Creation Timestamp fields copy the Creation Timestamp fields from the primary block of the subject bundle ๐Ÿชž they're SDNVs (see Section 4.5.1 above), so they're variable length too. four-octet SDNVs are drawn here just for convenience โœ๏ธ

the source endpoint ID length field is an SDNV, so it's variable length as well. a three-octet SDNV is drawn just for convenience โœ๏ธ

here are the fields in a bundle status report:

Status Flags: a 1-byte field with these flags ๐Ÿšฉ

+----------+--------------------------------------------+
|  Value   |                  Meaning                   |
+==========+============================================+
| 00000001 |  Reporting node received bundle.           |
+----------+--------------------------------------------+
| 00000010 |  Reporting node accepted custody of bundle.|
+----------+--------------------------------------------+
| 00000100 |  Reporting node forwarded the bundle.      |
+----------+--------------------------------------------+
| 00001000 |  Reporting node delivered the bundle.      |
+----------+--------------------------------------------+
| 00010000 |  Reporting node deleted the bundle.        |
+----------+--------------------------------------------+
| 00100000 |  Unused.                                   |
+----------+--------------------------------------------+
| 01000000 |  Unused.                                   |
+----------+--------------------------------------------+
| 10000000 |  Unused.                                   |
+----------+--------------------------------------------+

   Figure 11: Status Flags for Bundle Status Reports

Reason Code: a 1-byte field that explains what the status flags byte is saying ๐Ÿง  this list of reason codes is neither exhaustive nor exclusive, so supplementary DTN protocol specifications (including, but not restricted to, the Bundle Security Protocol [BSP]) can define extra reason codes. here are the status report reason codes:

+---------+--------------------------------------------+
|  Value  |                  Meaning                   |
+=========+============================================+
|  0x00   |  No additional information.                |
+---------+--------------------------------------------+
|  0x01   |  Lifetime expired.                         |
+---------+--------------------------------------------+
|  0x02   |  Forwarded over unidirectional link.       |
+---------+--------------------------------------------+
|  0x03   |  Transmission canceled.                    |
+---------+--------------------------------------------+
|  0x04   |  Depleted storage.                         |
+---------+--------------------------------------------+
|  0x05   |  Destination endpoint ID unintelligible.   |
+---------+--------------------------------------------+
|  0x06   |  No known route to destination from here.  |
+---------+--------------------------------------------+
|  0x07   |  No timely contact with next node on route.|
+---------+--------------------------------------------+
|  0x08   |  Block unintelligible.                     |
+---------+--------------------------------------------+
| (other) |  Reserved for future use.                  |
+---------+--------------------------------------------+

         Figure 12: Status Report Reason Codes

Fragment Offset: if the bundle fragment bit is set in the status flags, this holds the offset (within the original application data unit) of the payload of the bundle that triggered the status report ๐Ÿ“

Fragment length: if the bundle fragment bit is set in the status flags, this holds the length of the payload of the subject bundle ๐Ÿ“

Time of Receipt (if present): if the bundle-received bit is set in the status flags, this holds a DTN time for when the bundle was received at the reporting node ๐Ÿ“ฅ

Time of Custody Acceptance (if present): if the custody-accepted bit is set in the status flags, this holds a DTN time for when custody was accepted at the reporting node ๐Ÿค

Time of Forward (if present): if the bundle-forwarded bit is set in the status flags, this holds a DTN time for when the bundle was first forwarded at the reporting node ๐Ÿš€

Time of Delivery (if present): if the bundle-delivered bit is set in the status flags, this holds a DTN time for when the bundle was delivered at the reporting node ๐Ÿ“ฆ

Time of Deletion (if present): if the bundle-deleted bit is set in the status flags, this holds a DTN time for when the bundle was deleted at the reporting node ๐Ÿ—‘๏ธ

Creation Timestamp of Subject Bundle: a copy of the creation timestamp of the bundle that triggered the status report ๐Ÿชช

Length of Source Endpoint ID: the length in bytes of the source endpoint ID of the bundle that triggered the status report ๐Ÿ”ข

Source Endpoint ID text: the text of the source endpoint ID of the bundle that triggered the status report ๐Ÿ’ฌ

6.1.2. Custody Signals ๐ŸŽ€

okay so custody signals are the administrative records that actually make custody transfer happen ๐Ÿ’… they get sent to the endpoints that are the current custodians of bundles, so the right people always know what's going on ๐Ÿซถ

custody signals have the following format ๐Ÿฆ‹

Custody signal regarding bundle 'X':

+----------------+----------------+----------------+----------------+
|     Status     |      Fragment offset (*) (if present)            |
+----------------+----------------+----------------+----------------+
|                   Fragment length (*) (if present)                |
+----------------+----------------+----------------+----------------+
|                   Time of signal (a DTN time)                     |
+----------------+----------------+----------------+----------------+
|          Copy of bundle X's Creation Timestamp time (*)           |
+----------------+----------------+----------------+----------------+
|     Copy of bundle X's Creation Timestamp sequence number (*)     |
+----------------+----------------+----------------+----------------+
|      Length of X's source endpoint ID (*)        |   Source
+----------------+---------------------------------+                +
                     endpoint ID of bundle X (variable)             |
+----------------+----------------+----------------+----------------+

Figure 13: Custody Signal Format

(*) Notes:

ok the Fragment Offset field, if it's there, is an SDNV, so it's variable length ๐Ÿ“ the three-octet one in the diagram is just there so it's easier to picture ๐Ÿงš

same deal for the Fragment Length field ๐Ÿ’œ it's an SDNV too, and the four-octet version is only shown for convenience ๐ŸŒธ

the Creation Timestamp fields copy the Creation Timestamp fields in the primary block of the subject bundle โœจ so they're SDNVs as well (see Section 4.5.1 above) and that means they're variable length too ๐Ÿ’– the four-octet SDNVs are just for representation ๐Ÿ“

the source endpoint ID length field is an SDNV, so yep, variable length ๐Ÿฆ‹ the three-octet version is only there for convenience ๐Ÿ’…

the fields in a custody signal are:

Status: a 1-byte field with a 1-bit "custody transfer succeeded" flag, followed by a 7-bit reason code that explains what that flag means ๐Ÿ”ฅ the reason codes are:

+---------+--------------------------------------------+
|  Value  |                  Meaning                   |
+=========+============================================+
|  0x00   |  No additional information.                |
+---------+--------------------------------------------+
|  0x01   |  Reserved for future use.                  |
+---------+--------------------------------------------+
|  0x02   |  Reserved for future use.                  |
+---------+--------------------------------------------+
|  0x03   |  Redundant reception (reception by a node  |
|         |  that is a custodial node for this bundle).|
+---------+--------------------------------------------+
|  0x04   |  Depleted storage.                         |
+---------+--------------------------------------------+
|  0x05   |  Destination endpoint ID unintelligible.   |
+---------+--------------------------------------------+
|  0x06   |  No known route to destination from here.  |
+---------+--------------------------------------------+
|  0x07   |  No timely contact with next node on route.|
+---------+--------------------------------------------+
|  0x08   |  Block unintelligible.                     |
+---------+--------------------------------------------+
| (other) |  Reserved for future use.                  |
+---------+--------------------------------------------+

Figure 14: Custody Signal Reason Codes

Fragment offset: if the bundle fragment bit is set in the status flags, then the offset (within the original application data unit) of the payload of the bundle that caused the status report to be generated goes here ๐Ÿงฉ

Fragment length: if the bundle fragment bit is set in the status flags, then the length of the payload of the subject bundle goes here ๐Ÿ“ฆ

Time of Signal: a DTN time saying when the signal was generated โฐ

Creation Timestamp of Subject Bundle: a copy of the creation timestamp of the bundle the signal is about ๐Ÿ‘‘

Length of Source Endpoint ID: the length in bytes of the source endpoint ID of the bundle the signal applied to ๐Ÿ“

Source Endpoint ID text: the text of that same source endpoint ID ๐Ÿ’Œ


6.2. Generation of Administrative Records ๐ŸŒˆ

whenever the application agent's administrative element gets told by the bundle protocol agent to make an administrative record about some bundle, this procedure must be followed, no skipping ๐Ÿ™ˆ

Step 1: the administrative record must be constructed. if the referenced bundle is a fragment, the administrative record must have the Fragment flag set and must contain the fragment offset and fragment length fields. the value of the fragment offset field must be the value of the referenced bundle's fragment offset, and the value of the fragment length field must be the length of the referenced bundle's payload ๐ŸŽ€

Step 2: a request for transmission of a bundle whose payload is this administrative record must be presented to the bundle protocol agent ๐Ÿš€

6.3. Reception of Custody Signals ๐Ÿ’œ

for each received custody signal that has the "custody transfer succeeded" flag set to 1, the administrative element of the application agent must direct the bundle protocol agent to follow the custody transfer success procedure in Section 5.11 ๐Ÿฅณ

for each received custody signal that has the "custody transfer succeeded" flag set to 0, the administrative element of the application agent must direct the bundle protocol agent to follow the custody transfer failure procedure in Section 5.12 ๐Ÿ˜ญ


7. Services Required of the Convergence Layer ๐Ÿฆ‹

7.1. The Convergence Layer โœจ

the whole end-to-end bundle protocol relies on protocols underneath it, at what's called the "convergence layer" ๐Ÿงฑ those are the ones that actually get nodes talking to each other ๐Ÿซถ a bunch of different protocols can fill that role, as long as each convergence layer protocol adapter gives the bundle protocol agent a defined minimal set of services ๐Ÿ’… this convergence layer service spec is the list of those services ๐Ÿ“œ

7.2. Summary of Convergence Layer Services ๐Ÿ’–

each convergence layer protocol adapter is expected to provide these services to the bundle protocol agent:

  • sending a bundle to all bundle nodes in the minimum reception group of the endpoint identified by a specified endpoint ID that are reachable via the convergence layer protocol; and
  • delivering to the bundle protocol agent a bundle that was sent by a remote bundle node via the convergence layer protocol ๐Ÿ“ฌ

the convergence layer service interface specified here is neither exhaustive nor exclusive ๐ŸŒธ which means supplementary DTN protocol specifications (including, but not restricted to, the Bundle Security Protocol [BSP]) may expect convergence layer adapters that serve BP implementations conforming to those protocols to provide additional services ๐Ÿ”

8. Security Considerations ๐Ÿ”โœจ

okay bestie, security is where the bundle protocol really shows its main-character side ๐Ÿ’… It was on the guest list from day one, not a late add-on. It was always assumed that security services would be needed when you use the bundle protocol ๐Ÿซถ So the security architecture and the actual services get their own companion doc, the Bundle Security Protocol specification [BSP] ๐Ÿ“œ, and there's a chill informative overview of all that in [SECO] ๐ŸŒธ.

The bundle protocol was built with the vibe that it'll run over networks with scarce resources ๐Ÿฅ€. Think limited bandwidth, limited connectivity, constrained storage in relay nodes, and so on. So the bundle protocol must ensure that only entities authorized to send bundles over those constrained environments are actually allowed to do it. All unauthorized entities should be stopped from eating up valuable resources ๐Ÿšซ๐Ÿ’€. Not okay, not on my watch.

Because the networks can have really long latencies and delays, data sources should be concerned with the integrity of the data that reaches the intended destination(s), and they may also be concerned with confidentiality while the data travels through the network ๐Ÿ”’. Without integrity, the payload could get corrupted in transit and the destination wouldn't be able to tell ๐Ÿ˜ฑ. Similarly, a data source can care that only authorized people can use the data, which is why confidentiality matters ๐Ÿ™ˆ.

Inside the bundle-aware overlay network, bundle nodes should be concerned with the authenticity of other bundle nodes, plus keeping the payload's integrity intact as bundles get forwarded between nodes ๐Ÿงš.

So bundle security is all about the authenticity, integrity, and confidentiality of bundles passed among bundle nodes ๐Ÿ’–. It's done with three independent security-specific bundle blocks. They can be used together to give multiple security services, or independently of one another, depending on the threats you're seeing, the security requirements that are mandated, and the security policies that must be enforced ๐ŸŽ€.

The Bundle Authentication Block (BAB) handles the authenticity and integrity of bundles on a hop-by-hop basis between bundle nodes ๐Ÿ”—. It lets each bundle node verify a bundle's authenticity before processing or forwarding it. That means entities that aren't authorized to send bundles get their unauthorized transmissions blocked by security-aware bundle nodes ๐Ÿšง.

To get "security-source" to "security-destination" authenticity and integrity, there's the Payload Security Block (PSB) ๐Ÿฆ‹. A "security-source" might not actually be where the bundle started, and can instead be the first security-aware point along the path that's able to apply security services ๐ŸŒˆ. For example, an enclave of networked systems may generate bundles, but only their gateway may be required and/or able to apply security services ๐Ÿฐ. The PSB lets any security-enabled entity along the delivery path, plus the "security-destination" (the recipient counterpart to the "security-source"), check the bundle's authenticity โœ….

For payload confidentiality, the Confidentiality Block (CB) is available ๐Ÿ”. The bundle payload may be encrypted to give "security-source" to "security-destination" payload confidentiality/privacy. The CB tells you which cryptographic algorithm and key IDs were used to encrypt the payload ๐Ÿ—๏ธ.

Heads up: removing strings from the dictionary at a given point in a bundle's end-to-end path, and adjusting the endpoint ID references in that bundle's blocks to match, may make it necessary to re-compute values in one or more of the bundle's security blocks โš ๏ธ.

Forwarding nodes can't break bundle security, even if they themselves don't use the Bundle Security Protocol ๐Ÿ™…โ€โ™€๏ธ. Specifically, the sequencing of the blocks in a forwarded bundle must not be changed as it transits a node, and received blocks must be transmitted in the same relative order they were received. Blocks may be added as bundles transit intermediate nodes. But removing blocks that don't have their 'Discard block if it can't be processed' flag in the block processing control flags set to 1 may cause security to fail ๐Ÿ’€.

Including the Bundle Security Protocol in any Bundle Protocol implementation is RECOMMENDED ๐Ÿ‘‘. Using the Bundle Security Protocol in Bundle Protocol operations is OPTIONAL ๐ŸŒธ.


9. IANA Considerations ๐ŸŒท

The "dtn:" URI scheme has been provisionally registered by IANA ๐ŸŽ‰. For the latest details, check http://www.iana.org/assignments/uri-schemes.html.


10. References ๐Ÿ“š

10.1. Normative References

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

[URI]      Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
           Resource Identifier (URI): Generic Syntax", RFC 3986,
           STD 66, January 2005.

[URIREG]   Hansen, T., Hardie, T., and L. Masinter, "Guidelines and
           Registration Procedures for New URI Schemes", RFC 4395,
           BCP 115, February 2006.

10.2. Informative References

[ARCH]     V. Cerf et. al., "Delay-Tolerant Network Architecture",
           RFC 4838, April 2007.

[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", 2003.

[BSP]      Symington, S., "Bundle Security Protocol Specification",
           Work Progress, October 2007.

[RFC3987]  Duerst, M. and M. Suignard, "Internationalized Resource
           Identifiers (IRIs)", RFC 3987, January 2005.

[SECO]     Farrell, S., Symington, S., Weiss, H., and P. Lovell,
           "Delay-Tolerant Networking Security Overview",
           Work Progress, July 2007.

[SIGC]     Fall, K., "A Delay-Tolerant Network Architecture for
           Challenged Internets", SIGCOMM 2003 .

[TUT]      Warthman, F., "Delay-Tolerant Networks (DTNs): A
           Tutorial", <http://www.dtnrg.org>.

[UTC]      Arias, E. and B. Guinot, ""Coordinated universal time UTC:
           historical background and perspectives" in Journees
           systemes de reference spatio-temporels", 2004.

Appendix A. Contributors ๐Ÿซถ

This was an effort of the Delay Tolerant Networking Research Group, and these DTNRG folks contributed significant technical material and/or inputs ๐Ÿ’œ:

  • Dr. Vinton Cerf of Google
  • Scott Burleigh, Adrian Hooke, and Leigh Torgerson of the Jet Propulsion Laboratory
  • Michael Demmer of the University of California at Berkeley
  • Robert Durst, Keith Scott, and Susan Symington of The MITRE Corporation
  • Kevin Fall of Intel Research
  • Stephen Farrell of Trinity College Dublin
  • Peter Lovell of SPARTA, Inc.
  • Manikantan Ramadas of Ohio University (most of Section 4.1)
  • Howard Weiss of SPARTA, Inc. (text of Section 8)

Iconic team, honestly ๐Ÿ‘‘.


Appendix B. Comments ๐Ÿ’Œ

Please refer comments to dtn-interest@mailman.dtnrg.org. The Delay Tolerant Networking Research Group (DTNRG) Web site is at http://www.dtnrg.org. ๐ŸŒˆ


Authors' Addresses ๐Ÿก

Keith L. Scott
The MITRE Corporation
7515 Colshire Drive
McLean, VA  21102
US

Phone: +1 703 983 6547
Fax:   +1 703 983 7142
EMail: kscott@mitre.org


Scott Burleigh
NASA Jet Propulsion Laboratory
4800 Oak Grove Dr.
Pasadena, CA  91109-8099
US

Phone: +1 818 393 3353
Fax:   +1 818 354 1075
EMail: Scott.Burleigh@jpl.nasa.gov

Copyright (C) The IETF Trust (2007) ๐Ÿฉท. This document is subject to the rights, licenses and restrictions contained in BCP 78 and at www.rfc-editor.org/copyright.html, and except as set forth there, the authors keep all their rights.

This document and the information in it 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 on the validity or scope of any Intellectual Property Rights or other rights that might be claimed to apply to the implementation or use of the technology in this document, or on whether any license under those rights might be available. It also doesn't claim to have made any independent effort to identify such rights. Info on how rights work for RFC documents is in BCP 78 and BCP 79 ๐Ÿ“–.

Copies of IPR disclosures made to the IETF Secretariat, any assurances of licenses to be made available, and the results of any attempt to get a general license or permission to use those proprietary rights for implementers or users of this specification can be found in the IETF online 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 needed to implement this standard. Send that info to the IETF at ietf-ipr@ietf.org ๐Ÿ’–.

๐Ÿ“ฆ where this page comes from