diff --git a/draft-lcurley-moq-lite.md b/draft-lcurley-moq-lite.md index 864c708..f11079c 100644 --- a/draft-lcurley-moq-lite.md +++ b/draft-lcurley-moq-lite.md @@ -20,6 +20,7 @@ normative: moqt: I-D.ietf-moq-transport qmux: I-D.ietf-quic-qmux RFC1951: + RFC7692: RFC3986: RFC6455: RFC9002: @@ -296,6 +297,9 @@ When the stream is closed, the subscriber MUST assume that all broadcasts are no Path prefix matching and equality is done on a byte-by-byte basis. There MAY be multiple Announce Streams, potentially containing overlapping prefixes, that get their own ANNOUNCE_OK + ANNOUNCE_BROADCAST messages. +The compression context for ANNOUNCE_BROADCAST payloads is retained across messages on the same Announce Stream, so separate messages still benefit from repeated path components and Hop ID lists. +The publisher flushes the compressor after each ANNOUNCE_BROADCAST, allowing the subscriber to decode each announcement as soon as its message bytes arrive. +For this reason, batching multiple path changes into one ANNOUNCE_BROADCAST is not needed for compression; `Active Count` provides application-level batching for the initial set while preserving one state change per ANNOUNCE_BROADCAST message. ### Subscribe A subscriber opens Subscribe Streams to request a Track. @@ -680,6 +684,10 @@ An ANNOUNCE_BROADCAST before ANNOUNCE_OK is a protocol violation. ~~~ ANNOUNCE_BROADCAST Message { Message Length (i) + Compressed Payload (..) +} + +ANNOUNCE_BROADCAST Payload { Announce Status (i), Broadcast Path Suffix (s), Hop Count (i), @@ -687,6 +695,12 @@ ANNOUNCE_BROADCAST Message { } ~~~ +**Message Length**: +The number of bytes in `Compressed Payload`. + +**Compressed Payload**: +The compressed form of `ANNOUNCE_BROADCAST Payload`, as described in [Compressed ANNOUNCE_BROADCAST Payloads](#compressed-announce-broadcast-payloads). + **Announce Status**: A flag indicating the announce status. @@ -708,6 +722,21 @@ When forwarding an announcement received from an upstream peer, a relay MUST app The total path length is `Hop Count + 1` (including the implicit ANNOUNCE_OK `Hop ID`). A Hop ID value of 0 means the hop is unknown: either it was never assigned (e.g. when bridging from an older protocol version) or a relay deliberately withholds it to obscure the underlying routing; the Hop Count still reflects the total number of entries including unknown hops. +### Compressed ANNOUNCE_BROADCAST Payloads {#compressed-announce-broadcast-payloads} +ANNOUNCE_BROADCAST compresses the entire message payload, excluding only the `Message Length` field. +The uncompressed input is exactly the `ANNOUNCE_BROADCAST Payload` encoding defined above. + +Compression uses the DEFLATE format [RFC1951] with a single compression context per Announce Stream. +The context is initialized immediately after ANNOUNCE_OK and is retained until the Announce Stream closes. +For each ANNOUNCE_BROADCAST, the publisher feeds the uncompressed payload bytes into that context and then performs the equivalent of `Z_SYNC_FLUSH`. +A sync flush produces output ending with the fixed four-byte marker `00 00 ff ff`; the publisher MUST remove this marker before writing the compressed bytes into `Compressed Payload`, matching WebSocket compression [RFC7692]. + +The subscriber uses a single decompression context per Announce Stream. +Before inflating each `Compressed Payload`, the subscriber appends the four bytes `00 00 ff ff` to reconstruct the sync-flushed DEFLATE stream. +After reading `Compressed Payload`, the subscriber inflates it using the retained context and parses the resulting bytes as `ANNOUNCE_BROADCAST Payload`. +The decompressed payload MUST be a valid `ANNOUNCE_BROADCAST Payload`; otherwise, the subscriber MUST reset the Announce Stream with a PROTOCOL_VIOLATION. +If decompression fails, the subscriber MUST reset the Announce Stream with a PROTOCOL_VIOLATION. + ## SUBSCRIBE SUBSCRIBE is sent by a subscriber to start a subscription. @@ -1035,6 +1064,7 @@ The `Message Length` describes the payload size on the wire. - Added QUIC datagram delivery for groups. - Dropped the `Subscriber` prefix from fields that exist on only one side. - Added Qmux [qmux] transport bindings for TCP/TLS and WebSocket. +- Added mandatory DEFLATE compression for ANNOUNCE_BROADCAST payloads. ## moq-lite-04 - Renamed ANNOUNCE_PLEASE to ANNOUNCE_REQUEST. diff --git a/draft-lcurley-moq-namespace-compression.md b/draft-lcurley-moq-namespace-compression.md new file mode 100644 index 0000000..d471ba7 --- /dev/null +++ b/draft-lcurley-moq-namespace-compression.md @@ -0,0 +1,146 @@ +--- +title: "MoQ Namespace Compression Extension" +abbrev: "moq-namespace-compression" +category: info + +docname: draft-lcurley-moq-namespace-compression-latest +submissiontype: IETF # also: "independent", "editorial", "IAB", or "IRTF" +number: +date: +v: 3 +area: wit +workgroup: moq + +author: + - + fullname: Luke Curley + email: kixelated@gmail.com + +normative: + moqt: I-D.ietf-moq-transport + RFC1951: + RFC7692: + +informative: + +--- abstract + +This document defines an extension for MoQ Transport {{moqt}} that compresses namespace advertisements sent in response to SUBSCRIBE_NAMESPACE. +The extension defines a namespace suffix compression negotiation and a DEFLATE compression algorithm for the Track Namespace Suffix carried by NAMESPACE and NAMESPACE_DONE messages, retaining compression context across messages on the same namespace subscription response stream and flushing after each message. + +--- middle + +# Conventions and Definitions +{::boilerplate bcp14-tagged} + + +# Introduction + +MoQ Transport {{moqt}} lets a subscriber discover published namespaces by sending SUBSCRIBE_NAMESPACE. +The publisher responds with NAMESPACE messages for matching namespaces and NAMESPACE_DONE messages when a matching namespace is no longer available. + +In applications with many live publishers, these namespace suffixes often share repeated structure, such as room identifiers, participant identifiers, or media role names. +This extension compresses only the Track Namespace Suffix field of NAMESPACE and NAMESPACE_DONE messages. +The rest of the control message framing remains unchanged, allowing each namespace change to remain an independent protocol event. + +The compression model intentionally mirrors WebSocket per-message compression {{RFC7692}}: compressed data is flushed at each message boundary so the receiver can process each message immediately, and the fixed sync-flush marker is removed from the bytes carried on the wire. + + +# Setup Negotiation + +The Namespace Compression extension is negotiated during the SETUP exchange as defined in {{moqt}} Section 10.3. +An endpoint indicates support by including the following Setup Option: + +~~~ +NAMESPACE_COMPRESSION Setup Option { + Option Key (vi64) = 0x40B59 + Option Value Length (vi64) + Namespace Compression Algorithm (vi64) +} +~~~ + +**Namespace Compression Algorithm**: +The namespace suffix compression algorithm supported by the endpoint. + +- `deflate` (0): DEFLATE compression as defined in [Compressed Suffix Encoding](#compressed-suffix-encoding). + +The Option Value MUST contain exactly one Namespace Compression Algorithm. +An endpoint that receives an unknown Namespace Compression Algorithm MUST close the session with PROTOCOL_VIOLATION. + +If both endpoints include NAMESPACE_COMPRESSION with the same Namespace Compression Algorithm, then namespace suffix compression is negotiated for the session. +When namespace suffix compression is negotiated, every NAMESPACE and NAMESPACE_DONE message sent in response to SUBSCRIBE_NAMESPACE on the session MUST encode its Track Namespace Suffix using the negotiated algorithm. +If either endpoint omits NAMESPACE_COMPRESSION, namespace suffix compression is not negotiated and NAMESPACE and NAMESPACE_DONE use the encoding defined by {{moqt}}. + +The extension applies to a single hop and is negotiated independently for each session. +A relay MUST NOT assume support on one session implies support on another. + + +# Compressed Namespace Suffixes + +This extension does not define new message types and does not otherwise replace the NAMESPACE or NAMESPACE_DONE message definitions in {{moqt}}. +Instead, when namespace suffix compression is negotiated, only the Track Namespace Suffix field in each NAMESPACE and NAMESPACE_DONE message is compressed. +All other fields and any future fields in those messages retain the encoding defined by {{moqt}} or by the extension that defines them. + +**Track Namespace Suffix**: +When namespace suffix compression is negotiated, this field carries the compressed form of the Track Namespace Suffix value. +The uncompressed bytes are exactly the Track Namespace Suffix encoding defined by {{moqt}}, excluding the field's own length prefix if the base encoding supplies one. + +After decompression, the receiver parses the resulting bytes as a Track Namespace Suffix. +If decompression fails, or if the decompressed bytes are not a valid Track Namespace Suffix, the receiver MUST close the session with PROTOCOL_VIOLATION. + + +# Compressed Suffix Encoding +{: #compressed-suffix-encoding} + +The `deflate` Namespace Compression Algorithm uses the DEFLATE format {{RFC1951}} with one compression context per SUBSCRIBE_NAMESPACE response stream. +The context is initialized when the publisher accepts the SUBSCRIBE_NAMESPACE request and is retained until the response stream is closed. + +For each NAMESPACE or NAMESPACE_DONE message, the publisher feeds the uncompressed Track Namespace Suffix bytes into that stream's compression context and then performs the equivalent of `Z_SYNC_FLUSH`. +A sync flush produces output ending with the fixed four-byte marker `00 00 ff ff`; the publisher MUST remove this marker before writing the compressed bytes into the Track Namespace Suffix field. + +The subscriber uses one decompression context for the same response stream. +Before inflating each compressed Track Namespace Suffix, the subscriber appends the four bytes `00 00 ff ff` to reconstruct the sync-flushed DEFLATE stream. +Because the publisher flushes after every NAMESPACE or NAMESPACE_DONE message, the subscriber can decompress and process each namespace update as soon as that message is received. +The flush does not reset the compression context, so repeated namespace components in later messages can reference bytes from earlier messages on the same response stream. + + +# Security Considerations + +This extension adds stateful decompression to namespace discovery. +Implementations SHOULD bound the amount of memory and CPU used for each compression context and SHOULD apply the same limits to decompressed namespace suffixes that they apply to uncompressed suffixes. + +Compression can reveal information through compressed sizes when an attacker can influence namespace names and observe response sizes. +Applications that consider namespace names sensitive SHOULD avoid enabling this extension across trust boundaries, or partition namespace subscriptions so attacker-controlled and secret namespace components do not share a compression context. + +Malformed compressed data is a protocol violation. +Repeated decompression failures can be used as a denial-of-service signal and MAY be rate limited or logged by implementations. + + +# IANA Considerations + +This document requests the following registrations. +High, distinctive values are requested to avoid the low ranges reserved by {{moqt}} and to minimize collisions with provisional registrations by other extensions; they also avoid the greasing pattern (`0x7f * N + 0x9D`). + +## MOQT Setup Options + +This document requests a registration in the "MOQT Setup Options" registry ({{moqt}} Section 15.4), whose policy is Specification Required. + +| Value | Name | Reference | +|:--------|:------------------|:--------------| +| 0x40B59 | NAMESPACE_COMPRESSION | This Document | + +## MOQT Namespace Compression Algorithms + +This document requests a new "MOQT Namespace Compression Algorithms" registry, whose policy is Specification Required. + +| Value | Name | Reference | +|:------|:--------|:--------------| +| 0 | DEFLATE | This Document | + + +--- back + +# Acknowledgments +{:numbered="false"} + +This document was drafted with the assistance of AI tools.