Delay-Tolerant Networking TCP Convergence-Layer Protocol Version 4
Extracted elements (30)
Once established, TCPCL session parameters cannot change; a new TCP connection and session must be established to use different parameters. This simplifies convergence-layer logic and relies on the assumption that TCP connection establishment overhead is negligible compared to TCPCL data transfer sizes.
Segments from different bundles are never interleaved on a single TCPCL transfer stream; transfers are serialized. Bundle interleaving requires either BP-layer fragmentation or establishing multiple concurrent TCPCL sessions between the same peers. This avoids complex stream-multiplexing state in the convergence layer.
XFER_ACK messages are not used for flow control (there is no explicit flow control in TCPCL) but to support reactive fragmentation: by tracking the cumulative acknowledged length, a transmitting BPA that must interrupt a transfer can avoid resending the portion already confirmed as received by the peer.
TCPCLv4 can coexist on a network with TCPCLv3 (RFC 7242) entities through Contact Header version negotiation. If the active entity receives a SESS_TERM with reason 'Version mismatch', it MAY retry using decreasing version numbers. A passive entity receiving an unsupported version SHALL terminate with 'Version mismatch' or may adapt to an older version at its discretion.
All integer encodings in the TCPCL protocol SHALL be transmitted in network byte order (most significant byte first, big endian).
All TCPCL end-entity certificates SHALL conform to RFC 5280 and SHALL be version 3; entities SHALL reject version 1 and version 2 end-entity certificates. Unless prohibited by CA policy, a TCPCL end-entity certificate SHALL contain a NODE-ID (subjectAltName otherName of type id-on-bundleEID) authenticating the peer's node ID.
During contact initiation, the active TCPCL entity SHALL send the highest TCPCL protocol version on a first session attempt. If it receives a lower version in response, the TCP connection SHALL be closed. If the passive entity receives an unrecognized version, it SHALL send its Contact Header and immediately terminate with reason code 'Version mismatch'.
Enable TLS is negotiated by the logical AND of the two CAN_TLS flags. The RECOMMENDED policy is to require TLS for all sessions. If the negotiated Enable TLS state is unacceptable per local security policy, the entity SHALL terminate the session with reason code 'Contact Failure'.
For any peer end-entity certificate received during the TLS handshake, the entity SHALL perform certification path validation per RFC 5280. If OCSP is enabled by local policy, an OCSP check SHALL be performed for each certificate. If validation fails, the entity SHALL fail the TLS handshake with a 'bad_certificate' alert.
Immediately before session parameter negotiation, each entity SHALL validate the NODE-ID from the peer's SESS_INIT against the peer's certificate using RFC 6125 logic. If NODE-ID validation is Failure, or Absent when security policy requires it, the entity SHALL terminate the session with reason code 'Contact Failure'.
The active entity SHALL transmit its Contact Header immediately upon TCP connection establishment; the passive entity SHALL wait, then reply with its own Contact Header. If either entity does not receive a Contact Header within an implementation-defined timeout (SHOULD be no longer than 60 seconds), the waiting entity SHALL close the TCP connection.
When Enable TLS is negotiated to true, entities SHALL begin a TLS 1.3 handshake (RFC 8446) before any other TCPCL messages. Any TCPCL entity SHALL follow all recommended practices in BCP 195 (RFC 7525). The passive entity SHALL request a client-side certificate; the active entity SHALL supply a certificate chain.
When retrying a failed TCP connection, an entity MUST NOT retry earlier than some delay from the last attempt and SHOULD use exponential backoff. The upper backoff limit SHOULD be no longer than 60 seconds before signaling to the BPA that a connection cannot be made.
TCPCL session establishment exposes each entity's node ID to its peer via SESS_INIT, and TLS handshake metadata (certificates, SNI HostName) may leak identity information before full encryption is established. A TCPCL entity MAY send a zero-length Node ID Data field in SESS_INIT to avoid exposing its node ID on untrusted networks.
A Transfer ID is a numeric identifier for each bundle transfer, guaranteed unique only within a single direction of a single TCPCL session. The Transfer ID appears in XFER_SEGMENT, XFER_ACK, and XFER_REFUSE messages to correlate segments, acknowledgments, and refusals to their bundle transfer.
KEEPALIVE (message type 0x04) is sent during idle sessions at the negotiated Session Keepalive interval to signal entity liveness when no data is being transferred. A negotiated Session Keepalive of zero disables KEEPALIVE messages entirely.
MSG_REJECT (message type 0x06) allows a TCPCL entity to reject a received message it cannot process or does not recognize, conveying a numeric reason code. It provides a mechanism for signaling unknown or malformed messages without immediately terminating the session.
SESS_TERM (message type 0x05) initiates clean session termination. The initiating entity sends SESS_TERM and enters the Ending substate; the responding entity replies with its own SESS_TERM. In-progress transfers may complete during the Ending state, but no new transfers may be started.
Session Extension Items are carried in the SESS_INIT message as a variable-length list (prefixed by a U32 length). Each item uses a consistent container encoding defined in Section 4.8. Extension items apply for the full duration of the TCPCL session; their order and multiplicity are significant per their type specification.
XFER_REFUSE (message type 0x03) is sent by the receiver to interrupt an in-progress bundle transfer; the sender SHALL stop transmission of the associated bundle. This enables cross-layer optimization where a receiver that already holds the bundle can abort redundant retransmission early.
RFC 9174 creates or updates the following IANA registries: TCPCLv4 registered port 4556, Protocol Versions, Session Extension Types, Transfer Extension Types, Message Types, XFER_REFUSE Reason Codes, SESS_TERM Reason Codes, MSG_REJECT Reason Codes, and PKIX OIDs for the BundleEID Other Name Form (id-on-bundleEID) and the id-kp-bundleSecurity Extended Key Usage.
BP Node Impersonation threat: when using DTN-ignorant CAs that cannot issue certificates binding a node ID, the peer's node ID in SESS_INIT cannot be cryptographically verified. This allows any peer holding a valid network-level certificate to claim an arbitrary node ID. DTN-aware CA certificates providing NODE-ID validation are the preferred mitigation.
TLS 1.3 (RFC 8446) with mutual certificate authentication is mandatory to implement for TCPCLv4. All TCPCL entities must support TLS regardless of whether authentication is enforced by local policy, ensuring that opportunistic encryption is always available even when full authentication is not required.
TLS Stripping threat: since the CAN_TLS flag is exchanged over an unsecured TCP connection, an active on-path attacker can clear the flag to downgrade a session to non-TLS. The recommended mitigation is a local policy that requires TLS, causing the entity to terminate any session where Enable TLS negotiates to false.
Top-level TCPCL session states: START → TCP Connected → Contact/Session Negotiation → Established (with Idle, Live, and Ending substates) → TCP Terminating → END. The Ending substate is entered when a SESS_TERM is sent; no new transfers may be initiated in this state, though in-progress transfers may complete.
Transfer receiver states: Stream Idle → In Progress (triggered by receiving any XFER_SEGMENT; XFER_ACK is sent for each segment received, looping until final segment) → Stream Idle (triggered by sending the final XFER_ACK after the END-flagged segment).
Transfer sender states: Stream Idle → In Progress (triggered by first XFER_SEGMENT transmission; loops on additional segments) → Waiting for Ack (after all segments sent) → Stream Idle (triggered by receipt of final XFER_ACK). Pipelining is permitted by starting a new transfer while in Waiting for Ack.
All post-contact-negotiation TCPCL messages begin with a 1-octet Message Header carrying a Message Type field. Defined types are XFER_SEGMENT (0x01), XFER_ACK (0x02), XFER_REFUSE (0x03), KEEPALIVE (0x04), SESS_TERM (0x05), MSG_REJECT (0x06), and SESS_INIT (0x07).
The Contact Header is a 6-octet structure: a 4-octet magic field containing 'dtn!' (0x64 0x74 0x6E 0x21), a 1-octet Version field (value 4 for TCPCLv4), and a 1-octet Flags field where bit 0x01 is the CAN_TLS flag. Reserved flag bits SHALL be set to 0 by the sender and SHALL be ignored by the receiver.
The SESS_INIT message contains: Message Header (1 octet), Keepalive Interval (U16, seconds), Segment MRU (U64, bytes), Transfer MRU (U64, bytes), Node ID Length (U16), Node ID Data (variable, UTF-8), Session Extension Items Length (U32), and Session Extension Items (variable). A zero-length Node ID Data indicates the absence of a node ID.