From 3f0745c19a9d638a4cdbc2436bde1c05f5a18a8d Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Fri, 23 May 2025 21:53:42 -0700 Subject: [PATCH 1/4] datagrams: Add initial datagram draft --- datagrams/datagrams.md | 75 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 datagrams/datagrams.md diff --git a/datagrams/datagrams.md b/datagrams/datagrams.md new file mode 100644 index 000000000..2dff7b600 --- /dev/null +++ b/datagrams/datagrams.md @@ -0,0 +1,75 @@ +# Datagrams in libp2p + +| Lifecycle Stage | Maturity | Status | Latest Revision | +| --------------- | ------------- | ------ | --------------- | +| 1A | Working Draft | Active | r0, 2025-05-23 | + +Authors: [@marcopolo] + +Interest Group: [@sukunrt], [@jxs], [@raulk] + +[@marcopolo]: https://github.com/marcopolo +[@sukunrt]: https://github.com/sukunrt +[@jxs]: https://github.com/jxs +[@raulk]: https://github.com/raulk + +See the [lifecycle document][lifecycle-spec] for context about the maturity level +and spec status. + +[lifecycle-spec]: https://github.com/libp2p/specs/blob/master/00-framework-01-spec-lifecycle.md + +## Table of Contents + +- [Introduction](#introduction) +- [Native support at the transport level](#native-support-at-the-transport-level) +- [Encoding Datagrams](#encoding-datagrams) +- [Datagrams on top of a multiplexed stream on top of TCP](#datagrams-on-top-of-a-multiplexed-stream-on-top-of-tcp) +- [Datagrams with WebRTC](#datagrams-with-webrtc) + +## Introduction + +This specification defines the datagrams on libp2p, which enable the +transmission of MTU-sized, unreliable, and low latency messages between peers. + +TODO write more about the tradeoffs here as well as the kinds of applications that would benefit from using datagrams. + +## Native support at the transport level + +Some libp2p transports natively support datagrams, such as QUIC and WebTransport. libp2p implementations MUST use the native datagram support to send datagrams. + +QUIC has an Unreliable Datagram Extension [RFC 9221] +WebTransport supports Datagrams though HTTP Datagrams [WebTransport draft RFC](https://www.ietf.org/archive/id/draft-ietf-webtrans-http3-12.html#name-datagrams) + +## Encoding Datagrams + +The libp2p datagram encoding introduces minimal framing overhead to application payloads. Each datagram MUST be encoded with the following structure to ensure proper protocol identification and version compatibility. + +The datagram frame consists of the following components: + +| Field Name | Data Type | Length (bits) | Description | +| ------------------ | ---------------- | ------------- | ---------------------------------------------------- | +| version | unsigned integer | 8 | Protocol version identifier | +| protocol id length | [uvarint] | 8..72 | Length of the protocol identifier field | +| protocol id | byte sequence | variable | Protocol identifier as defined by protocol id length | +| application data | byte sequence | variable | Application payload | + +The complete datagram frame is constructed as follows: + +``` +version || protocol id length || protocol id || application data +``` + +Where "||" denotes byte concatenation. + +The version field provides extensibility for future encoding modifications while maintaining backward compatibility. Implementations MUST verify the version field before processing the remainder of the datagram. + +## Datagrams on top of a multiplexed stream on top of TCP + +This is currently not specified. + +## Datagrams with WebRTC + +This is currently not specified. + +[uvarint]: https://github.com/multiformats/unsigned-varint +[RFC 9221]: https://www.rfc-editor.org/rfc/rfc9221 From c4217cd6f3d3bf90b928667a63a612d4f353afe9 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Tue, 27 May 2025 18:13:47 -0700 Subject: [PATCH 2/4] Update spec to use stream ID pointer as protocol ID and version --- datagrams/datagrams.md | 72 +++++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 22 deletions(-) diff --git a/datagrams/datagrams.md b/datagrams/datagrams.md index 2dff7b600..af16ec8e0 100644 --- a/datagrams/datagrams.md +++ b/datagrams/datagrams.md @@ -22,46 +22,74 @@ and spec status. - [Introduction](#introduction) - [Native support at the transport level](#native-support-at-the-transport-level) -- [Encoding Datagrams](#encoding-datagrams) +- [Datagrams on QUIC](#datagrams-on-quic) + - [Encoding](#encoding) +- [Datagrams on WebTransport](#datagrams-on-webtransport) - [Datagrams on top of a multiplexed stream on top of TCP](#datagrams-on-top-of-a-multiplexed-stream-on-top-of-tcp) - [Datagrams with WebRTC](#datagrams-with-webrtc) ## Introduction -This specification defines the datagrams on libp2p, which enable the -transmission of MTU-sized, unreliable, and low latency messages between peers. +This specification defines libp2p datagrams, which enable the transmission of +MTU-sized, unreliable, and low latency messages between peers. TODO write more about the tradeoffs here as well as the kinds of applications that would benefit from using datagrams. ## Native support at the transport level -Some libp2p transports natively support datagrams, such as QUIC and WebTransport. libp2p implementations MUST use the native datagram support to send datagrams. +Some libp2p transports natively support datagrams, such as QUIC and +WebTransport. libp2p implementations MUST use the native datagram support to +send datagrams. -QUIC has an Unreliable Datagram Extension [RFC 9221] -WebTransport supports Datagrams though HTTP Datagrams [WebTransport draft RFC](https://www.ietf.org/archive/id/draft-ietf-webtrans-http3-12.html#name-datagrams) +- QUIC has an Unreliable Datagram Extension [RFC 9221]. +- WebTransport supports Datagrams though HTTP Datagrams [WebTransport draft RFC](https://www.ietf.org/archive/id/draft-ietf-webtrans-http3-12.html#name-datagrams) -## Encoding Datagrams +## Datagrams on QUIC -The libp2p datagram encoding introduces minimal framing overhead to application payloads. Each datagram MUST be encoded with the following structure to ensure proper protocol identification and version compatibility. +Each datagram flow MUST be associated with a control stream. A datagram flow is +defined as a logical flow of datagrams for a specific application protocol. A +control stream is a QUIC bidirectional stream that has negotiated the application +protocol ID. The control stream MUST stay open for the duration of the datagram +flow. Implementation MAY create the control stream and start sending datagrams +at once. -The datagram frame consists of the following components: +There is currently no other use for the control stream besides negotiating the +application protocol ID. -| Field Name | Data Type | Length (bits) | Description | -| ------------------ | ---------------- | ------------- | ---------------------------------------------------- | -| version | unsigned integer | 8 | Protocol version identifier | -| protocol id length | [uvarint] | 8..72 | Length of the protocol identifier field | -| protocol id | byte sequence | variable | Protocol identifier as defined by protocol id length | -| application data | byte sequence | variable | Application payload | +Receipt of a QUIC DATAGRAM frame whose payload is too short to allow parsing the +Control Stream ID field MUST be treated as a connection error of type +PROTOCOL_VIOLATION (0x1003). -The complete datagram frame is constructed as follows: +libp2p datagrams MUST NOT be sent unless the control stream's send side is +open. If a datagram is received after the corresponding stream's receive side is +closed, the received datagrams MUST be silently dropped. -``` -version || protocol id length || protocol id || application data -``` +If a libp2p datagram is received and its Control Stream ID field maps to a +stream that has not yet been created, the receiver SHALL either drop that +datagram silently or buffer it temporarily (on the order of a round trip) while +awaiting the creation of the corresponding stream. -Where "||" denotes byte concatenation. +If a libp2p datagram is received and its Control Stream ID field maps to a +stream that cannot be created due to client-initiated bidirectional stream +limits, it MUST be treated as a connection error of type PROTOCOL_VIOLATION +(0x1003). -The version field provides extensibility for future encoding modifications while maintaining backward compatibility. Implementations MUST verify the version field before processing the remainder of the datagram. +### Encoding + +Each libp2p datagram SHALL be encoded with the following structure. + +| Field Name | Data Type | Length (bits) | Description | +| ---------------- | ------------- | ------------- | --------------------------------------------------------------------- | +| Control StreamID | [QUIC varint] | 8..64 | The stream ID of the associated control stream for this datagram flow | +| Application Data | byte sequence | variable | Application payload | + +## Datagrams on WebTransport + +libp2p datagrams on WebTransport behave the same as libp2p datagrams on QUIC. +However, the application data may be further limited by the overhead of HTTP +Datagram's Quarter Stream ID field. + +In the future, a separate spec may be able to remove this overhead. ## Datagrams on top of a multiplexed stream on top of TCP @@ -71,5 +99,5 @@ This is currently not specified. This is currently not specified. -[uvarint]: https://github.com/multiformats/unsigned-varint [RFC 9221]: https://www.rfc-editor.org/rfc/rfc9221 +[QUIC varint]: https://www.rfc-editor.org/rfc/rfc9000.html#name-variable-length-integer-enc From 6442799865af6e61a94971adb3141629586bfd55 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Wed, 28 May 2025 08:25:25 -0700 Subject: [PATCH 3/4] Specify control stream protocol id --- datagrams/datagrams.md | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/datagrams/datagrams.md b/datagrams/datagrams.md index af16ec8e0..754c9d075 100644 --- a/datagrams/datagrams.md +++ b/datagrams/datagrams.md @@ -47,21 +47,18 @@ send datagrams. ## Datagrams on QUIC Each datagram flow MUST be associated with a control stream. A datagram flow is -defined as a logical flow of datagrams for a specific application protocol. A -control stream is a QUIC bidirectional stream that has negotiated the application -protocol ID. The control stream MUST stay open for the duration of the datagram -flow. Implementation MAY create the control stream and start sending datagrams -at once. - -There is currently no other use for the control stream besides negotiating the -application protocol ID. - -Receipt of a QUIC DATAGRAM frame whose payload is too short to allow parsing the -Control Stream ID field MUST be treated as a connection error of type -PROTOCOL_VIOLATION (0x1003). - -libp2p datagrams MUST NOT be sent unless the control stream's send side is -open. If a datagram is received after the corresponding stream's receive side is +defined as a logical flow of datagrams related to a specific application +protocol. A control stream is a QUIC bidirectional stream that has negotiated +the libp2p datagram control stream protocol ID `/dg/1`. The initiator MUST send +the related application protocol ID related to the datagram flow after +negotiating the control stream. The control stream MUST stay open for the +duration of the datagram flow. Implementation MAY create the control stream and +start sending datagrams at once. There is currently no other use for the control +stream besides negotiating the application protocol ID. Receipt of a QUIC +DATAGRAM frame whose payload is too short to allow parsing the Control Stream ID +field MUST be treated as a connection error of type PROTOCOL_VIOLATION (0x1003). +libp2p datagrams MUST NOT be sent unless the control stream's send side is open. +If a datagram is received after the corresponding stream's receive side is closed, the received datagrams MUST be silently dropped. If a libp2p datagram is received and its Control Stream ID field maps to a From 1b5c1107f4fcc1e2c7b54bab92de82370a6c45f3 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Wed, 28 May 2025 08:28:20 -0700 Subject: [PATCH 4/4] Specify uvarint length prefix --- datagrams/datagrams.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/datagrams/datagrams.md b/datagrams/datagrams.md index 754c9d075..fb77899ca 100644 --- a/datagrams/datagrams.md +++ b/datagrams/datagrams.md @@ -50,7 +50,7 @@ Each datagram flow MUST be associated with a control stream. A datagram flow is defined as a logical flow of datagrams related to a specific application protocol. A control stream is a QUIC bidirectional stream that has negotiated the libp2p datagram control stream protocol ID `/dg/1`. The initiator MUST send -the related application protocol ID related to the datagram flow after +the related application protocol ID with a [uvarint] length prefix after negotiating the control stream. The control stream MUST stay open for the duration of the datagram flow. Implementation MAY create the control stream and start sending datagrams at once. There is currently no other use for the control @@ -98,3 +98,4 @@ This is currently not specified. [RFC 9221]: https://www.rfc-editor.org/rfc/rfc9221 [QUIC varint]: https://www.rfc-editor.org/rfc/rfc9000.html#name-variable-length-integer-enc +[uvarint]: https://github.com/multiformats/unsigned-varint