From 8dca396c36377bd6eec54b8b3fd743a21f6f2258 Mon Sep 17 00:00:00 2001 From: ID Bot Date: Sun, 2 Mar 2025 19:05:10 +0000 Subject: [PATCH] Script updating gh-pages from f1c1215. [ci skip] --- .../draft-ietf-moq-transport.html | 5151 +++++++++++++++++ .../draft-ietf-moq-transport.txt | 3057 ++++++++++ ianswett-move-connection-url/index.html | 45 + index.html | 8 + 4 files changed, 8261 insertions(+) create mode 100644 ianswett-move-connection-url/draft-ietf-moq-transport.html create mode 100644 ianswett-move-connection-url/draft-ietf-moq-transport.txt create mode 100644 ianswett-move-connection-url/index.html diff --git a/ianswett-move-connection-url/draft-ietf-moq-transport.html b/ianswett-move-connection-url/draft-ietf-moq-transport.html new file mode 100644 index 00000000..0259b137 --- /dev/null +++ b/ianswett-move-connection-url/draft-ietf-moq-transport.html @@ -0,0 +1,5151 @@ + + + + + + +Media over QUIC Transport + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Internet-Draftmoq-transportMarch 2025
Curley, et al.Expires 3 September 2025[Page]
+
+
+
+
Workgroup:
+
Media Over QUIC
+
Internet-Draft:
+
draft-ietf-moq-transport-latest
+
Published:
+
+ +
+
Intended Status:
+
Standards Track
+
Expires:
+
+
Authors:
+
+
+
L. Curley
+
Discord
+
+
+
K. Pugin
+
Meta
+
+
+
S. Nandakumar
+
Cisco
+
+
+
V. Vasiliev
+
Google
+
+
+
I. Swett, Ed. +
+
Google
+
+
+
+
+

Media over QUIC Transport

+
+

Abstract

+

This document defines the core behavior for Media over QUIC Transport +(MOQT), a media transport protocol designed to operate over QUIC and +WebTransport, which have similar functionality. MOQT allows a producer of +media to publish data and have it consumed via subscription by a +multiplicity of endpoints. It supports intermediate content distribution +networks and is designed for high scale and low latency distribution.

+
+
+

+About This Document +

+

This note is to be removed before publishing as an RFC.

+

+ The latest revision of this draft can be found at https://moq-wg.github.io/moq-transport/draft-ietf-moq-transport.html. + Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-moq-transport/.

+

+ Discussion of this document takes place on the + Media Over QUIC Working Group mailing list (mailto:moq@ietf.org), + which is archived at https://mailarchive.ietf.org/arch/browse/moq/. + Subscribe at https://www.ietf.org/mailman/listinfo/moq/.

+

Source for this draft and an issue tracker can be found at + https://github.com/moq-wg/moq-transport.

+
+
+
+

+Status of This Memo +

+

+ This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79.

+

+ Internet-Drafts are working documents of the Internet Engineering Task + Force (IETF). Note that other groups may also distribute working + documents as Internet-Drafts. The list of current Internet-Drafts is + at https://datatracker.ietf.org/drafts/current/.

+

+ Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress."

+

+ This Internet-Draft will expire on 3 September 2025.

+
+
+ +
+
+

+Table of Contents +

+ +
+
+
+
+

+1. Introduction +

+

Media Over QUIC Transport (MOQT) is a protocol that is optimized +for the QUIC protocol [QUIC], either directly or via WebTransport +[WebTransport], for the dissemination of media. MOQT utilizes a +publish/subscribe workflow in which producers of media publish data in +response to subscription requests from a multiplicity of endpoints. MOQT +supports wide range of use-cases with different resiliency and latency +(live, interactive) needs without compromising the scalability and cost +effectiveness associated with content delivery networks.

+

MOQT is a generic protocol designed to work in concert with multiple +MoQ Streaming Formats. These MoQ Streaming Formats define how content is +encoded, packaged, and mapped to MOQT objects, along with policies for +discovery and subscription.

+
    +
  • +

    Section 2 describes the data model employed by MOQT.

    +
  • +
  • +

    Section 3 covers aspects of setting up a MOQT session.

    +
  • +
  • +

    Section 5 covers mechanisms for prioritizing subscriptions.

    +
  • +
  • +

    Section 6 covers behavior at the relay entities.

    +
  • +
  • +

    Section 7 covers how control messages are encoded on the wire.

    +
  • +
  • +

    Section 8 covers how data messages are encoded on the wire.

    +
  • +
+
+
+

+1.1. Motivation +

+

The development of MOQT is driven by goals in a number of areas - +specifically latency, the robust feature set of QUIC and relay +support.

+
+
+

+1.1.1. Latency +

+

Latency is necessary to correct for variable network throughput. Ideally live +content is consumed at the same bitrate it is produced. End-to-end latency would +be fixed and only subject to encoding and transmission delays. Unfortunately, +networks have variable throughput, primarily due to congestion. Attempting to +deliver content encoded at a higher bitrate than the network can support causes +queuing along the path from producer to consumer. The speed at which a protocol +can detect and respond to congestion determines the overall latency. TCP-based +protocols are simple but are slow to detect congestion and suffer from +head-of-line blocking. Protocols utilizing UDP directly can avoid queuing, but +the application is then responsible for the complexity of fragmentation, +congestion control, retransmissions, receiver feedback, reassembly, and +more. One goal of MOQT is to achieve the best of both these worlds: leverage the +features of QUIC to create a simple yet flexible low latency protocol that can +rapidly detect and respond to congestion.

+
+
+
+
+

+1.1.2. Leveraging QUIC +

+

The parallel nature of QUIC streams can provide improvements in the face +of loss. A goal of MOQT is to design a streaming protocol to leverage +the transmission benefits afforded by parallel QUIC streams as well +exercising options for flexible loss recovery.

+
+
+
+
+

+1.1.3. Convergence +

+

Some live media architectures today have separate protocols for ingest and +distribution, for example RTMP and HTTP based HLS or DASH. Switching protocols +necessitates intermediary origins which re-package the +media content. While specialization can have its benefits, there are efficiency +gains to be had in not having to re-package content. A goal of MOQT is to +develop a single protocol which can be used for transmission from contribution +to distribution. A related goal is the ability to support existing encoding and +packaging schemas, both for backwards compatibility and for interoperability +with the established content preparation ecosystem.

+
+
+
+
+

+1.1.4. Relays +

+

An integral feature of a protocol being successful is its ability to +deliver media at scale. Greatest scale is achieved when third-party +networks, independent of both the publisher and subscriber, can be +leveraged to relay the content. These relays must cache content for +distribution efficiency while simultaneously routing content and +deterministically responding to congestion in a multi-tenant network. A +goal of MOQT is to treat relays as first-class citizens of the protocol +and ensure that objects are structured such that information necessary +for distribution is available to relays while the media content itself +remains opaque and private.

+
+
+
+
+
+
+

+1.2. Terms and Definitions +

+

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", +"MAY", and "OPTIONAL" in this document are to be interpreted as +described in BCP 14 [RFC2119] [RFC8174] when, and only when, they +appear in all capitals, as shown here.

+

The following terms are used with the first letter capitalized.

+
+
Client:
+
+

The party initiating a Transport Session.

+
+
+
Server:
+
+

The party accepting an incoming Transport Session.

+
+
+
Endpoint:
+
+

A Client or Server.

+
+
+
Peer:
+
+

The other endpoint than the one being described

+
+
+
Publisher:
+
+

An endpoint that handles subscriptions by sending requested Objects from the requested track.

+
+
+
Subscriber:
+
+

An endpoint that subscribes to and receives tracks.

+
+
+
Original Publisher:
+
+

The initial publisher of a given track.

+
+
+
End Subscriber:
+
+

A subscriber that initiates a subscription and does not send the data on to other subscribers.

+
+
+
Relay:
+
+

An entity that is both a Publisher and a Subscriber, but not the Original +Publisher or End Subscriber.

+
+
+
Upstream:
+
+

In the direction of the Original Publisher

+
+
+
Downstream:
+
+

In the direction of the End Subscriber(s)

+
+
+
Transport Session:
+
+

A raw QUIC connection or a WebTransport session.

+
+
+
Congestion:
+
+

Packet loss and queuing caused by degraded or overloaded networks.

+
+
+
Group:
+
+

A temporal sequence of objects. A group represents a join point in a +track. See (Section 2.3).

+
+
+
Object:
+
+

An object is an addressable unit whose payload is a sequence of +bytes. Objects form the base element in the MOQT data model. See +(Section 2.1).

+
+
+
Track:
+
+

A track is a collection of groups. See (Section 2.4).

+
+
+
+
+
+
+
+

+1.3. Notational Conventions +

+

This document uses the conventions detailed in ([RFC9000], Section 1.3) +when describing the binary encoding.

+

As a quick reference, the following list provides a non normative summary +of the parts of RFC9000 field syntax that are used in this specification.

+
+
x (L):
+
+

Indicates that x is L bits long

+
+
+
x (i):
+
+

Indicates that x holds an integer value using the variable-length +encoding as described in ([RFC9000], Section 16)

+
+
+
x (..):
+
+

Indicates that x can be any length including zero bits long. Values + in this format always end on a byte boundary.

+
+
+
[x (L)]:
+
+

Indicates that x is optional and has a length of L

+
+
+
x (L) ...:
+
+

Indicates that x is repeated zero or more times and that each instance +has a length of L

+
+
+
+

This document extends the RFC9000 syntax and with the additional field types:

+
+
x (b):
+
+

Indicates that x consists of a variable length integer encoding as +described in ([RFC9000], Section 16), followed by that many bytes +of binary data

+
+
+
x (tuple):
+
+

Indicates that x is a tuple, consisting of a variable length integer encoded +as described in ([RFC9000], Section 16), followed by that many variable +length tuple fields, each of which are encoded as (b) above.

+
+
+
+

To reduce unnecessary use of bandwidth, variable length integers SHOULD +be encoded using the least number of bytes possible to represent the +required value.

+
+
+
+
+
+
+

+2. Object Data Model +

+

MOQT has a hierarchical data model, comprised of tracks which contain +groups, and groups that contain objects. Inside of a group, the objects +can be organized into subgroups.

+

To give an example of how an application might use this data model, +consider an application sending high and low resolution video using a +codec with temporal scalability. Each resolution is sent as a separate +track to allow the subscriber to pick the appropriate resolution given +the display environment and available bandwidth. Each "group of pictures" +in a video is sent as a group because the first frame is needed to +decode later frames. This allows the client to join at the logical points +where they can get the information to start decoding the stream. +The temporal layers are sent as separate sub groups to allow the +priority mechanism to favour the base layer when there is not enough +bandwidth to send both the base and enhancement layers. Each frame of +video on a given layer is sent as a single object.

+
+
+

+2.1. Objects +

+

The basic data element of MOQT is an object. An object is an +addressable unit whose payload is a sequence of bytes. All objects +belong to a group, indicating ordering and potential +dependencies. Section 2.3 An object is uniquely identified by +its track namespace, track name, group ID, and object ID, and must be an +identical sequence of bytes regardless of how or where it is retrieved. +An Object can become unavailable, but its contents MUST NOT change over +time.

+

Objects are comprised of two parts: metadata and a payload. The metadata is +never encrypted and is always visible to relays (see Section 6). The +payload portion may be encrypted, in which case it is only visible to the +Original Publisher and End Subscribers. The Original Publisher is solely +responsible for the content of the object payload. This includes the +underlying encoding, compression, any end-to-end encryption, or +authentication. A relay MUST NOT combine, split, or otherwise modify object +payloads.

+

Objects within a group are ordered numerically by their Object ID.

+
+
+
+
+

+2.2. Subgroups +

+

A subgroup is a sequence of one or more objects from the same group +(Section 2.3) in ascending order by Object ID. Objects in a subgroup +have a dependency and priority relationship consistent with sharing a +stream and are sent on a single stream whenever possible. A Group is delivered +using at least as many streams as there are Subgroups, +typically with a one-to-one mapping between Subgroups and streams.

+

When a Track's forwarding preference (see Section 8.1.1) is +"Datagram", Objects are not sent in Subgroups and the +description in the remainder of this section does not apply.

+

Streams offer in-order reliable delivery and the ability to cancel sending +and retransmission of data. Furthermore, many implementations offer the ability +to control the relative priority of streams, which allows control over the +scheduling of sending data on active streams.

+

Every object within a Group belongs to exactly one Subgroup.

+

Objects from two subgroups cannot be sent on the same stream. Objects from the +same Subgroup MUST NOT be sent on different streams, unless one of the streams +was reset prematurely, or upstream conditions have forced objects from a Subgroup +to be sent out of Object ID order.

+

Original publishers assign each Subgroup a Subgroup ID, and do so as they see fit. The +scope of a Subgroup ID is a Group, so Subgroups from different Groups MAY share a Subgroup +ID without implying any relationship between them. In general, publishers assign +objects to subgroups in order to leverage the features of streams as described +above.

+

An example strategy for using stream properties follows. If object B is +dependent on object A, then delivery of B can follow A, i.e. A and B can be +usefully delivered over a single stream. Furthermore, in this example:

+
    +
  • +

    If an object is dependent on all previous objects in a Subgroup, it is added to +that Subgroup.

    +
  • +
  • +

    If an object is not dependent on all of the objects in a Subgroup, it goes in +a different Subgroup.

    +
  • +
  • +

    There are often many ways to compose Subgroups that meet these criteria. Where +possible, choose the composition that results in the fewest Subgroups in a group +to minimize the number of streams used.

    +
  • +
+
+
+
+
+

+2.3. Groups +

+

A group is a collection of objects and is a sub-unit of a track (Section 2.4). +Groups SHOULD be indendepently useful, so objects within a group SHOULD NOT depend +on objects in other groups. A group provides a join point for subscriptions, so a +subscriber that does not want to receive the entire track can opt to receive only +the latest group(s). The publisher then selectively transmits objects based on +their group membership. Groups can contain any number of objects.

+

Within a track, the original publisher SHOULD produce Group IDs which increase +with time. Subscribers to tracks which do not follow this requirement SHOULD NOT +use range filters which span multiple groups in FETCH or SUBSCRIBE. SUBSCRIBE and +FETCH delivery use Group Order, so a FETCH cannot deliver Groups out of order +and a subscription could have unexpected delivery order if Group IDs do not increase +with time.

+
+
+
+
+

+2.4. Track +

+

A track is a sequence of groups (Section 2.3). It is the entity +against which a subscriber issues a subscription request. A subscriber +can request to receive individual tracks starting at a group boundary, +including any new objects pushed by the publisher while the track is +active.

+
+
+

+2.4.1. Track Naming and Scopes +

+

In MOQT, every track is identified by a Full Track Name, consisting of a Track +Namespace and a Track Name.

+

Track Namespace is an ordered N-tuple of bytes where N can be between 1 and 32. +The structured nature of Track Namespace allows relays and applications to +manipulate prefixes of a namespace. If an endpoint receives a Track Namespace +tuple with an N of 0 or more than 32, it MUST close the session with a Protocol +Violation.

+

Track Name is a sequence of bytes that identifies an individual track within the +namespace.

+

In this specification, both the Track Namespace tuple fields and the Track Name +are not constrained to a specific encoding. They carry a sequence of bytes and +comparison between two Track Namespace tuple fields or Track Names is done by +exact comparison of the bytes. Specifications that use MoQ Transport may +constrain the information in these fields, for example by restricting them to +UTF-8. Any specification that does needs to specify the canonicalization into +the bytes in the Track Namespace or Track Name such that exact comparison works.

+
+
+
+
+

+2.4.2. Scope +

+

A MOQT scope is a set of servers (as identified by their connection +URIs) for which the tuple of Track Name and Track Namespace are +guaranteed to be unique and identify a specific track. It is up to +the application using MOQT to define how broad or narrow the scope is. +An application that deals with connections between devices +on a local network may limit the scope to a single connection; by +contrast, an application that uses multiple CDNs to serve media may +require the scope to include all of those CDNs.

+

Because the tuple of Track Namespace and Track Name are unique within an +MOQT scope, they can be used as a cache key. +MOQT does not provide any in-band content negotiation methods similar to +the ones defined by HTTP ([RFC9110], Section 10); if, at a given +moment in time, two tracks within the same scope contain different data, +they have to have different names and/or namespaces.

+
+
+
+
+
+
+
+
+

+3. Sessions +

+
+
+

+3.1. Session establishment +

+

This document defines a protocol that can be used interchangeably both +over a QUIC connection directly [QUIC], and over WebTransport +[WebTransport]. Both provide streams and datagrams with similar +semantics (see [I-D.ietf-webtrans-overview], Section 4); thus, the +main difference lies in how the servers are identified and how the +connection is established. When using QUIC, datagrams MUST be +supported via the [QUIC-DATAGRAM] extension, which is already a +requirement for WebTransport over HTTP/3.

+

There is no definition of the protocol over other transports, +such as TCP, and applications using MoQ might need to fallback to +another protocol when QUIC or WebTransport aren't available.

+
+
+

+3.1.1. WebTransport +

+

A MOQT server that is accessible via WebTransport can be identified +using an HTTPS URI ([RFC9110], Section 4.2.2). A MOQT session can be +established by sending an extended CONNECT request to the host and the +path indicated by the URI, as described in +([WebTransport], Section 3).

+
+
+
+
+

+3.1.2. QUIC +

+

A MOQT server that is accessible via native QUIC can be identified by a +URI with a "moqt" scheme. The "moqt" URI scheme is defined as follows, +using definitions from [RFC3986]:

+
+
+moqt-URI = "moqt" "://" authority path-abempty [ "?" query ]
+
+
+

The authority portion MUST NOT contain an empty host portion. +The moqt URI scheme supports the /.well-known/ path prefix defined in +[RFC8615].

+

This protocol does not specify any semantics on the path-abempty and +query portions of the URI. The contents of those are left up to the +application.

+

The client can establish a connection to a MoQ server identified by a +given URI by setting up a QUIC connection to the host and port +identified by the authority section of the URI. The path-abempty +and query portions of the URI are communicated to the server using the +PATH parameter (Section 7.2.2.1) which is sent in the CLIENT_SETUP message at the +start of the session. The ALPN value [RFC7301] used by the protocol +is moq-00.

+
+
+
+
+

+3.1.3. Connection URL +

+

Each track MAY have one or more associated connection URLs specifying +network hosts through which a track may be accessed. The syntax of the +Connection URL and the associated connection setup procedures are +specific to the underlying transport protocol usage Section 3.

+
+
+
+
+
+
+

+3.2. Version and Extension Negotiation +

+

Endpoints use the exchange of Setup messages to negotiate the MOQT version and +any extensions to use.

+

The client indicates the MOQT versions it supports in the CLIENT_SETUP message +(see Section 7.2). It also includes the union of all Setup Parameters +Section 7.2.2 required for a handshake by any of those versions.

+

Within any MOQT version, clients request the use of extensions by adding Setup +parameters corresponding to that extension. No extensions are defined in this +document.

+

The server replies with a SERVER_SETUP message that indicates the chosen +version, includes all parameters required for a handshake in that version, and +parameters for every extension requested by the client that it supports.

+

New versions of MOQT MUST specify which existing extensions can be used with +that version. New extensions MUST specify the existing versions with which they +can be used.

+

If a given parameter carries the same information in multiple versions, +but might have different optimal values in those versions, there SHOULD be +separate Setup parameters for that information in each version.

+
+
+
+
+

+3.3. Session initialization +

+

The first stream opened is a client-initiated bidirectional control stream where +the endpoints exchange Setup messages (Section 7.2). All messages defined +in this draft except OBJECT and OBJECT_WITH_LENGTH are sent on the control +stream after the Setup message. Control messages MUST NOT be sent on any other +stream, and a peer receiving a control message on a different stream closes the +session as a 'Protocol Violation'. Objects MUST NOT be sent on the control +stream, and a peer receiving an Object on the control stream closes the session +as a 'Protocol Violation'.

+

This draft only specifies a single use of bidirectional streams. Objects are +sent on unidirectional streams. Because there are no other uses of +bidirectional streams, a peer MAY currently close the session as a +'Protocol Violation' if it receives a second bidirectional stream.

+

The control stream MUST NOT be closed at the underlying transport layer while the +session is active. Doing so results in the session being closed as a +'Protocol Violation'.

+
+
+
+
+

+3.4. Stream Cancellation +

+

Streams aside from the control stream MAY be canceled due to congestion +or other reasons by either the publisher or subscriber. Early termination of a +stream does not affect the MoQ application state, and therefore has no +effect on outstanding subscriptions.

+
+
+
+
+

+3.5. Termination +

+

The Transport Session can be terminated at any point. When native QUIC +is used, the session is closed using the CONNECTION_CLOSE frame +([QUIC], Section 19.19). When WebTransport is used, the session is +closed using the CLOSE_WEBTRANSPORT_SESSION capsule ([WebTransport], Section 5).

+

The application MAY use any error message and SHOULD use a relevant +code, as defined below:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1
CodeReason
0x0No Error
0x1Internal Error
0x2Unauthorized
0x3Protocol Violation
0x4Duplicate Track Alias
0x5Parameter Length Mismatch
0x6Too Many Subscribes
0x10GOAWAY Timeout
0x11Control Message Timeout
0x12Data Stream Timeout
+
    +
  • +

    No Error: The session is being terminated without an error.

    +
  • +
  • +

    Internal Error: An implementation specific error occurred.

    +
  • +
  • +

    Unauthorized: The endpoint breached an agreement, which MAY have been + pre-negotiated by the application.

    +
  • +
  • +

    Protocol Violation: The remote endpoint performed an action that was +disallowed by the specification.

    +
  • +
  • +

    Duplicate Track Alias: The endpoint attempted to use a Track Alias +that was already in use.

    +
  • +
  • +

    Too Many Subscribes: The session was closed because the subscriber used +a Subscribe ID equal or larger than the current Maximum Subscribe ID.

    +
  • +
  • +

    GOAWAY Timeout: The session was closed because the peer took too long to +close the session in response to a GOAWAY (Section 7.3) message. +See session migration (Section 3.6).

    +
  • +
  • +

    Control Message Timeout: The session was closed because the peer took too +long to respond to a control message.

    +
  • +
  • +

    Data Stream Timeout: The session was closed because the peer took too +long to send data expected on an open Data Stream Section 8. This +includes fields of a stream header or an object header within a data +stream. If an endpoint times out waiting for a new object header on an +open subgroup stream, it MAY send a STOP_SENDING on that stream, terminate +the subscription, or close the session with an error.

    +
  • +
+
+
+
+
+

+3.6. Migration +

+

MOQT requires a long-lived and stateful session. However, a service +provider needs the ability to shutdown/restart a server without waiting for all +sessions to drain naturally, as that can take days for long-form media. +MOQT enables proactively draining sessions via the GOAWAY message (Section 7.3).

+

The server sends a GOAWAY message, signaling the client to establish a new +session and migrate any active subscriptions. The GOAWAY message optionally +contains a new URI for the new session, otherwise the current URI is +reused. The server SHOULD terminate the session with 'GOAWAY Timeout' after a +sufficient timeout if there are still open subscriptions or fetches on a +connection.

+

When the server is a subscriber, it SHOULD send a GOAWAY message to downstream +subscribers prior to any UNSUBSCRIBE messages to upstream publishers.

+

After the client receives a GOAWAY, it's RECOMMENDED that the client waits until +there are no more active subscriptions before closing the session with NO_ERROR. +Ideally this is transparent to the application using MOQT, which involves +establishing a new session in the background and migrating active subscriptions +and announcements. The client can choose to delay closing the session if it +expects more OBJECTs to be delivered. The server closes the session with a +'GOAWAY Timeout' if the client doesn't close the session quickly enough.

+
+
+
+
+
+
+

+4. Track Discovery and Retrieval +

+

Discovery of MoQT servers is always done out-of-band. Namespace discovery can be +done in the context of an established MoQT session.

+

Given sufficient out of band information, it is valid for a subscriber +to send a SUBSCRIBE or FETCH message to a publisher (including a relay) without +any previous MoQT messages besides SETUP. However, SUBSCRIBE_ANNOUNCES and +ANNOUNCE messages provide an in-band means of discovery of subscribers and +publishers for a namespace.

+

The syntax of these messages is described in Section 7.

+
+
+

+4.1. SUBSCRIBE_ANNOUNCES +

+

If the subscriber is aware of a namespace of interest, it can send +SUBSCRIBE_ANNOUNCES to publishers/relays it has established a session with. The +recipient of this message will send any relevant ANNOUNCE or UNANNOUNCE messages +for that namespace, or subset of that namespace.

+

A publisher MUST send exactly one SUBSCRIBE_ANNOUNCES_OK or +SUBSCRIBE_ANNOUNCES_ERROR in response to a SUBSCRIBE_ANNOUNCES. The subscriber +SHOULD close the session with a protocol error if it detects receiving more than +one.

+

The receiver of a SUBSCRIBE_ANNOUNCES_OK or SUBSCRIBE_ANNOUNCES_ERROR ought to +forward the result to the application, so that it can make decisions about +further publishers to contact.

+

An UNSUBSCRIBE_ANNOUNCES withdraws a previous SUBSCRIBE_ANNOUNCES. It does +not prohibit the receiver (publisher) from sending further ANNOUNCE messages.

+
+
+
+
+

+4.2. ANNOUNCE +

+

A publisher MAY send ANNOUNCE messages to any subscriber. An ANNOUNCE indicates +to the subscriber where to route a SUBSCRIBE or FETCH for that namespace. A +subscriber MAY send SUBSCRIBE or FETCH for a namespace without having received +an ANNOUNCE for it.

+

If a publisher is authoritative for a given namespace, or is a relay that has +received an authorized ANNOUNCE for that namespace from an upstream publisher, +it MUST send an ANNOUNCE to any subscriber that has subscribed to ANNOUNCE for +that namespace, or a subset of that namespace. A publisher MAY send the ANNOUNCE +to any other subscriber.

+

An endpoint SHOULD NOT, however, send an ANNOUNCE advertising a namespace that +exactly matches a namespace for which the peer sent an earlier ANNOUNCE +(i.e. an ANNOUNCE ought not to be echoed back to its sender).

+

The receiver of an ANNOUNCE_OK or ANNOUNCE_ERROR SHOULD report this to the +application to inform the search for additional subscribers for a namespace, +or abandoning the attempt to publish under this namespace. This might be +especially useful in upload or chat applications. A subscriber MUST send exactly +one ANNOUNCE_OK or ANNOUNCE_ERROR in response to an ANNOUNCE. The publisher +SHOULD close the session with a protocol error if it receives more than one.

+

An UNANNOUNCE message withdraws a previous ANNOUNCE, although it is not a +protocol error for the subscriber to send a SUBSCRIBE or FETCH message after +receiving an UNANNOUNCE.

+

A subscriber can send ANNOUNCE_CANCEL to revoke acceptance of an ANNOUNCE, for +example due to expiration of authorization credentials. The message enables the +publisher to ANNOUNCE again with refreshed authorization, or discard associated +state. After receiving an ANNOUNCE_CANCEL, the publisher does not send UNANNOUNCE.

+

While ANNOUNCE does provide hints on where to route a SUBSCRIBE or FETCH, it is +not a full-fledged routing protocol and does not protect against loops and other +phenomena. In particular, ANNOUNCE SHOULD NOT be used to find paths through +richly connected networks of relays.

+
+
+
+
+

+4.3. SUBSCRIBE/FETCH +

+

The central interaction with a publisher is to send SUBSCRIBE and/or FETCH for +a particular track. The subscriber expects to receive a +SUBSCRIBE_OK/FETCH_OK and objects from the track.

+

A subscriber MAY send a SUBSCRIBE or FETCH for a track to any publisher. If it +has accepted an ANNOUNCE with a namespace that exactly matches the namespace for +that track, it SHOULD only request it from the senders of those ANNOUNCE +messages.

+

A publisher MUST send exactly one SUBSCRIBE_OK or SUBSCRIBE_ERROR in response to +a SUBSCRIBE. It MUST send exactly one FETCH_OK or FETCH_ERROR in response to a +FETCH. The subscriber SHOULD close the session with a protocol error if it +receives more than one.

+

A subscriber keeps SUBSCRIBE state until it sends UNSUBSCRIBE, or after receipt +of a SUBSCRIBE_DONE or SUBSCRIBE_ERROR. Note that SUBSCRIBE_DONE does not +usually indicate that state can immediately be destroyed, see +Section 7.19.

+

A subscriber keeps FETCH state until it sends FETCH_CANCEL, receives +FETCH_ERROR, or receives a FIN or RESET_STREAM for the FETCH data stream. If the +data stream is already open, it MAY send STOP_SENDING for the data stream along +with FETCH_CANCEL, but MUST send FETCH_CANCEL.

+

The Publisher can destroy subscription or fetch state as soon as it has received +UNSUBSCRIBE or FETCH_CANCEL, respectively. It MUST reset any open streams +associated with the SUBSCRIBE or FETCH. It can also destroy state after closing +the FETCH data stream.

+

The publisher can immediately delete SUBSCRIBE state after sending +SUBSCRIBE_DONE, but MUST NOT send it until it has closed all related streams. It +can destroy all FETCH state after closing the data stream.

+

A SUBSCRIBE_ERROR or FETCH_ERROR indicates no objects will be delivered, and +both endpoints can immediately destroy relevant state. Objects MUST NOT be sent +for requests that end with an error.

+
+
+
+
+
+
+

+5. Priorities +

+

MoQ priorities allow a subscriber and original publisher to influence +the transmission order of Objects within a session in the presence of +congestion.

+
+
+

+5.1. Definitions +

+

MoQT maintains priorities between different schedulable objects. +A schedulable object in MoQT is either:

+
    +
  1. +

    An object that belongs to a subgroup where that object would be the next +object to be sent in that subgroup.

    +
  2. +
  3. +

    An object that belongs to a track with delivery preference Datagram.

    +
  4. +
+

Since a single subgroup or datagram has a single publisher priority, it can be +useful to conceptualize this process as scheduling subgroups or datagrams +instead of individual objects on them.

+

A priority number is an unsigned integer with a value between 0 and 255. +A lower priority number indicates higher priority; the highest priority is 0.

+

Subscriber Priority is a priority number associated with an individual +subscription. It is specified in the SUBSCRIBE message, and can be updated via +SUBSCRIBE_UPDATE message. The subscriber priority of an individual schedulable +object is the subscriber priority of the subscription that caused that object +to be sent. When subscriber priority is changed, a best effort SHOULD be made +to apply the change to all objects that have not been sent, but it is +implementation dependent what happens to objects that have already been +received and possibly scheduled.

+

Publisher Priority is a priority number associated with an individual +schedulable object. It is specified in the header of the respective subgroup or +datagram, and is the same for all objects in a single subgroup.

+

Group Order is a property of an invidual subscription. It can be either +'Ascending' (groups with lower group ID are sent first), or 'Descending' +(groups with higher group ID are sent first). The publisher communicates its +group order in the SUBSCRIBE_OK message; the subscriber can override it in its +SUBSCRIBE message. The group order of an existing subscription cannot be +changed.

+
+
+
+
+

+5.2. Scheduling Algorithm +

+

When an MoQT publisher has multiple schedulable objects it can choose between, +the objects SHOULD be selected as follows:

+
    +
  1. +

    If two objects have a different subscriber priority associated with them, +the one with the highest subscriber priority is sent first.

    +
  2. +
  3. +

    If two objects have the same subscriber priority, but a different publisher +priority, the one with the highest publisher priority is sent first.

    +
  4. +
  5. +

    If two objects have the same subscriber and publisher priority, but belong +to two different groups of the same track, +the group order of the associated subscription is used to +decide the one that is sent first.

    +
  6. +
  7. +

    If two objects belong to the same group of the same track, +the one with the lowest Subgroup ID (for tracks +with delivery preference Subgroup), or the lowest Object ID (for tracks +with delivery preference Datagram) is sent first.

    +
  8. +
+

This algorithm does not provide a well-defined ordering for objects that belong +to different subscriptions, but have the same subscriber and publisher +priority. The ordering in those cases is implementation-defined, though the +expectation is that all subscriptions will be able to send some data.

+

Given the critical nature of control messages and their relatively +small size, the control stream SHOULD be prioritized higher than all +subscribed Objects.

+
+
+
+
+

+5.3. Considerations for Setting Priorities +

+

Relays SHOULD respect the subscriber and original publisher's priorities. +Relays SHOULD NOT directly use Subscriber Priority or Group Order +from incoming subscriptions for upstream subscriptions. Relays use of +Subscriber Priority for upstream subscriptions can be based on +factors specific to it, such as the popularity of the +content or policy, or relays can specify the same value for all +upstream subscriptions.

+

MoQ Sessions can span multiple namespaces, and priorities might not +be coordinated across namespaces. The subscriber's priority is +considered first, so there is a mechanism for a subscriber to fix +incompatibilities between different namespaces prioritization schemes. +Additionally, it is anticipated that when multiple namespaces +are present within a session, the namespaces could be coordinating, +possibly part of the same application. In cases when pooling among +namespaces is expected to cause issues, multiple MoQ sessions, either +within a single connection or on multiple connections can be used.

+

Implementations that have a default priority SHOULD set it to a value in +the middle of the range (eg: 128) to allow non-default priorities to be +set either higher or lower.

+
+
+
+
+
+
+

+6. Relays +

+

Relays are leveraged to enable distribution scale in the MoQ +architecture. Relays can be used to form an overlay delivery network, +similar in functionality to Content Delivery Networks +(CDNs). Additionally, relays serve as policy enforcement points by +validating subscribe and publish requests at the edge of a network.

+

Relays are endpoints, which means they terminate Transport Sessions in order to +have visibility of MoQ Object metadata.

+

Relays MAY cache Objects, but are not required to.

+
+
+

+6.1. Subscriber Interactions +

+

Subscribers subscribe to tracks by sending a SUBSCRIBE +(Section 7.4) control message for each track of +interest. Relays MUST ensure subscribers are authorized to access the +content associated with the track. The authorization +information can be part of subscription request itself or part of the +encompassing session. The specifics of how a relay authorizes a user are outside +the scope of this specification.

+

The relay will have to send an upstream SUBSCRIBE and/or FETCH if it does not +have all the objects in the FETCH, or is not currently subscribed to the full +requested range. In this case, it SHOULD withhold sending its own SUBSCRIBE_OK +until receiving one from upstream. It MUST withhold FETCH_OK until receiving +one from upstream.

+

For successful subscriptions, the publisher maintains a list of +subscribers for each track. Each new OBJECT belonging to the +track within the subscription range is forwarded to each active +subscriber, dependent on the congestion response.

+

A caching relay saves Objects to its cache identified by the Object's +Full Track Name, Group ID and Object ID. Relays MUST be able to +process objects for the same Full Track Name from multiple +publishers and forward objects to active matching subscriptions. +If multiple objects are received with the same Full Track Name, +Group ID and Object ID, Relays MAY ignore subsequently received Objects +or MAY use them to update the cache. Implementations that update the +cache need to protect against cache poisoning.

+

A relay MUST NOT reorder or drop objects received on a multi-object stream when +forwarding to subscribers, unless it has application specific information.

+

Relays MAY aggregate authorized subscriptions for a given track when +multiple subscribers request the same track. Subscription aggregation +allows relays to make only a single upstream subscription for the +track. The published content received from the upstream subscription +request is cached and shared among the pending subscribers.

+
+
+

+6.1.1. Graceful Subscriber Relay Switchover +

+

This section describes behavior a subscriber MAY implement +to allow for a better user experience when a relay sends a GOAWAY.

+

When a subscriber receives the GOAWAY message, it starts the process +of connecting to a new relay and sending the SUBSCRIBE requests for +all active subscriptions to the new relay. The new relay will send a +response to the subscribes and if they are successful, the subscriptions +to the old relay can be stopped with an UNSUBSCRIBE.

+
+
+
+
+
+
+

+6.2. Publisher Interactions +

+

Publishing through the relay starts with publisher sending ANNOUNCE +control message with a Track Namespace (Section 2.4). +The ANNOUNCE enables the relay to know which publisher to forward a +SUBSCRIBE to.

+

Relays MUST verify that publishers are authorized to publish +the content associated with the set of +tracks whose Track Namespace matches the announced namespace. Where the +authorization and identification of the publisher occurs depends on the way the +relay is managed and is application specific.

+

A Relay can receive announcements from multiple publishers for the same +Track Namespace and it SHOULD respond with the same response to each of the +publishers, as though it was responding to an ANNOUNCE +from a single publisher for a given track namespace.

+

When a publisher wants to stop +new subscriptions for an announced namespace it sends an UNANNOUNCE. +A subscriber indicates it will no longer route subscriptions for a +namespace it previously responded ANNOUNCE_OK to by sending an +ANNOUNCE_CANCEL.

+

A relay manages sessions from multiple publishers and subscribers, +connecting them based on the track namespace. This MUST use an exact +match on track namespace unless otherwise negotiated by the application. +For example, a SUBSCRIBE namespace=foobar message will be forwarded to +the session that sent ANNOUNCE namespace=foobar.

+

When a relay receives an incoming SUBSCRIBE request that triggers an +upstream subscription, it SHOULD send a SUBSCRIBE request to each +publisher that has announced the subscription's namespace, unless it +already has an active subscription for the Objects requested by the +incoming SUBSCRIBE request from all available publishers.

+

When a relay receives an incoming ANNOUNCE for a given namespace, for +each active upstream subscription that matches that namespace, it SHOULD send a +SUBSCRIBE to the publisher that sent the ANNOUNCE.

+

OBJECT message headers carry a short hop-by-hop Track Alias that maps to +the Full Track Name (see Section 7.15). Relays use the +Track Alias of an incoming OBJECT message to identify its track and find +the active subscribers for that track. Relays MUST forward OBJECT messages to +matching subscribers in accordance to each subscription's priority, group order, +and delivery timeout.

+
+
+

+6.2.1. Graceful Publisher Network Switchover +

+

This section describes behavior that a publisher MAY +choose to implement to allow for a better users experience when +switching between networks, such as WiFi to Cellular or vice versa.

+

If the original publisher detects it is likely to need to switch networks, +for example because the WiFi signal is getting weaker, and it does not +have QUIC connection migration available, it establishes a new session +over the new interface and sends an ANNOUCE. The relay will forward +matching subscribes and the publisher publishes objects on both sessions. +Once the subscriptions have migrated over to session on the new network, +the publisher can stop publishing objects on the old network. The relay +will drop duplicate objects received on both subscriptions. +Ideally, the subscriptions downstream from the relay do no observe this +change, and keep receiving the objects on the same subscription.

+
+
+
+
+

+6.2.2. Graceful Publisher Relay Switchover +

+

This section describes behavior that a publisher MAY choose to implement +to allow for a better user experience when a relay sends them a GOAWAY.

+

When a publisher receives a GOAWAY, it starts the process of +connecting to a new relay and sends announces, but it does not immediately +stop publishing objects to the old relay. The new relay will send +subscribes and the publisher can start sending new objects to the new relay +instead of the old relay. Once objects are going to the new relay, +the announcement and subscription to the old relay can be stopped.

+
+
+
+
+
+
+

+6.3. Relay Object Handling +

+

MOQT encodes the delivery information for a stream via OBJECT headers +(Section 8.1). A relay MUST NOT modify Object properties when +forwarding.

+

A relay MUST treat the object payload as opaque. A relay MUST NOT +combine, split, or otherwise modify object payloads. A relay SHOULD +prioritize sending Objects based on Section 5.

+

A publisher SHOULD begin sending incomplete objects when available to +avoid incurring additional latency.

+

A relay that reads from one stream and writes to another in order can +introduce head-of-line blocking. Packet loss will cause stream data to +be buffered in the library, awaiting in-order delivery, which could +increase latency over additional hops. To mitigate this, a relay MAY +read and write stream data out of order subject to flow control +limits. See section 2.2 in [QUIC].

+
+
+
+
+
+
+

+7. Control Messages +

+

MOQT uses a single bidirectional stream to exchange control messages, as +defined in Section 3.3. Every single message on the control stream is +formatted as follows:

+
+
+
+
+MOQT Control Message {
+  Message Type (i),
+  Message Length (i),
+  Message Payload (..),
+}
+
+
+
Figure 1: +MOQT Message +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 2
IDMessages
0x2SUBSCRIBE_UPDATE (Section 7.5)
0x3SUBSCRIBE (Section 7.4)
0x4SUBSCRIBE_OK (Section 7.15)
0x5SUBSCRIBE_ERROR (Section 7.16)
0x6ANNOUNCE (Section 7.22)
0x7ANNOUNCE_OK (Section 7.9)
0x8ANNOUNCE_ERROR (Section 7.10)
0x9UNANNOUNCE (Section 7.23)
0xAUNSUBSCRIBE (Section 7.6)
0xBSUBSCRIBE_DONE (Section 7.19)
0xCANNOUNCE_CANCEL (Section 7.11)
0xDTRACK_STATUS_REQUEST (Section 7.12)
0xETRACK_STATUS (Section 7.24)
0x10GOAWAY (Section 7.3)
0x11SUBSCRIBE_ANNOUNCES (Section 7.13)
0x12SUBSCRIBE_ANNOUNCES_OK (Section 7.25)
0x13SUBSCRIBE_ANNOUNCES_ERROR (Section 7.26 +
0x14UNSUBSCRIBE_ANNOUNCES (Section 7.14)
0x15MAX_SUBSCRIBE_ID (Section 7.20)
0x1ASUBSCRIBES_BLOCKED (Section 7.21)
0x16FETCH (Section 7.7)
0x17FETCH_CANCEL (Section 7.8)
0x18FETCH_OK (Section 7.17)
0x19FETCH_ERROR (Section 7.18)
0x40CLIENT_SETUP (Section 7.2)
0x41SERVER_SETUP (Section 7.2)
+

An endpoint that receives an unknown message type MUST close the session. +Control messages have a length to make parsing easier, but no control +messages are intended to be ignored. If the length does not match the +length of the message content, the receiver MUST close the session.

+
+
+

+7.1. Parameters +

+

Some messages include a Parameters field that encode optional message +elements. They contain a type, length, and value.

+

Senders MUST NOT repeat the same parameter type in a message. Receivers +SHOULD check that there are no duplicate parameters and close the session +as a 'Protocol Violation' if found.

+

Receivers ignore unrecognized parameters.

+

The format of Parameters is as follows:

+
+
+
+
+Parameter {
+  Parameter Type (i),
+  Parameter Length (i),
+  Parameter Value (..),
+}
+
+
+
Figure 2: +MOQT Parameter +
+
+

Parameter Type is an integer that indicates the semantic meaning of the +parameter. Setup message parameters use a namespace that is constant across all +MoQ Transport versions. All other messages use a version-specific namespace. For +example, the integer '1' can refer to different parameters for Setup messages +and for all other message types.

+

SETUP message parameter types are defined in Section 7.2.2. Version- +specific parameter types are defined in Section 7.1.1.

+

The Parameter Length field of the String Parameter encodes the length +of the Parameter Value field in bytes.

+

Each parameter description will indicate the data type in the Parameter Value +field. If a receiver understands a parameter type, and the parameter length +implied by that type does not match the Parameter Length field, the receiver +MUST terminate the session with error code 'Parameter Length Mismatch'.

+
+
+

+7.1.1. Version Specific Parameters +

+

Each version-specific parameter definition indicates the message types in which +it can appear. If it appears in some other type of message, it MUST be ignored. +Note that since Setup parameters use a separate namespace, it is impossible for +these parameters to appear in Setup messages.

+
+
+
+7.1.1.1. AUTHORIZATION INFO +
+

AUTHORIZATION INFO parameter (Parameter Type 0x02) identifies a track's +authorization information in a SUBSCRIBE, SUBSCRIBE_ANNOUNCES, ANNOUNCE +or FETCH message. This parameter is populated for cases where the authorization +is required at the track level. The value is an ASCII string.

+
+
+
+
+
+7.1.1.2. DELIVERY TIMEOUT Parameter +
+

The DELIVERY TIMEOUT parameter (Parameter Type 0x03) MAY appear in a +SUBSCRIBE, SUBSCRIBE_OK, or a SUBSCRIBE_UDPATE message. It is the duration in +milliseconds the relay SHOULD continue to attempt forwarding Objects after +they have been received. The start time for the timeout is based on when the +beginning of the Object is received, and does not depend upon the forwarding +preference. There is no explicit signal that an Object was not sent because +the delivery timeout was exceeded.

+

If both the subscriber and publisher specify the parameter, they use the min of the +two values for the subscription. The publisher SHOULD always specify the value +received from an upstream subscription when there is one, and nothing otherwise. +If an earlier Object arrives later than subsequent Objects, relays can consider +the receipt time as that of the next later Object, with the assumption that the +Object's data was reordered.

+

If neither the subscriber or publisher specify DELIVERY TIMEOUT, all Objects +in the track matching the subscription filter are delivered as indicated by +their Group Order and Priority. If a subscriber exceeds the publisher's +resource limits by failing to consume objects at a sufficient rate, the +publisher MAY terminate the subscription with error 'Too Far Behind'.

+

If an object in a subgroup exceeds the delivery timeout, the publisher MUST +reset the underlying transport stream (see Section 8.4.2).

+

When sent by a subscriber, this parameter is intended to be specific to a +subscription, so it SHOULD NOT be forwarded upstream by a relay that intends +to serve multiple subscriptions for the same track.

+

Publishers SHOULD consider whether the entire Object is likely to be delivered +before sending any data for that Object, taking into account priorities, +congestion control, and any other relevant information.

+
+
+
+
+
+7.1.1.3. MAX CACHE DURATION Parameter +
+

MAX_CACHE_DURATION (Parameter Type 0x04): An integer expressing a number of +milliseconds. If present, the relay MUST NOT start forwarding any individual +Object received through this subscription after the specified number of +milliseconds has elapsed since the beginning of the Object was received. This +means Objects earlier in a multi-object stream will expire earlier than Objects +later in the stream. Once Objects have expired, their state becomes unknown, and +a relay that handles a subscription that includes those Objects re-requests them.

+
+
+
+
+
+
+
+
+

+7.2. CLIENT_SETUP and SERVER_SETUP +

+

The CLIENT_SETUP and SERVER_SETUP messages are the first messages exchanged +by the client and the server; they allow the endpoints to establish the mutually +supported version and agree on the initial configuration before any objects are +exchanged. It is a sequence of key-value pairs called Setup parameters; the +semantics and format of which can vary based on whether the client or server is +sending. To ensure future extensibility of MOQT, endpoints MUST ignore unknown +setup parameters. TODO: describe GREASE for those.

+

The wire format of the Setup messages are as follows:

+
+
+
+
+CLIENT_SETUP Message {
+  Type (i) = 0x40,
+  Length (i),
+  Number of Supported Versions (i),
+  Supported Version (i) ...,
+  Number of Parameters (i) ...,
+  Setup Parameters (..) ...,
+}
+
+SERVER_SETUP Message {
+  Type (i) = 0x41,
+  Length (i),
+  Selected Version (i),
+  Number of Parameters (i) ...,
+  Setup Parameters (..) ...,
+}
+
+
+
Figure 3: +MOQT Setup Messages +
+
+

The available versions and Setup parameters are detailed in the next sections.

+
+
+

+7.2.1. Versions +

+

MoQ Transport versions are a 32-bit unsigned integer, encoded as a varint. +This version of the specification is identified by the number 0x00000001. +Versions with the most significant 16 bits of the version number cleared are +reserved for use in future IETF consensus documents.

+

The client offers the list of the protocol versions it supports; the +server MUST reply with one of the versions offered by the client. If the +server does not support any of the versions offered by the client, or +the client receives a server version that it did not offer, the +corresponding peer MUST close the session.

+

[[RFC editor: please remove the remainder of this section before +publication.]]

+

The version number for the final version of this specification (0x00000001), is +reserved for the version of the protocol that is published as an RFC. +Version numbers used to identify IETF drafts are created by adding the draft +number to 0xff000000. For example, draft-ietf-moq-transport-13 would be +identified as 0xff00000D.

+
+
+
+
+

+7.2.2. Setup Parameters +

+
+
+
+7.2.2.1. PATH +
+

The PATH parameter (Parameter Type 0x01) allows the client to specify the path +of the MoQ URI when using native QUIC ([QUIC]). It MUST NOT be used by +the server, or when WebTransport is used. If the peer receives a PATH +parameter from the server, or when WebTransport is used, it MUST close +the connection. It follows the URI formatting rules [RFC3986].

+

When connecting to a server using a URI with the "moqt" scheme, the +client MUST set the PATH parameter to the path-abempty portion of the +URI; if query is present, the client MUST concatenate ?, followed by +the query portion of the URI to the parameter.

+
+
+
+
+
+7.2.2.2. MAX_SUBSCRIBE_ID +
+

The MAX_SUBSCRIBE_ID parameter (Parameter Type 0x02) communicates an initial +value for the Maximum Subscribe ID to the receiving subscriber. The default +value is 0, so if not specified, the peer MUST NOT create subscriptions.

+
+
+
+
+
+
+
+
+

+7.3. GOAWAY +

+

An endpoint sends a GOAWAY message to inform the peer it intends to close +the session soon. Servers can use GOAWAY to initiate session migration +(Section 3.6) with an optional URI.

+

The GOAWAY message does not impact subscription state. A subscriber +SHOULD individually UNSUBSCRIBE for each existing subscription, while a +publisher MAY reject new requests while in the draining state.

+

Upon receiving a GOAWAY, an endpoint SHOULD NOT initiate new requests to +the peer including SUBSCRIBE, FETCH, ANNOUNCE and SUBSCRIBE_ANNOUNCE.

+

The endpoint MUST terminate the session with a Protocol Violation +(Section 3.5) if it receives multiple GOAWAY messages.

+
+
+
+
+GOAWAY Message {
+  Type (i) = 0x10,
+  Length (i),
+  New Session URI Length (i),
+  New Session URI (..),
+}
+
+
+
Figure 4: +MOQT GOAWAY Message +
+
+
    +
  • +

    New Session URI: When received by a client, indicates where the client can +connect to continue this session. The client MUST use this URI for the new +session if provided. If the URI is zero bytes long, the client can reuse the +current URI is reused instead. The new session URI SHOULD use the same scheme +as the current URL to ensure compatibility.

    +

    +If a server receives a GOAWAY with a non-zero New Session URI Length it MUST +terminate the session with a Protocol Violation.

    +
  • +
+
+
+
+
+

+7.4. SUBSCRIBE +

+

A subscription causes the publisher to send newly published objects for a track. +A subscriber MUST NOT make multiple active subscriptions for a track within a +single session and publishers SHOULD treat this as a protocol violation.

+

Filter Types

+

The subscriber specifies a filter on the subscription to allow +the publisher to identify which objects need to be delivered.

+

There are 3 types of filters:

+

Latest Object (0x2): Specifies an open-ended subscription beginning from +the current object of the current group. If no content has been delivered yet, +the subscription starts with the first published or received group.

+

AbsoluteStart (0x3): Specifies an open-ended subscription beginning +from the object identified in the StartGroup and StartObject fields. If the +StartGroup is prior to the current group, the subscription starts at the +beginning of the current object like the 'Latest Object' filter.

+

AbsoluteRange (0x4): Specifies a closed subscription starting at StartObject +in StartGroup and ending at the largest object in EndGroup. The start and +end of the range are inclusive. EndGroup MUST specify the same or a later +group than StartGroup. If the StartGroup is prior to the current group, the +subscription starts at the beginning of the current object like the 'Latest +Object' filter.

+

A filter type other than the above MUST be treated as error.

+

If a subscriber wants to subscribe to Objects both before and after +the Latest Object, it can send a SUBSCRIBE for the Latest Object +followed by a FETCH. Depending upon the application, one might want to send +both messages at the same time or wait for the first to return before sending +the second.

+

The format of SUBSCRIBE is as follows:

+
+
+
+
+SUBSCRIBE Message {
+  Type (i) = 0x3,
+  Length (i),
+  Subscribe ID (i),
+  Track Alias (i),
+  Track Namespace (tuple),
+  Track Name Length (i),
+  Track Name (..),
+  Subscriber Priority (8),
+  Group Order (8),
+  Filter Type (i),
+  [StartGroup (i),
+   StartObject (i)],
+  [EndGroup (i)],
+  Number of Parameters (i),
+  Subscribe Parameters (..) ...
+}
+
+
+
Figure 5: +MOQT SUBSCRIBE Message +
+
+
    +
  • +

    Subscribe ID: The subscriber specified identifier used to manage a +subscription. Subscribe ID is a variable length integer that MUST be +unique and monotonically increasing within a session and MUST be less +than the session's Maximum Subscribe ID.

    +
  • +
  • +

    Track Alias: A session specific identifier for the track. +Messages that reference a track, such as OBJECT (Section 8.1), +reference this Track Alias instead of the Track Name and Track Namespace to +reduce overhead. If the Track Alias is already being used for a different +track, the publisher MUST close the session with a Duplicate Track Alias +error (Section 3.5).

    +
  • +
  • +

    Track Namespace: Identifies the namespace of the track as defined in +(Section 2.4.1).

    +
  • +
  • +

    Track Name: Identifies the track name as defined in (Section 2.4.1).

    +
  • +
  • +

    Subscriber Priority: Specifies the priority of a subscription relative to +other subscriptions in the same session. Lower numbers get higher priority. +See Section 5.

    +
  • +
  • +

    Group Order: Allows the subscriber to request Objects be delivered in +Ascending (0x1) or Descending (0x2) order by group. See Section 5. +A value of 0x0 indicates the original publisher's Group Order SHOULD be +used. Values larger than 0x2 are a protocol error.

    +
  • +
  • +

    Filter Type: Identifies the type of filter, which also indicates whether +the StartGroup/StartObject and EndGroup/EndObject fields will be present.

    +
  • +
  • +

    StartGroup: The start Group ID. Only present for "AbsoluteStart" and +"AbsoluteRange" filter types.

    +
  • +
  • +

    StartObject: The start Object ID. Only present for "AbsoluteStart" and +"AbsoluteRange" filter types.

    +
  • +
  • +

    EndGroup: The end Group ID, inclusive. Only present for the "AbsoluteRange" +filter type.

    +
  • +
  • +

    Subscribe Parameters: The parameters are defined in Section 7.1.1.

    +
  • +
+

On successful subscription, the publisher MUST reply with a SUBSCRIBE_OK, +allowing the subscriber to determine the start group/object when not explicitly +specified and the publisher SHOULD start delivering objects.

+

If a publisher cannot satisfy the requested start or end or if the end has +already been published it SHOULD send a SUBSCRIBE_ERROR with code 'Invalid Range'. +A publisher MUST NOT send objects from outside the requested start and end.

+
+
+
+
+

+7.5. SUBSCRIBE_UPDATE +

+

A subscriber issues a SUBSCRIBE_UPDATE to a publisher to request a change to +an existing subscription. Subscriptions can only become more narrow, not wider, +because an attempt to widen a subscription could fail. If Objects before the +start or after the end of the current subscription are needed, a fetch might +be able to retrieve objects before the start. The start Object MUST NOT +decrease and when it increases, there is no guarantee that a publisher will +not have already sent Objects before the new start Object. The end Group +MUST NOT increase and when it decreases, there is no guarantee that a publisher +will not have already sent Objects after the new end Object. A publisher SHOULD +close the Session as a 'Protocol Violation' if the SUBSCRIBE_UPDATE violates +either rule or if the subscriber specifies a Subscribe ID that has not existed +within the Session.

+

There is no control message in response to a SUBSCRIBE_UPDATE, because it is +expected that it will always succeed and the worst outcome is that it is not +processed promptly and some extra objects from the existing subscription are +delivered.

+

Unlike a new subscription, SUBSCRIBE_UPDATE can not cause an Object to be +delivered multiple times. Like SUBSCRIBE, EndGroup MUST specify the +same or a later object than StartGroup and StartObject.

+

The format of SUBSCRIBE_UPDATE is as follows:

+
+
+
+
+SUBSCRIBE_UPDATE Message {
+  Type (i) = 0x2,
+  Length (i),
+  Subscribe ID (i),
+  StartGroup (i),
+  StartObject (i),
+  EndGroup (i),
+  Subscriber Priority (8),
+  Number of Parameters (i),
+  Subscribe Parameters (..) ...
+}
+
+
+
Figure 6: +MOQT SUBSCRIBE_UPDATE Message +
+
+
    +
  • +

    Subscribe ID: The subscription identifier that is unique within the session. +This MUST match an existing Subscribe ID.

    +
  • +
  • +

    StartGroup: The start Group ID.

    +
  • +
  • +

    StartObject: The start Object ID.

    +
  • +
  • +

    EndGroup: The end Group ID, plus 1. A value of 0 means the subscription is +open-ended.

    +
  • +
  • +

    Subscriber Priority: Specifies the priority of a subscription relative to +other subscriptions in the same session. Lower numbers get higher priority. +See Section 5.

    +
  • +
  • +

    Subscribe Parameters: The parameters are defined in Section 7.1.1.

    +
  • +
+
+
+
+
+

+7.6. UNSUBSCRIBE +

+

A subscriber issues a UNSUBSCRIBE message to a publisher indicating it is no +longer interested in receiving media for the specified track and requesting that +the publisher stop sending Objects as soon as possible.

+

The format of UNSUBSCRIBE is as follows:

+
+
+
+
+UNSUBSCRIBE Message {
+  Type (i) = 0xA,
+  Length (i),
+  Subscribe ID (i)
+}
+
+
+
Figure 7: +MOQT UNSUBSCRIBE Message +
+
+
    +
  • +

    Subscribe ID: Subscription Identifier as defined in Section 7.4.

    +
  • +
+
+
+
+
+

+7.7. FETCH +

+

A subscriber issues a FETCH to a publisher to request a range of already published +objects within a track. The publisher responding to a FETCH is responsible for retrieving +all available Objects. If there are gaps between Objects, the publisher omits them from the +fetch response. All omitted objects have status Object Does Not Exist.

+

Fetch Types

+

There are two types of Fetch messages:

+

Standalone Fetch (0x1) : A Fetch of Objects performed independently of any Subscribe.

+

Joining Fetch (0x2) : A Fetch joined together with a Subscribe by specifying +the Subscribe ID of an active subscription. A publisher receiving a +Joining Fetch uses properties of the associated Subscribe to determine the +Track Namespace, Track, StartGroup, StartObject, EndGroup, and EndObject such that +it is contiguous with the associated Subscribe. The Joining Fetch begins the +Preceding Group Offset prior to the associated subscription.

+

A Subscriber can use a Joining Fetch to, for example, fill a playback buffer with a +certain number of groups prior to the live edge of a track.

+

A Joining Fetch is only permitted when the associated Subscribe has the Filter +Type Latest Object.

+

A Fetch Type other than 0x1 or 0x2 MUST be treated as an error.

+

A publisher responds to a FETCH request with either a FETCH_OK or a FETCH_ERROR +message. If it responds with FETCH_OK, the publisher creates a new unidirectional +stream that is used to send the Objects. A relay MAY start sending objects immediately +in response to a FETCH, even if sending the FETCH_OK takes longer because it requires +going upstream to populate the latest object.

+

The Object Forwarding Preference does not apply to fetches.

+

Fetch specifies an inclusive range of Objects starting at StartObject +in StartGroup and ending at EndObject in EndGroup. EndGroup and EndObject MUST +specify the same or a later object than StartGroup and StartObject.

+

The format of FETCH is as follows:

+
+
+
+
+FETCH Message {
+  Type (i) = 0x16,
+  Length (i),
+  Subscribe ID (i),
+  Subscriber Priority (8),
+  Group Order (8),
+  Fetch Type (i),
+  [Track Namespace (tuple),
+   Track Name Length (i),
+   Track Name (..),
+   StartGroup (i),
+   StartObject (i),
+   EndGroup (i),
+   EndObject (i),]
+  [Joining Subscribe ID (i),
+   Preceding Group Offset (i),]
+  Number of Parameters (i),
+  Parameters (..) ...
+}
+
+
+
Figure 8: +MOQT FETCH Message +
+
+

Fields common to all Fetch Types:

+
    +
  • +

    Subscribe ID: The Subscribe ID identifies a given fetch request. Subscribe ID +is a variable length integer that MUST be unique and monotonically increasing +within a session.

    +
  • +
  • +

    Subscriber Priority: Specifies the priority of a fetch request relative to +other subscriptions or fetches in the same session. Lower numbers get higher +priority. See Section 5.

    +
  • +
  • +

    Group Order: Allows the subscriber to request Objects be delivered in +Ascending (0x1) or Descending (0x2) order by group. See Section 5. +A value of 0x0 indicates the original publisher's Group Order SHOULD be +used. Values larger than 0x2 are a protocol error.

    +
  • +
  • +

    Fetch Type: Identifies the type of Fetch, whether joining or standalone.

    +
  • +
  • +

    Parameters: The parameters are defined in Section 7.1.1.

    +
  • +
+

Fields present only for Standalone Fetch (0x1):

+
    +
  • +

    Track Namespace: Identifies the namespace of the track as defined in +(Section 2.4.1).

    +
  • +
  • +

    Track Name: Identifies the track name as defined in (Section 2.4.1).

    +
  • +
  • +

    StartGroup: The start Group ID.

    +
  • +
  • +

    StartObject: The start Object ID.

    +
  • +
  • +

    EndGroup: The end Group ID.

    +
  • +
  • +

    EndObject: The end Object ID, plus 1. A value of 0 means the entire group is +requested.

    +
  • +
+

Fields present only for Joining Fetch (0x2):

+
    +
  • +

    Joining Subscribe ID: The Subscribe ID of the existing subscription to be +joined. If a publisher receives a Joining Fetch with a Subscribe ID that does +not correspond to an existing Subscribe, it MUST respond with a Fetch Error.

    +
  • +
  • +

    Preceding Group Offset: The group offset for the Fetch prior and relative +to the Current Group of the corresponding Subscribe. A value of 0 indicates +the Fetch starts at the beginning of the Current Group.

    +
  • +
+

Objects that are not yet published will not be retrieved by a FETCH. +The latest available Object is indicated in the FETCH_OK, and is the last +Object a fetch will return if the EndGroup and EndObject have not yet been +published.

+

A publisher MUST send fetched groups in the determined group order, either +ascending or descending. Within each group, objects are sent in Object ID order; +subgroup ID is not used for ordering.

+

If StartGroup/StartObject is greater than the latest published Object group, +the publisher MUST return FETCH_ERROR with error code 'No Objects'.

+
+
+

+7.7.1. Calculating the Range of a Joining Fetch +

+

A publisher that receives a Fetch of type Type 0x2 treats it +as a Fetch with a range dynamically determined by the Preceding Group Offset +and field values derived from the corresponding subscription.

+

The Largest Group ID and Largest Object ID values from the corresponding +subscription are used to calculate the end of a Joining Fetch so the Objects +retrieved by the FETCH and SUBSCRIBE are contiguous and non-overlapping. +If no Objects have been published for the track, and the SUBSCRIBE_OK has a +ContentExists value of 0, the publisher responds with a FETCH_ERROR with +error code 'No Objects'.

+

The publisher receiving a Joining Fetch computes the range as follows:

+
    +
  • +

    Fetch StartGroup: Subscribe Largest Group - Preceding Group Offset

    +
  • +
  • +

    Fetch StartObject: 0

    +
  • +
  • +

    Fetch EndGroup: Subscribe Largest Group

    +
  • +
  • +

    Fetch EndObject: Subscribe Largest Object

    +
  • +
+

A Fetch EndObject of 0 requests the entire group, but Fetch will not +retrieve Objects that have not yet been published, so 1 is subtracted from +the Fetch EndGroup if Fetch EndObject is 0.

+
+
+
+
+
+
+

+7.8. FETCH_CANCEL +

+

A subscriber issues a FETCH_CANCEL message to a publisher indicating it is no +longer interested in receiving Objects for the fetch specified by 'Subscribe ID'. +The publisher SHOULD close the unidirectional stream as soon as possible.

+

The format of FETCH_CANCEL is as follows:

+
+
+
+
+FETCH_CANCEL Message {
+  Type (i) = 0x17,
+  Length (i),
+  Subscribe ID (i)
+}
+
+
+
Figure 9: +MOQT FETCH_CANCEL Message +
+
+
    +
  • +

    Subscribe ID: Subscription Identifier as defined in Section 7.7.

    +
  • +
+
+
+
+
+

+7.9. ANNOUNCE_OK +

+

The subscriber sends an ANNOUNCE_OK control message to acknowledge the +successful authorization and acceptance of an ANNOUNCE message.

+
+
+
+
+ANNOUNCE_OK Message
+{
+  Type (i) = 0x7,
+  Length (i),
+  Track Namespace (tuple),
+}
+
+
+
Figure 10: +MOQT ANNOUNCE_OK Message +
+
+
    +
  • +

    Track Namespace: Identifies the track namespace in the ANNOUNCE +message for which this response is provided.

    +
  • +
+
+
+
+
+

+7.10. ANNOUNCE_ERROR +

+

The subscriber sends an ANNOUNCE_ERROR control message for tracks that +failed authorization.

+
+
+
+
+ANNOUNCE_ERROR Message
+{
+  Type (i) = 0x8,
+  Length (i),
+  Track Namespace (tuple),
+  Error Code (i),
+  Reason Phrase Length (i),
+  Reason Phrase (..),
+}
+
+
+
Figure 11: +MOQT ANNOUNCE_ERROR Message +
+
+
    +
  • +

    Track Namespace: Identifies the track namespace in the ANNOUNCE +message for which this response is provided.

    +
  • +
  • +

    Error Code: Identifies an integer error code for announcement failure.

    +
  • +
  • +

    Reason Phrase: Provides the reason for announcement error.

    +
  • +
+

The application SHOULD use a relevant error code in ANNOUNCE_ERROR, as defined +below:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 3
CodeReason
0x0Internal Error
0x1Unauthorized
0x2Timeout
0x3Not Supported
0x4Uninterested
+
+
+
+
+

+7.11. ANNOUNCE_CANCEL +

+

The subscriber sends an ANNOUNCE_CANCEL control message to +indicate it will stop sending new subscriptions for tracks +within the provided Track Namespace.

+
+
+
+
+ANNOUNCE_CANCEL Message {
+  Type (i) = 0xC,
+  Length (i),
+  Track Namespace (tuple),
+  Error Code (i),
+  Reason Phrase Length (i),
+  Reason Phrase Length (..),
+}
+
+
+
Figure 12: +MOQT ANNOUNCE_CANCEL Message +
+
+
    +
  • +

    Track Namespace: Identifies a track's namespace as defined in +(Section 2.4.1).

    +
  • +
  • +

    Error Code: Identifies an integer error code for canceling the announcement. +ANNOUNCE_CANCEL uses the same error codes as ANNOUNCE_ERROR +(Section 7.10).

    +
  • +
  • +

    Reason Phrase: Provides the reason for announcement cancelation.

    +
  • +
+
+
+
+
+

+7.12. TRACK_STATUS_REQUEST +

+

A potential subscriber sends a 'TRACK_STATUS_REQUEST' message on the control +stream to obtain information about the current status of a given track.

+

A TRACK_STATUS message MUST be sent in response to each TRACK_STATUS_REQUEST.

+
+
+
+
+TRACK_STATUS_REQUEST Message {
+  Type (i) = 0xD,
+  Length (i),
+  Track Namespace (tuple),
+  Track Name Length (i),
+  Track Name (..),
+}
+
+
+
Figure 13: +MOQT TRACK_STATUS_REQUEST Message +
+
+
+
+
+
+

+7.13. SUBSCRIBE_ANNOUNCES +

+

The subscriber sends the SUBSCRIBE_ANNOUNCES control message to a publisher +to request the current set of matching announcements, as well as future updates +to the set.

+
+
+
+
+SUBSCRIBE_ANNOUNCES Message {
+  Type (i) = 0x11,
+  Length (i),
+  Track Namespace Prefix (tuple),
+  Number of Parameters (i),
+  Parameters (..) ...,
+}
+
+
+
Figure 14: +MOQT SUBSCRIBE_ANNOUNCES Message +
+
+
    +
  • +

    Track Namespace Prefix: An ordered N-Tuple of byte fields which are matched +against track namespaces known to the publisher. For example, if the publisher +is a relay that has received ANNOUNCE messages for namespaces ("example.com", +"meeting=123", "participant=100") and ("example.com", "meeting=123", +"participant=200"), a SUBSCRIBE_ANNOUNCES for ("example.com", "meeting=123") +would match both. If an endpoint receives a Track Namespace Prefix tuple with +an N of 0 or more than 32, it MUST close the session with a Protocol +Violation.

    +
  • +
  • +

    Parameters: The parameters are defined in Section 7.1.1.

    +
  • +
+

The publisher will respond with SUBSCRIBE_ANNOUNCES_OK or +SUBSCRIBE_ANNOUNCES_ERROR. If the SUBSCRIBE_ANNOUNCES is successful, +the publisher will forward any matching ANNOUNCE messages to the subscriber +that it has not yet sent. If the set of matching ANNOUNCE messages changes, the +publisher sends the corresponding ANNOUNCE or UNANNOUNCE message.

+

A subscriber cannot make overlapping namespace subscriptions on a single +session. Within a session, if a publisher receives a SUBSCRIBE_ANNOUNCES +with a Track Namespace Prefix that is a prefix of an earlier +SUBSCRIBE_ANNOUNCES or vice versa, it MUST respond with +SUBSCRIBE_ANNOUNCES_ERROR, with error code SUBSCRIBE_ANNOUNCES_OVERLAP.

+

The publisher MUST ensure the subscriber is authorized to perform this +namespace subscription.

+

SUBSCRIBE_ANNOUNCES is not required for a publisher to send ANNOUNCE and +UNANNOUNCE messages to a subscriber. It is useful in applications or relays +where subscribers are only interested in or authorized to access a subset of +available announcements.

+
+
+
+
+

+7.14. UNSUBSCRIBE_ANNOUNCES +

+

A subscriber issues a UNSUBSCRIBE_ANNOUNCES message to a publisher +indicating it is no longer interested in ANNOUNCE and UNANNOUNCE messages for +the specified track namespace prefix.

+

The format of UNSUBSCRIBE_ANNOUNCES is as follows:

+
+
+
+
+UNSUBSCRIBE_ANNOUNCES Message {
+  Type (i) = 0x14,
+  Length (i),
+  Track Namespace Prefix (tuple)
+}
+
+
+
Figure 15: +MOQT UNSUBSCRIBE Message +
+
+ +
+
+
+
+

+7.15. SUBSCRIBE_OK +

+

A publisher sends a SUBSCRIBE_OK control message for successful +subscriptions.

+
+
+
+
+SUBSCRIBE_OK
+{
+  Type (i) = 0x4,
+  Length (i),
+  Subscribe ID (i),
+  Expires (i),
+  Group Order (8),
+  ContentExists (8),
+  [Largest Group ID (i)],
+  [Largest Object ID (i)],
+  Number of Parameters (i),
+  Subscribe Parameters (..) ...
+}
+
+
+
Figure 16: +MOQT SUBSCRIBE_OK Message +
+
+
    +
  • +

    Subscribe ID: Subscription Identifier as defined in Section 7.4.

    +
  • +
  • +

    Expires: Time in milliseconds after which the subscription is no +longer valid. A value of 0 indicates that the subscription does not expire +or expires at an unknown time. Expires is advisory and a subscription can +end prior to the expiry time or last longer.

    +
  • +
  • +

    Group Order: Indicates the subscription will be delivered in +Ascending (0x1) or Descending (0x2) order by group. See Section 5. +Values of 0x0 and those larger than 0x2 are a protocol error.

    +
  • +
  • +

    ContentExists: 1 if an object has been published on this track, 0 if not. +If 0, then the Largest Group ID and Largest Object ID fields will not be +present. Any other value is a protocol error and MUST terminate the +session with a Protocol Violation (Section 3.5).

    +
  • +
  • +

    Largest Group ID: The largest Group ID available for this track. This field +is only present if ContentExists has a value of 1.

    +
  • +
  • +

    Largest Object ID: The largest Object ID available within the largest Group ID +for this track. This field is only present if ContentExists has a value of 1.

    +
  • +
  • +

    Subscribe Parameters: The parameters are defined in Section 7.1.1.

    +
  • +
+
+
+
+
+

+7.16. SUBSCRIBE_ERROR +

+

A publisher sends a SUBSCRIBE_ERROR control message in response to a +failed SUBSCRIBE.

+
+
+
+
+SUBSCRIBE_ERROR
+{
+  Type (i) = 0x5,
+  Length (i),
+  Subscribe ID (i),
+  Error Code (i),
+  Reason Phrase Length (i),
+  Reason Phrase (..),
+  Track Alias (i),
+}
+
+
+
Figure 17: +MOQT SUBSCRIBE_ERROR Message +
+
+
    +
  • +

    Subscribe ID: Subscription Identifier as defined in Section 7.4.

    +
  • +
  • +

    Error Code: Identifies an integer error code for subscription failure.

    +
  • +
  • +

    Reason Phrase: Provides the reason for subscription error.

    +
  • +
  • +

    Track Alias: When Error Code is 'Retry Track Alias', the subscriber SHOULD re-issue the +SUBSCRIBE with this Track Alias instead. If this Track Alias is already in use, +the subscriber MUST close the connection with a Duplicate Track Alias error +(Section 3.5).

    +
  • +
+

The application SHOULD use a relevant error code in SUBSCRIBE_ERROR, +as defined below:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 4
CodeReason
0x0Internal Error
0x1Unauthorized
0x2Timeout
0x3Not Supported
0x4Track Does Not Exist
0x5Invalid Range
0x6Retry Track Alias
+
+
+
+
+

+7.17. FETCH_OK +

+

A publisher sends a FETCH_OK control message in response to successful fetches. +A publisher MAY send Objects in response to a FETCH before the FETCH_OK message is sent, +but the FETCH_OK MUST NOT be sent until the latest group and object are known.

+
+
+
+
+FETCH_OK
+{
+  Type (i) = 0x18,
+  Length (i),
+  Subscribe ID (i),
+  Group Order (8),
+  End Of Track (8),
+  Largest Group ID (i),
+  Largest Object ID (i),
+  Number of Parameters (i),
+  Subscribe Parameters (..) ...
+}
+
+
+
Figure 18: +MOQT FETCH_OK Message +
+
+
    +
  • +

    Subscribe ID: Fetch Identifier as defined in Section 7.7.

    +
  • +
  • +

    Group Order: Indicates the fetch will be delivered in +Ascending (0x1) or Descending (0x2) order by group. See Section 5. +Values of 0x0 and those larger than 0x2 are a protocol error.

    +
  • +
  • +

    End Of Track: 1 if all objects have been published on this track, so +the Largest Group ID and Object Id indicate the last Object in the track, +0 if not.

    +
  • +
  • +

    Largest Group ID: The largest Group ID available for this track.

    +
  • +
  • +

    Largest Object ID: The largest Object ID available within the largest Group ID +for this track.

    +
  • +
  • +

    Subscribe Parameters: The parameters are defined in Section 7.1.1.

    +
  • +
+
+
+
+
+

+7.18. FETCH_ERROR +

+

A publisher sends a FETCH_ERROR control message in response to a +failed FETCH.

+
+
+
+
+FETCH_ERROR
+{
+  Type (i) = 0x19,
+  Length (i),
+  Subscribe ID (i),
+  Error Code (i),
+  Reason Phrase Length (i),
+  Reason Phrase (..),
+}
+
+
+
Figure 19: +MOQT FETCH_ERROR Message +
+
+
    +
  • +

    Subscribe ID: Subscription Identifier as defined in Section 7.4.

    +
  • +
  • +

    Error Code: Identifies an integer error code for fetch failure.

    +
  • +
  • +

    Reason Phrase: Provides the reason for fetch error.

    +
  • +
+

The application SHOULD use a relevant error code in FETCH_ERROR, +as defined below:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 5
CodeReason
0x0Internal Error
0x1Unauthorized
0x2Timeout
0x3Not Supported
0x4Track Does Not Exist
0x5Invalid Range
+
+
+
+
+

+7.19. SUBSCRIBE_DONE +

+

A publisher sends a SUBSCRIBE_DONE message to indicate it is done publishing +Objects for that subscription. The Status Code indicates why the subscription +ended, and whether it was an error. Because SUBSCRIBE_DONE is sent on the +control stream, it is likely to arrive at the receiver before late-arriving +objects, and often even late-opening streams. However, the receiver uses it +as an indication that it should receive any late-opening streams in a relatively +short time.

+

Note that some objects in the subscribed track might never be delivered, +because a stream was reset, or never opened in the first place, due to the +delivery timeout.

+

A sender MUST NOT send SUBSCRIBE_DONE until it has closed all streams it will +ever open, and has no further datagrams to send, for a subscription. After +sending SUBSCRIBE_DONE, the sender can immediately destroy subscription state, +although stream state can persist until delivery completes. The sender might +persist subscription state to enforce the delivery timeout by resetting streams +on which it has already sent FIN, only deleting it when all such streams have +received ACK of the FIN.

+

A sender MUST NOT destroy subscription state until it sends SUBSCRIBE_DONE, +though it can choose to stop sending objects (and thus send SUBSCRIBE_DONE) for +any reason.

+

A subscriber that receives SUBSCRIBE_DONE SHOULD set a timer of at least its +delivery timeout in case some objects are still inbound due to prioritization +or packet loss. The subscriber MAY dispense with a timer if it sent UNSUBSCRIBE +or is otherwise no longer interested in objects from the track. Once the timer +has expired, the receiver destroys subscription state once all open streams for +the subscription have closed. A subscriber MAY discard subscription state +earlier, at the cost of potentially not delivering some late objects to the +application. The subscriber SHOULD send STOP_SENDING on all streams related to +the subscription when it deletes subscription state.

+

The format of SUBSCRIBE_DONE is as follows:

+
+
+
+
+SUBSCRIBE_DONE Message {
+  Type (i) = 0xB,
+  Length (i),
+  Subscribe ID (i),
+  Status Code (i),
+  Stream Count (i),
+  Reason Phrase Length (i),
+  Reason Phrase (..),
+}
+
+
+
Figure 20: +MOQT SUBSCRIBE_DONE Message +
+
+
    +
  • +

    Subscribe ID: Subscription identifier as defined in Section 7.4.

    +
  • +
  • +

    Status Code: An integer status code indicating why the subscription ended.

    +
  • +
  • +

    Stream Count: An integer indicating the number of data streams the publisher +opened for this subscription. This helps the subscriber know if it has received +all of the data published in this subscription by comparing the number of +streams received. The subscriber can immediately remove all subscription state +once the same number of streams have been processed. If the track had +Forwarding Preference = Datagram, the publisher MUST set Stream Count to 0. If +the publisher is unable to set Stream Count to the exact number of streams +opened for the subscription, it MUST set Stream Count to 2^62 - 1. Subscribers +SHOULD use a timeout or other mechanism to remove subscription state in case +the publisher set an incorrect value, reset a stream before the SUBGROUP_HEADER, +or set the maximum value. If a subscriber receives more streams for a +subscription than specified in Stream Count, it MAY close the session with a +Protocol Violation.

    +
  • +
  • +

    Reason Phrase: Provides the reason for subscription error.

    +
  • +
+

The application SHOULD use a relevant status code in +SUBSCRIBE_DONE, as defined below:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 6
CodeReason
0x0Internal Error
0x1Unauthorized
0x2Track Ended
0x3Subscription Ended
0x4Going Away
0x5Expired
0x6Too Far Behind
+
+
+
+
+

+7.20. MAX_SUBSCRIBE_ID +

+

A publisher sends a MAX_SUBSCRIBE_ID message to increase the number of +subscriptions a subscriber can create within a session.

+

The Maximum Subscribe Id MUST only increase within a session, and +receipt of a MAX_SUBSCRIBE_ID message with an equal or smaller Subscribe ID +value is a 'Protocol Violation'.

+
+
+
+
+MAX_SUBSCRIBE_ID
+{
+  Type (i) = 0x15,
+  Length (i),
+  Subscribe ID (i),
+}
+
+
+
Figure 21: +MOQT MAX_SUBSCRIBE_ID Message +
+
+
    +
  • +

    Subscribe ID: The new Maximum Subscribe ID for the session. If a Subscribe ID +Section 7.4 equal or larger than this is received by the publisher +that sent the MAX_SUBSCRIBE_ID, the publisher MUST close the session with an +error of 'Too Many Subscribes'.

    +
  • +
+

MAX_SUBSCRIBE_ID is similar to MAX_STREAMS in ([RFC9000], Section 4.6), +and similar considerations apply when deciding how often to send MAX_SUBSCRIBE_ID. +For example, implementations might choose to increase MAX_SUBSCRIBE_ID as +subscriptions close to keep the number of subscriptions available to subscribers +roughly consistent.

+
+
+
+
+

+7.21. SUBSCRIBES_BLOCKED +

+

The SUBSCRIBES_BLOCKED message is sent when a subscriber would like to begin +a new subscription, but cannot because the Subscribe ID would exceed the +Maximum Subscribe ID value sent by the peer. The subscriber SHOULD send only +one SUBSCRIBES_BLOCKED for a given Maximum Subscribe ID.

+

A publisher MAY send a MAX_SUBSCRIBE_ID upon receipt of SUBSCRIBES_BLOCKED, +but it MUST NOT rely on SUBSCRIBES_BLOCKED to trigger sending a +MAX_SUBSCRIBE_ID, because sending SUBSCRIBES_BLOCKED is not required.

+
+
+
+
+SUBSCRIBES_BLOCKED
+{
+  Type (i) = 0x1A,
+  Length (i),
+  Maximum Subscribe ID (i),
+}
+
+
+
Figure 22: +MOQT SUBSCRIBES_BLOCKED Message +
+
+
    +
  • +

    Maximum Subscribe ID: The Maximum Subscribe ID for the session on which the subscriber +is blocked. More on Subscribe ID in Section 7.4.

    +
  • +
+
+
+
+
+

+7.22. ANNOUNCE +

+

The publisher sends the ANNOUNCE control message to advertise where the +receiver can route SUBSCRIBEs for tracks within the announced +Track Namespace. The receiver verifies the publisher is authorized to +publish tracks under this namespace.

+
+
+
+
+ANNOUNCE Message {
+  Type (i) = 0x6,
+  Length (i),
+  Track Namespace (tuple),
+  Number of Parameters (i),
+  Parameters (..) ...,
+}
+
+
+
Figure 23: +MOQT ANNOUNCE Message +
+
+
    +
  • +

    Track Namespace: Identifies a track's namespace as defined in +(Section 2.4.1)

    +
  • +
  • +

    Parameters: The parameters are defined in Section 7.1.1.

    +
  • +
+
+
+
+
+

+7.23. UNANNOUNCE +

+

The publisher sends the UNANNOUNCE control message to indicate +its intent to stop serving new subscriptions for tracks +within the provided Track Namespace.

+
+
+
+
+UNANNOUNCE Message {
+  Type (i) = 0x9,
+  Length (i),
+  Track Namespace (tuple),
+}
+
+
+
Figure 24: +MOQT UNANNOUNCE Message +
+
+
    +
  • +

    Track Namespace: Identifies a track's namespace as defined in +(Section 2.4.1).

    +
  • +
+
+
+
+
+

+7.24. TRACK_STATUS +

+

A publisher sends a 'TRACK_STATUS' message on the control stream in response +to a TRACK_STATUS_REQUEST message.

+
+
+
+
+TRACK_STATUS Message {
+  Type (i) = 0xE,
+  Length (i),
+  Track Namespace (tuple),
+  Track Name Length(i),
+  Track Name (..),
+  Status Code (i),
+  Last Group ID (i),
+  Last Object ID (i),
+}
+
+
+
Figure 25: +MOQT TRACK_STATUS Message +
+
+

The 'Status Code' field provides additional information about the status of the +track. It MUST hold one of the following values. Any other value is a malformed +message.

+

0x00: The track is in progress, and subsequent fields contain the highest group +and object ID for that track.

+

0x01: The track does not exist. Subsequent fields MUST be zero, and any other +value is a malformed message.

+

0x02: The track has not yet begun. Subsequent fields MUST be zero. Any other +value is a malformed message.

+

0x03: The track has finished, so there is no "live edge." Subsequent fields +contain the highest Group and object ID known.

+

0x04: The publisher is a relay that cannot obtain the current track status from +upstream. Subsequent fields contain the largest group and object ID known.

+

Any other value in the Status Code field is a malformed message.

+

When a relay is subscribed to a track, it can simply return the highest group +and object ID it has observed, whether or not that object was cached or +completely delivered. If not subscribed, a relay SHOULD send a +TRACK_STATUS_REQUEST upstream to obtain updated information.

+

Alternatively, the relay MAY subscribe to the track to obtain the same +information.

+

If a relay cannot or will not do either, it should return its best available +information with status code 0x04.

+

The receiver of multiple TRACK_STATUS messages for a track uses the information +from the latest arriving message, as they are delivered in order on a single +stream.

+
+
+
+
+

+7.25. SUBSCRIBE_ANNOUNCES_OK +

+

A publisher sends a SUBSCRIBE_ANNOUNCES_OK control message for successful +namespace subscriptions.

+
+
+
+
+SUBSCRIBE_ANNOUNCES_OK
+{
+  Type (i) = 0x12,
+  Length (i),
+  Track Namespace Prefix (tuple),
+}
+
+
+
Figure 26: +MOQT SUBSCRIBE_ANNOUNCES_OK Message +
+
+ +
+
+
+
+

+7.26. SUBSCRIBE_ANNOUNCES_ERROR +

+

A publisher sends a SUBSCRIBE_ANNOUNCES_ERROR control message in response to +a failed SUBSCRIBE_ANNOUNCES.

+
+
+
+
+SUBSCRIBE_ANNOUNCES_ERROR
+{
+  Type (i) = 0x13,
+  Length (i),
+  Track Namespace Prefix (tuple),
+  Error Code (i),
+  Reason Phrase Length (i),
+  Reason Phrase (..),
+}
+
+
+
Figure 27: +MOQT SUBSCRIBE_ANNOUNCES_ERROR Message +
+
+
    +
  • +

    Track Namespace Prefix: As defined in Section 7.13.

    +
  • +
  • +

    Error Code: Identifies an integer error code for the namespace subscription +failure.

    +
  • +
  • +

    Reason Phrase: Provides the reason for the namespace subscription error.

    +
  • +
+

The application SHOULD use a relevant error code in SUBSCRIBE_ANNOUNCES_ERROR, +as defined below:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 7
CodeReason
0x0Internal Error
0x1Unauthorized
0x2Timeout
0x3Not Supported
0x4Namespace Prefix Unknown
+
+
+
+
+
+
+

+8. Data Streams +

+

A publisher sends Objects matching a subscription on Data Streams.

+

All unidirectional MOQT streams start with a variable-length integer indicating +the type of the stream in question.

+ + + + + + + + + + + + + + + + + + +
Table 8
IDType
0x4SUBGROUP_HEADER (Section 8.4.1)
0x5FETCH_HEADER (Section 8.4.3)
+

All MOQT datagrams start with a variable-length integer indicating the type of +the datagram.

+ + + + + + + + + + + + + + + + + + +
Table 9
IDType
0x1OBJECT_DATAGRAM (Section 8.2)
0x2OBJECT_DATAGRAM_STATUS (Section 8.2)
+

An endpoint that receives an unknown stream or datagram type MUST close the +session.

+

The publisher only sends Objects after receiving a SUBSCRIBE or FETCH. The +publisher MUST NOT send Objects that are not requested. If an endpoint receives +an Object it never requested, it SHOULD terminate the session with a protocol +violation. Objects can arrive after a subscription or fetch has been cancelled, +so the session MUST NOT be teriminated in that case.

+

Every Track has a single 'Object Forwarding Preference' and the Original +Publisher MUST NOT mix different forwarding preferences within a single track. +If a subscriber receives different forwarding preferences for a track, it +SHOULD close the session with an error of 'Protocol Violation'.

+
+
+

+8.1. Object Headers +

+

An OBJECT message contains a range of contiguous bytes from from the +specified track, as well as associated metadata required to deliver, +cache, and forward it. Objects are sent by publishers.

+
+
+

+8.1.1. Canonical Object Fields +

+

A canonical MoQ Object has the following information:

+
    +
  • +

    Track Namespace and Track Name: The track this object belongs to.

    +
  • +
  • +

    Group ID: The object is a member of the indicated group ID +Section 2.3 within the track.

    +
  • +
  • +

    Object ID: The order of the object within the group. The +IDs starts at 0, increasing sequentially for each object within the +group.

    +
  • +
  • +

    Publisher Priority: An 8 bit integer indicating the publisher's priority for +the Object Section 5.

    +
  • +
  • +

    Object Forwarding Preference: An enumeration indicating how a publisher sends +an object. The preferences are Subgroup and Datagram. An Object +MUST be sent according to its Object Forwarding Preference, described below.

    +
  • +
  • +

    Subgroup ID: The object is a member of the indicated subgroup ID (Section 2.2) +within the group. This field is omitted if the Object Forwarding Preference is +Track or Datagram.

    +
  • +
  • +

    Object Status: As enumeration used to indicate missing +objects or mark the end of a group or track. See Section 8.1.1.1 below.

    +
  • +
  • +

    Object Extension Length: The total length of the Object Extension Headers +block, in bytes.

    +
  • +
  • +

    Object Extensions : A sequence of Object Extension Headers. See +Section 8.1.1.2 below.

    +
  • +
  • +

    Object Payload: An opaque payload intended for an End Subscriber and SHOULD NOT be processed by a relay. Only present when 'Object Status' is Normal (0x0).

    +
  • +
+
+
+
+8.1.1.1. Object Status +
+

The Object Status informs subscribers what objects will not be received +because they were never produced, are no longer available, or because they +are beyond the end of a group or track.

+

Status can have following values:

+
    +
  • +

    0x0 := Normal object. This status is implicit for any non-zero length object. + Zero-length objects explicitly encode the Normal status.

    +
  • +
  • +

    0x1 := Indicates Object does not exist. Indicates that this object + does not exist at any publisher and it will not be published in + the future. This SHOULD be cached.

    +
  • +
  • +

    0x3 := Indicates end of Group. ObjectId is one greater that the + largest object produced in the group identified by the + GroupID. This is sent right after the last object in the + group. If the ObjectID is 0, it indicates there are no Objects + in this Group. This SHOULD be cached. A publisher MAY use an end of + Group object to signal the end of all open Subgroups in a Group.

    +
  • +
  • +

    0x4 := Indicates end of Track and Group. GroupID is the largest group produced + in this track and the ObjectId is one greater than the largest object + produced in that group. An object with this status that has a Group ID + less than any other Group ID, or an Object ID less than or equal to the + largest in the group, is a protocol error, and the receiver MUST + terminate the session. This SHOULD be cached.

    +
  • +
  • +

    0x5 := Indicates end of Track. GroupID is one greater than the largest group + produced in this track and the ObjectId is zero. An object with this + status that has a Group ID less than or equal to any other Group ID, or + an Object ID other than zero, is a protocol error, and the receiver + MUST terminate the session. This SHOULD be cached.

    +
  • +
+

Any other value SHOULD be treated as a protocol error and terminate the +session with a Protocol Violation (Section 3.5). +Any object with a status code other than zero MUST have an empty payload.

+

Though some status information could be inferred from QUIC stream state, +that information is not reliable and cacheable.

+
+
+
+
+
+8.1.1.2. Object Extension Header +
+

Object Extension Headers are visible to relays and allow the transmission of +future metadata relevant to MOQT Object distribution. Any Object metadata never +accessed by the transport or relays SHOULD be serialized as part of the Object +payload and not as an extension header.

+

Extension Headers are defined in external specifications and registered in an +IANA table Section 10. These specifications define the type and value of the +header, along with any rules concerning processing, modification, caching and +forwarding. A relay which is coded to implement these rules is said to +"support" the extension.

+

If unsupported by the relay, Extension Headers MUST NOT be modified, MUST be +cached as part of the Object and MUST be forwarded by relays.

+

If supported by the relay and subject to the processing rules specified in the +definition of the extension, Extension Headers MAY be modified, added, removed, +and/or cached by relays.

+

Object Extension Headers are serialized as defined below:

+
+
+
+
+Extension Header {
+  Header Type (i),
+  [Header Value (i)]
+  [Header Length (i),
+   Header Value (..)]
+}
+
+
+
Figure 28: +Object Extension Header Format +
+
+
    +
  • +

    Header type: an unsigned integer, encoded as a varint, identifying the type +of the extension and also the subsequent serialization.

    +
  • +
  • +

    Header values: even types are followed by a single varint encoded value. Odd +types are followed by a varint encoded length and then the header value. +Header types are registered in the IANA table 'MOQ Extension Headers'. +See Section 10.

    +
  • +
+
+
+
+
+
+
+
+
+

+8.2. Object Datagram +

+

An OBJECT_DATAGRAM carries a single object in a datagram.

+

An Object received in an OBJECT_DATAGRAM message has an Object +Forwarding Preference = Datagram. To send an Object with Object +Forwarding Preference = Datagram, determine the length of the header and +payload and send the Object as datagram. In certain scenarios where the object +size can be larger than maximum datagram size for the session, the Object +will be dropped.

+
+
+
+
+OBJECT_DATAGRAM {
+  Track Alias (i),
+  Group ID (i),
+  Object ID (i),
+  Publisher Priority (8),
+  Extension Headers Length (i),
+  [Extension headers (...)],
+  Object Payload (..),
+}
+
+
+
Figure 29: +MOQT OBJECT_DATAGRAM +
+
+

There is no explicit length field. The entirety of the transport datagram +following Publisher Priority contains the Object Payload.

+
+
+
+
+

+8.3. Object Datagram Status +

+

An OBJECT_DATAGRAM_STATUS is similar to OBEJCT_DATAGRAM except it +conveys an Object Status and has no payload.

+
+
+
+
+OBJECT_DATAGRAM_STATUS {
+  Track Alias (i),
+  Group ID (i),
+  Object ID (i),
+  Publisher Priority (8),
+  Extension Headers Length (i),
+  [Extension headers (...)],
+  Object Status (i),
+}
+
+
+
Figure 30: +MOQT OBJECT_DATAGRAM_STATUS +
+
+
+
+
+
+

+8.4. Streams +

+

When objects are sent on streams, the stream begins with a Subgroup Header +and is followed by one or more sets of serialized object fields. +If a stream ends gracefully in the middle of a serialized Object, the session +SHOULD be terminated with a Protocol Violation.

+

A publisher SHOULD NOT open more than one stream at a time with the same Subgroup +Header field values.

+
+
+

+8.4.1. Subgroup Header +

+

When a stream begins with SUBGROUP_HEADER, all Objects on the stream +belong to the track requested in the Subscribe message identified by Track Alias +and the subgroup indicated by 'Group ID' and Subgroup ID.

+
+
+
+
+SUBGROUP_HEADER {
+  Track Alias (i),
+  Group ID (i),
+  Subgroup ID (i),
+  Publisher Priority (8),
+}
+
+
+
Figure 31: +MOQT SUBGROUP_HEADER +
+
+

All Objects received on a stream opened with SUBGROUP_HEADER have an +Object Forwarding Preference = Subgroup.

+

To send an Object with Object Forwarding Preference = Subgroup, find the open +stream that is associated with the subscription, Group ID and Subgroup ID, +or open a new one and send the SUBGROUP_HEADER. Then serialize the +following fields.

+

The Object Status field is only sent if the Object Payload Length is zero.

+
+
+
+
+{
+  Object ID (i),
+  Extension Headers Length (i),
+  [Extension headers (...)],
+  Object Payload Length (i),
+  [Object Status (i)],
+  Object Payload (..),
+}
+
+
+
Figure 32: +MOQT Subgroup Fields +
+
+

A publisher MUST NOT send an Object on a stream if its Object ID is less than a +previously sent Object ID within a given group in that stream.

+
+
+
+
+

+8.4.2. Closing Subgroup Streams +

+

Subscribers will often need to know if they have received all objects in a +Subgroup, particularly if they serve as a relay or cache. QUIC and Webtransport +streams provide signals that can be used for this purpose. Closing Subgroups +promptly frees system resources and often unlocks flow control credit to open +more streams.

+

If a sender has delivered all objects in a Subgroup to the QUIC stream, except +any objects before the beginning of a subscription, it MUST close the +stream with a FIN.

+

If a sender closes the stream before delivering all such objects to the QUIC +stream, it MUST use a RESET_STREAM or RESET_STREAM_AT +[I-D.draft-ietf-quic-reliable-stream-reset] frame. This includes an open +Subgroup exceeding its Delivery Timeout, early termination of subscription due to +an UNSUBSCRIBE message, a publisher's decision to end the subscription early, or a +SUBSCRIBE_UPDATE moving the end of the subscription to before the current Group +or the start after the current Group. When RESET_STREAM_AT is used, the +reliable_size SHOULD include the stream header so the receiver can identify the +corresponding subscription and accurately account for reset data streams when +handling SUBSCRIBE_DONE (see Section 7.19). Publishers that reset +data streams without using RESET_STREAM_AT with an appropriate reliable_size can +cause subscribers to hold on to subscription state until a timeout expires.

+

A sender might send all objects in a Subgroup and the FIN on a QUIC stream, +and then reset the stream. In this case, the receiving application would receive +the FIN if and only if all objects were received. If the application receives +all data on the stream and the FIN, it can ignore any RESET_STREAM it receives.

+

If a sender will not deliver any objects from a Subgroup, it MAY send +a SUBGROUP_HEADER on a new stream, with no objects, and then send RESET_STREAM_AT +with a reliable_size equal to the length of the stream header. This explicitly +tells the receiver there is an unsent Subgroup.

+

Since SUBSCRIBEs always end on a group boundary, an ending subscription can +always cleanly close all its subgroups. A sender that terminates a stream +early for any other reason (e.g., to handoff to a different sender) MUST +use RESET_STREAM or RESET_STREAM_AT. Senders SHOULD terminate a stream on +Group boundaries to avoid doing so.

+

An MoQT implementation that processes a stream FIN is assured it has received +all objects in a subgroup from the start of the subscription. If a relay, it +can forward stream FINs to its own subscribers once those objects have been +sent. A relay MAY treat receipt of EndOfGroup, GroupDoesNotExist, or +EndOfTrack objects as a signal to close corresponding streams even if the FIN +has not arrived, as further objects on the stream would be a protocol violation.

+

Similarly, an EndOfGroup message indicates the maximum Object ID in the +Group, so if all Objects in the Group have been received, a FIN can be sent on +any stream where the entire subgroup has been sent. This might be complex to +implement.

+

Processing a RESET_STREAM or RESET_STREAM_AT means that there might be other +objects in the Subgroup beyond the last one received. A relay might immediately +reset the corresponding downstream stream, or it might attempt to recover the +missing Objects in an effort send all the objects in the subgroups and the FIN. It also +might send RESET_STREAM_AT with reliable_size set to the last object it has, so +as to reliably deliver the objects it has while signaling that other objects +might exist.

+

A subscriber MAY send a QUIC STOP_SENDING frame for a subgroup stream if the Group +or Subgroup is no longer of interest to it. The publisher SHOULD respond with +RESET_STREAM or RESET_STREAM_AT. If RESET_STREAM_AT is sent, note that the receiver +has indicated no interest in the objects, so setting a reliable_size beyond the +stream header is of questionable utility.

+

RESET_STREAM and STOP_SENDING on SUBSCRIBE data streams have no impact on other +Subgroups in the Group or the subscription, although applications might cancel all +Subgroups in a Group at once.

+
+
+
+
+

+8.4.3. Fetch Header +

+

When a stream begins with FETCH_HEADER, all objects on the stream belong to the +track requested in the Fetch message identified by Subscribe ID.

+
+
+
+
+FETCH_HEADER {
+  Subscribe ID (i),
+}
+
+
+
Figure 33: +MOQT FETCH_HEADER +
+
+

Each object sent on a fetch stream after the FETCH_HEADER has the following format:

+
+
+
+
+{
+  Group ID (i),
+  Subgroup ID (i),
+  Object ID (i),
+  Publisher Priority (8),
+  Extension Headers Length (i),
+  [Extension headers (...)],
+  Object Payload Length (i),
+  [Object Status (i)],
+  Object Payload (..),
+}
+
+
+
Figure 34: +MOQT Fetch Object Fields +
+
+

The Object Status field is only sent if the Object Payload Length is zero.

+

The Subgroup ID field of an object with a Forwarding Preference of "Datagram" +(see Section 8.1.1) is set to the Object ID.

+
+
+
+
+
+
+

+8.5. Examples +

+

Sending a subgroup on one stream:

+
+
+Stream = 2
+
+SUBGROUP_HEADER {
+  Track Alias = 2
+  Group ID = 0
+  Subgroup ID = 0
+  Publisher Priority = 0
+}
+{
+  Object ID = 0
+  Extension Headers Length = 0
+  Object Payload Length = 4
+  Payload = "abcd"
+}
+{
+  Object ID = 1
+  Extension Headers Length = 0
+  Object Payload Length = 4
+  Payload = "efgh"
+}
+
+
+

Sending a group on one stream, with the first object containing two +Extension Headers.

+
+
+Stream = 2
+
+STREAM_HEADER_GROUP {
+  Subscribe ID = 2
+  Track Alias = 2
+  Group ID = 0
+  Publisher Priority = 0
+}
+{
+  Object ID = 0
+  Extension Headers Length = 33
+    { Type = 4
+      Value = 2186796243
+    },
+    { Type = 77
+      Length = 21
+      Value = "traceID:123456"
+    }
+  Object Payload Length = 4
+  Payload = "abcd"
+}
+{
+  Object ID = 1
+  Extension Headers Length = 0
+  Object Payload Length = 4
+  Payload = "efgh"
+}
+
+
+
+
+
+
+
+
+
+

+9. Security Considerations +

+

TODO: Expand this section, including subscriptions.

+
+
+

+9.1. Resource Exhaustion +

+

Live content requires significant bandwidth and resources. Failure to +set limits will quickly cause resource exhaustion.

+

MOQT uses stream limits and flow control to impose resource limits at +the network layer. Endpoints SHOULD set flow control limits based on the +anticipated bitrate.

+

Endpoints MAY impose a MAX STREAM count limit which would restrict the +number of concurrent streams which a MOQT Streaming Format could have in +flight.

+

The publisher prioritizes and transmits streams out of order. Streams +might be starved indefinitely during congestion. The publisher and +subscriber MUST cancel a stream, preferably the lowest priority, after +reaching a resource limit.

+
+
+
+
+

+9.2. Timeouts +

+

Implementations are advised to use timeouts to prevent resource +exhaustion attacks by a peer that does not send expected data within +an expected time. Each implementation is expected to set its own limits.

+
+
+
+
+
+
+

+10. IANA Considerations +

+

TODO: fill out currently missing registries:

+
    +
  • +

    MOQT version numbers

    +
  • +
  • +

    Setup parameters

    +
  • +
  • +

    Subscribe parameters

    +
  • +
  • +

    Subscribe Error codes

    +
  • +
  • +

    Subscribe Namespace Error codes

    +
  • +
  • +

    Announce Error codes

    +
  • +
  • +

    Announce Cancel Reason codes

    +
  • +
  • +

    Message types

    +
  • +
  • +

    MOQ Extension headers - we wish to reserve extension types 0-63 for +standards utilization where space is a premium, 64 - 16383 for +standards utilization where space is less of a concern, and 16384 and +above for first-come-first-served non-standardization usage.

    +
  • +
+

TODO: register the URI scheme and the ALPN and grease the Extension types

+
+
+
+
+

+Contributors +

+
    +
  • +

    Alan Frindell

    +
  • +
  • +

    Ali Begen

    +
  • +
  • +

    Charles Krasic

    +
  • +
  • +

    Christian Huitema

    +
  • +
  • +

    Cullen Jennings

    +
  • +
  • +

    James Hurley

    +
  • +
  • +

    Jordi Cenzano

    +
  • +
  • +

    Mike English

    +
  • +
  • +

    Mo Zanaty

    +
  • +
  • +

    Will Law

    +
  • +
+
+
+
+
+

+References +

+
+
+

+Normative References +

+
+
[I-D.draft-ietf-quic-reliable-stream-reset]
+
+Seemann, M. and K. Oku, "QUIC Stream Resets with Partial Delivery", Work in Progress, Internet-Draft, draft-ietf-quic-reliable-stream-reset-06, , <https://datatracker.ietf.org/doc/html/draft-ietf-quic-reliable-stream-reset-06>.
+
+
[QUIC]
+
+Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based Multiplexed and Secure Transport", RFC 9000, DOI 10.17487/RFC9000, , <https://www.rfc-editor.org/rfc/rfc9000>.
+
+
[RFC2119]
+
+Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/rfc/rfc2119>.
+
+
[RFC3986]
+
+Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, , <https://www.rfc-editor.org/rfc/rfc3986>.
+
+
[RFC7301]
+
+Friedl, S., Popov, A., Langley, A., and E. Stephan, "Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension", RFC 7301, DOI 10.17487/RFC7301, , <https://www.rfc-editor.org/rfc/rfc7301>.
+
+
[RFC8174]
+
+Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/rfc/rfc8174>.
+
+
[RFC8615]
+
+Nottingham, M., "Well-Known Uniform Resource Identifiers (URIs)", RFC 8615, DOI 10.17487/RFC8615, , <https://www.rfc-editor.org/rfc/rfc8615>.
+
+
[RFC9110]
+
+Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Semantics", STD 97, RFC 9110, DOI 10.17487/RFC9110, , <https://www.rfc-editor.org/rfc/rfc9110>.
+
+
[WebTransport]
+
+Frindell, A., Kinnear, E., and V. Vasiliev, "WebTransport over HTTP/3", Work in Progress, Internet-Draft, draft-ietf-webtrans-http3-11, , <https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-http3-11>.
+
+
+
+
+
+
+

+Informative References +

+
+
[I-D.ietf-webtrans-overview]
+
+Vasiliev, V., "The WebTransport Protocol Framework", Work in Progress, Internet-Draft, draft-ietf-webtrans-overview-09, , <https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-overview-09>.
+
+
[RFC9000]
+
+Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based Multiplexed and Secure Transport", RFC 9000, DOI 10.17487/RFC9000, , <https://www.rfc-editor.org/rfc/rfc9000>.
+
+
+
+
+
+
+
+
+

+Authors' Addresses +

+
+
Luke Curley
+
Discord
+ +
+
+
Kirill Pugin
+
Meta
+ +
+
+
Suhas Nandakumar
+
Cisco
+ +
+
+
Victor Vasiliev
+
Google
+ +
+
+
Ian Swett (editor)
+
Google
+ +
+
+
+ + + diff --git a/ianswett-move-connection-url/draft-ietf-moq-transport.txt b/ianswett-move-connection-url/draft-ietf-moq-transport.txt new file mode 100644 index 00000000..6da4b353 --- /dev/null +++ b/ianswett-move-connection-url/draft-ietf-moq-transport.txt @@ -0,0 +1,3057 @@ + + + + +Media Over QUIC L. Curley +Internet-Draft Discord +Intended status: Standards Track K. Pugin +Expires: 3 September 2025 Meta + S. Nandakumar + Cisco + V. Vasiliev + I. Swett, Ed. + Google + 2 March 2025 + + + Media over QUIC Transport + draft-ietf-moq-transport-latest + +Abstract + + This document defines the core behavior for Media over QUIC Transport + (MOQT), a media transport protocol designed to operate over QUIC and + WebTransport, which have similar functionality. MOQT allows a + producer of media to publish data and have it consumed via + subscription by a multiplicity of endpoints. It supports + intermediate content distribution networks and is designed for high + scale and low latency distribution. + +About This Document + + This note is to be removed before publishing as an RFC. + + The latest revision of this draft can be found at https://moq- + wg.github.io/moq-transport/draft-ietf-moq-transport.html. Status + information for this document may be found at + https://datatracker.ietf.org/doc/draft-ietf-moq-transport/. + + Discussion of this document takes place on the Media Over QUIC + Working Group mailing list (mailto:moq@ietf.org), which is archived + at https://mailarchive.ietf.org/arch/browse/moq/. Subscribe at + https://www.ietf.org/mailman/listinfo/moq/. + + Source for this draft and an issue tracker can be found at + https://github.com/moq-wg/moq-transport. + +Status of This Memo + + This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79. + + Internet-Drafts are working documents of the Internet Engineering + Task Force (IETF). Note that other groups may also distribute + working documents as Internet-Drafts. The list of current Internet- + Drafts is at https://datatracker.ietf.org/drafts/current/. + + Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress." + + This Internet-Draft will expire on 3 September 2025. + +Copyright Notice + + Copyright (c) 2025 IETF Trust and the persons identified as the + document authors. All rights reserved. + + This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents (https://trustee.ietf.org/ + license-info) in effect on the date of publication of this document. + Please review these documents carefully, as they describe your rights + and restrictions with respect to this document. Code Components + extracted from this document must include Revised BSD License text as + described in Section 4.e of the Trust Legal Provisions and are + provided without warranty as described in the Revised BSD License. + +Table of Contents + + 1. Introduction + 1.1. Motivation + 1.1.1. Latency + 1.1.2. Leveraging QUIC + 1.1.3. Convergence + 1.1.4. Relays + 1.2. Terms and Definitions + 1.3. Notational Conventions + 2. Object Data Model + 2.1. Objects + 2.2. Subgroups + 2.3. Groups + 2.4. Track + 2.4.1. Track Naming and Scopes + 2.4.2. Scope + 3. Sessions + 3.1. Session establishment + 3.1.1. WebTransport + 3.1.2. QUIC + 3.1.3. Connection URL + 3.2. Version and Extension Negotiation + 3.3. Session initialization + 3.4. Stream Cancellation + 3.5. Termination + 3.6. Migration + 4. Track Discovery and Retrieval + 4.1. SUBSCRIBE_ANNOUNCES + 4.2. ANNOUNCE + 4.3. SUBSCRIBE/FETCH + 5. Priorities + 5.1. Definitions + 5.2. Scheduling Algorithm + 5.3. Considerations for Setting Priorities + 6. Relays + 6.1. Subscriber Interactions + 6.1.1. Graceful Subscriber Relay Switchover + 6.2. Publisher Interactions + 6.2.1. Graceful Publisher Network Switchover + 6.2.2. Graceful Publisher Relay Switchover + 6.3. Relay Object Handling + 7. Control Messages + 7.1. Parameters + 7.1.1. Version Specific Parameters + 7.2. CLIENT_SETUP and SERVER_SETUP + 7.2.1. Versions + 7.2.2. Setup Parameters + 7.3. GOAWAY + 7.4. SUBSCRIBE + 7.5. SUBSCRIBE_UPDATE + 7.6. UNSUBSCRIBE + 7.7. FETCH + 7.7.1. Calculating the Range of a Joining Fetch + 7.8. FETCH_CANCEL + 7.9. ANNOUNCE_OK + 7.10. ANNOUNCE_ERROR + 7.11. ANNOUNCE_CANCEL + 7.12. TRACK_STATUS_REQUEST + 7.13. SUBSCRIBE_ANNOUNCES + 7.14. UNSUBSCRIBE_ANNOUNCES + 7.15. SUBSCRIBE_OK + 7.16. SUBSCRIBE_ERROR + 7.17. FETCH_OK + 7.18. FETCH_ERROR + 7.19. SUBSCRIBE_DONE + 7.20. MAX_SUBSCRIBE_ID + 7.21. SUBSCRIBES_BLOCKED + 7.22. ANNOUNCE + 7.23. UNANNOUNCE + 7.24. TRACK_STATUS + 7.25. SUBSCRIBE_ANNOUNCES_OK + 7.26. SUBSCRIBE_ANNOUNCES_ERROR + 8. Data Streams + 8.1. Object Headers + 8.1.1. Canonical Object Fields + 8.2. Object Datagram + 8.3. Object Datagram Status + 8.4. Streams + 8.4.1. Subgroup Header + 8.4.2. Closing Subgroup Streams + 8.4.3. Fetch Header + 8.5. Examples + 9. Security Considerations + 9.1. Resource Exhaustion + 9.2. Timeouts + 10. IANA Considerations + Contributors + References + Normative References + Informative References + Authors' Addresses + +1. Introduction + + Media Over QUIC Transport (MOQT) is a protocol that is optimized for + the QUIC protocol [QUIC], either directly or via WebTransport + [WebTransport], for the dissemination of media. MOQT utilizes a + publish/subscribe workflow in which producers of media publish data + in response to subscription requests from a multiplicity of + endpoints. MOQT supports wide range of use-cases with different + resiliency and latency (live, interactive) needs without compromising + the scalability and cost effectiveness associated with content + delivery networks. + + MOQT is a generic protocol designed to work in concert with multiple + MoQ Streaming Formats. These MoQ Streaming Formats define how + content is encoded, packaged, and mapped to MOQT objects, along with + policies for discovery and subscription. + + * Section 2 describes the data model employed by MOQT. + + * Section 3 covers aspects of setting up a MOQT session. + + * Section 5 covers mechanisms for prioritizing subscriptions. + + * Section 6 covers behavior at the relay entities. + + * Section 7 covers how control messages are encoded on the wire. + + * Section 8 covers how data messages are encoded on the wire. + +1.1. Motivation + + The development of MOQT is driven by goals in a number of areas - + specifically latency, the robust feature set of QUIC and relay + support. + +1.1.1. Latency + + Latency is necessary to correct for variable network throughput. + Ideally live content is consumed at the same bitrate it is produced. + End-to-end latency would be fixed and only subject to encoding and + transmission delays. Unfortunately, networks have variable + throughput, primarily due to congestion. Attempting to deliver + content encoded at a higher bitrate than the network can support + causes queuing along the path from producer to consumer. The speed + at which a protocol can detect and respond to congestion determines + the overall latency. TCP-based protocols are simple but are slow to + detect congestion and suffer from head-of-line blocking. Protocols + utilizing UDP directly can avoid queuing, but the application is then + responsible for the complexity of fragmentation, congestion control, + retransmissions, receiver feedback, reassembly, and more. One goal + of MOQT is to achieve the best of both these worlds: leverage the + features of QUIC to create a simple yet flexible low latency protocol + that can rapidly detect and respond to congestion. + +1.1.2. Leveraging QUIC + + The parallel nature of QUIC streams can provide improvements in the + face of loss. A goal of MOQT is to design a streaming protocol to + leverage the transmission benefits afforded by parallel QUIC streams + as well exercising options for flexible loss recovery. + +1.1.3. Convergence + + Some live media architectures today have separate protocols for + ingest and distribution, for example RTMP and HTTP based HLS or DASH. + Switching protocols necessitates intermediary origins which re- + package the media content. While specialization can have its + benefits, there are efficiency gains to be had in not having to re- + package content. A goal of MOQT is to develop a single protocol + which can be used for transmission from contribution to distribution. + A related goal is the ability to support existing encoding and + packaging schemas, both for backwards compatibility and for + interoperability with the established content preparation ecosystem. + +1.1.4. Relays + + An integral feature of a protocol being successful is its ability to + deliver media at scale. Greatest scale is achieved when third-party + networks, independent of both the publisher and subscriber, can be + leveraged to relay the content. These relays must cache content for + distribution efficiency while simultaneously routing content and + deterministically responding to congestion in a multi-tenant network. + A goal of MOQT is to treat relays as first-class citizens of the + protocol and ensure that objects are structured such that information + necessary for distribution is available to relays while the media + content itself remains opaque and private. + +1.2. Terms and Definitions + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and + "OPTIONAL" in this document are to be interpreted as described in + BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all + capitals, as shown here. + + The following terms are used with the first letter capitalized. + + Client: The party initiating a Transport Session. + + Server: The party accepting an incoming Transport Session. + + Endpoint: A Client or Server. + + Peer: The other endpoint than the one being described + + Publisher: An endpoint that handles subscriptions by sending + requested Objects from the requested track. + + Subscriber: An endpoint that subscribes to and receives tracks. + + Original Publisher: The initial publisher of a given track. + + End Subscriber: A subscriber that initiates a subscription and does + not send the data on to other subscribers. + + Relay: An entity that is both a Publisher and a Subscriber, but not + the Original Publisher or End Subscriber. + + Upstream: In the direction of the Original Publisher + + Downstream: In the direction of the End Subscriber(s) + + Transport Session: A raw QUIC connection or a WebTransport session. + + Congestion: Packet loss and queuing caused by degraded or overloaded + networks. + + Group: A temporal sequence of objects. A group represents a join + point in a track. See (Section 2.3). + + Object: An object is an addressable unit whose payload is a sequence + of bytes. Objects form the base element in the MOQT data model. + See (Section 2.1). + + Track: A track is a collection of groups. See (Section 2.4). + +1.3. Notational Conventions + + This document uses the conventions detailed in ([RFC9000], + Section 1.3) when describing the binary encoding. + + As a quick reference, the following list provides a non normative + summary of the parts of RFC9000 field syntax that are used in this + specification. + + x (L): Indicates that x is L bits long + + x (i): Indicates that x holds an integer value using the variable- + length encoding as described in ([RFC9000], Section 16) + + x (..): Indicates that x can be any length including zero bits long. + Values in this format always end on a byte boundary. + + [x (L)]: Indicates that x is optional and has a length of L + + x (L) ...: Indicates that x is repeated zero or more times and that + each instance has a length of L + + This document extends the RFC9000 syntax and with the additional + field types: + + x (b): Indicates that x consists of a variable length integer + encoding as described in ([RFC9000], Section 16), followed by that + many bytes of binary data + + x (tuple): Indicates that x is a tuple, consisting of a variable + length integer encoded as described in ([RFC9000], Section 16), + followed by that many variable length tuple fields, each of which + are encoded as (b) above. + + To reduce unnecessary use of bandwidth, variable length integers + SHOULD be encoded using the least number of bytes possible to + represent the required value. + +2. Object Data Model + + MOQT has a hierarchical data model, comprised of tracks which contain + groups, and groups that contain objects. Inside of a group, the + objects can be organized into subgroups. + + To give an example of how an application might use this data model, + consider an application sending high and low resolution video using a + codec with temporal scalability. Each resolution is sent as a + separate track to allow the subscriber to pick the appropriate + resolution given the display environment and available bandwidth. + Each "group of pictures" in a video is sent as a group because the + first frame is needed to decode later frames. This allows the client + to join at the logical points where they can get the information to + start decoding the stream. The temporal layers are sent as separate + sub groups to allow the priority mechanism to favour the base layer + when there is not enough bandwidth to send both the base and + enhancement layers. Each frame of video on a given layer is sent as + a single object. + +2.1. Objects + + The basic data element of MOQT is an object. An object is an + addressable unit whose payload is a sequence of bytes. All objects + belong to a group, indicating ordering and potential dependencies. + Section 2.3 An object is uniquely identified by its track namespace, + track name, group ID, and object ID, and must be an identical + sequence of bytes regardless of how or where it is retrieved. An + Object can become unavailable, but its contents MUST NOT change over + time. + + Objects are comprised of two parts: metadata and a payload. The + metadata is never encrypted and is always visible to relays (see + Section 6). The payload portion may be encrypted, in which case it + is only visible to the Original Publisher and End Subscribers. The + Original Publisher is solely responsible for the content of the + object payload. This includes the underlying encoding, compression, + any end-to-end encryption, or authentication. A relay MUST NOT + combine, split, or otherwise modify object payloads. + + Objects within a group are ordered numerically by their Object ID. + +2.2. Subgroups + + A subgroup is a sequence of one or more objects from the same group + (Section 2.3) in ascending order by Object ID. Objects in a subgroup + have a dependency and priority relationship consistent with sharing a + stream and are sent on a single stream whenever possible. A Group is + delivered using at least as many streams as there are Subgroups, + typically with a one-to-one mapping between Subgroups and streams. + + When a Track's forwarding preference (see Section 8.1.1) is + "Datagram", Objects are not sent in Subgroups and the description in + the remainder of this section does not apply. + + Streams offer in-order reliable delivery and the ability to cancel + sending and retransmission of data. Furthermore, many + implementations offer the ability to control the relative priority of + streams, which allows control over the scheduling of sending data on + active streams. + + Every object within a Group belongs to exactly one Subgroup. + + Objects from two subgroups cannot be sent on the same stream. + Objects from the same Subgroup MUST NOT be sent on different streams, + unless one of the streams was reset prematurely, or upstream + conditions have forced objects from a Subgroup to be sent out of + Object ID order. + + Original publishers assign each Subgroup a Subgroup ID, and do so as + they see fit. The scope of a Subgroup ID is a Group, so Subgroups + from different Groups MAY share a Subgroup ID without implying any + relationship between them. In general, publishers assign objects to + subgroups in order to leverage the features of streams as described + above. + + An example strategy for using stream properties follows. If object B + is dependent on object A, then delivery of B can follow A, i.e. A and + B can be usefully delivered over a single stream. Furthermore, in + this example: + + * If an object is dependent on all previous objects in a Subgroup, + it is added to that Subgroup. + + * If an object is not dependent on all of the objects in a Subgroup, + it goes in a different Subgroup. + + * There are often many ways to compose Subgroups that meet these + criteria. Where possible, choose the composition that results in + the fewest Subgroups in a group to minimize the number of streams + used. + +2.3. Groups + + A group is a collection of objects and is a sub-unit of a track + (Section 2.4). Groups SHOULD be indendepently useful, so objects + within a group SHOULD NOT depend on objects in other groups. A group + provides a join point for subscriptions, so a subscriber that does + not want to receive the entire track can opt to receive only the + latest group(s). The publisher then selectively transmits objects + based on their group membership. Groups can contain any number of + objects. + + Within a track, the original publisher SHOULD produce Group IDs which + increase with time. Subscribers to tracks which do not follow this + requirement SHOULD NOT use range filters which span multiple groups + in FETCH or SUBSCRIBE. SUBSCRIBE and FETCH delivery use Group Order, + so a FETCH cannot deliver Groups out of order and a subscription + could have unexpected delivery order if Group IDs do not increase + with time. + +2.4. Track + + A track is a sequence of groups (Section 2.3). It is the entity + against which a subscriber issues a subscription request. A + subscriber can request to receive individual tracks starting at a + group boundary, including any new objects pushed by the publisher + while the track is active. + +2.4.1. Track Naming and Scopes + + In MOQT, every track is identified by a Full Track Name, consisting + of a Track Namespace and a Track Name. + + Track Namespace is an ordered N-tuple of bytes where N can be between + 1 and 32. The structured nature of Track Namespace allows relays and + applications to manipulate prefixes of a namespace. If an endpoint + receives a Track Namespace tuple with an N of 0 or more than 32, it + MUST close the session with a Protocol Violation. + + Track Name is a sequence of bytes that identifies an individual track + within the namespace. + + In this specification, both the Track Namespace tuple fields and the + Track Name are not constrained to a specific encoding. They carry a + sequence of bytes and comparison between two Track Namespace tuple + fields or Track Names is done by exact comparison of the bytes. + Specifications that use MoQ Transport may constrain the information + in these fields, for example by restricting them to UTF-8. Any + specification that does needs to specify the canonicalization into + the bytes in the Track Namespace or Track Name such that exact + comparison works. + +2.4.2. Scope + + A MOQT scope is a set of servers (as identified by their connection + URIs) for which the tuple of Track Name and Track Namespace are + guaranteed to be unique and identify a specific track. It is up to + the application using MOQT to define how broad or narrow the scope + is. An application that deals with connections between devices on a + local network may limit the scope to a single connection; by + contrast, an application that uses multiple CDNs to serve media may + require the scope to include all of those CDNs. + + Because the tuple of Track Namespace and Track Name are unique within + an MOQT scope, they can be used as a cache key. MOQT does not + provide any in-band content negotiation methods similar to the ones + defined by HTTP ([RFC9110], Section 10); if, at a given moment in + time, two tracks within the same scope contain different data, they + have to have different names and/or namespaces. + +3. Sessions + +3.1. Session establishment + + This document defines a protocol that can be used interchangeably + both over a QUIC connection directly [QUIC], and over WebTransport + [WebTransport]. Both provide streams and datagrams with similar + semantics (see [I-D.ietf-webtrans-overview], Section 4); thus, the + main difference lies in how the servers are identified and how the + connection is established. When using QUIC, datagrams MUST be + supported via the [QUIC-DATAGRAM] extension, which is already a + requirement for WebTransport over HTTP/3. + + There is no definition of the protocol over other transports, such as + TCP, and applications using MoQ might need to fallback to another + protocol when QUIC or WebTransport aren't available. + +3.1.1. WebTransport + + A MOQT server that is accessible via WebTransport can be identified + using an HTTPS URI ([RFC9110], Section 4.2.2). A MOQT session can be + established by sending an extended CONNECT request to the host and + the path indicated by the URI, as described in ([WebTransport], + Section 3). + +3.1.2. QUIC + + A MOQT server that is accessible via native QUIC can be identified by + a URI with a "moqt" scheme. The "moqt" URI scheme is defined as + follows, using definitions from [RFC3986]: + + moqt-URI = "moqt" "://" authority path-abempty [ "?" query ] + + The authority portion MUST NOT contain an empty host portion. The + moqt URI scheme supports the /.well-known/ path prefix defined in + [RFC8615]. + + This protocol does not specify any semantics on the path-abempty and + query portions of the URI. The contents of those are left up to the + application. + + The client can establish a connection to a MoQ server identified by a + given URI by setting up a QUIC connection to the host and port + identified by the authority section of the URI. The path-abempty and + query portions of the URI are communicated to the server using the + PATH parameter (Section 7.2.2.1) which is sent in the CLIENT_SETUP + message at the start of the session. The ALPN value [RFC7301] used + by the protocol is moq-00. + +3.1.3. Connection URL + + Each track MAY have one or more associated connection URLs specifying + network hosts through which a track may be accessed. The syntax of + the Connection URL and the associated connection setup procedures are + specific to the underlying transport protocol usage Section 3. + +3.2. Version and Extension Negotiation + + Endpoints use the exchange of Setup messages to negotiate the MOQT + version and any extensions to use. + + The client indicates the MOQT versions it supports in the + CLIENT_SETUP message (see Section 7.2). It also includes the union + of all Setup Parameters Section 7.2.2 required for a handshake by any + of those versions. + + Within any MOQT version, clients request the use of extensions by + adding Setup parameters corresponding to that extension. No + extensions are defined in this document. + + The server replies with a SERVER_SETUP message that indicates the + chosen version, includes all parameters required for a handshake in + that version, and parameters for every extension requested by the + client that it supports. + + New versions of MOQT MUST specify which existing extensions can be + used with that version. New extensions MUST specify the existing + versions with which they can be used. + + If a given parameter carries the same information in multiple + versions, but might have different optimal values in those versions, + there SHOULD be separate Setup parameters for that information in + each version. + +3.3. Session initialization + + The first stream opened is a client-initiated bidirectional control + stream where the endpoints exchange Setup messages (Section 7.2). + All messages defined in this draft except OBJECT and + OBJECT_WITH_LENGTH are sent on the control stream after the Setup + message. Control messages MUST NOT be sent on any other stream, and + a peer receiving a control message on a different stream closes the + session as a 'Protocol Violation'. Objects MUST NOT be sent on the + control stream, and a peer receiving an Object on the control stream + closes the session as a 'Protocol Violation'. + + This draft only specifies a single use of bidirectional streams. + Objects are sent on unidirectional streams. Because there are no + other uses of bidirectional streams, a peer MAY currently close the + session as a 'Protocol Violation' if it receives a second + bidirectional stream. + + The control stream MUST NOT be closed at the underlying transport + layer while the session is active. Doing so results in the session + being closed as a 'Protocol Violation'. + +3.4. Stream Cancellation + + Streams aside from the control stream MAY be canceled due to + congestion or other reasons by either the publisher or subscriber. + Early termination of a stream does not affect the MoQ application + state, and therefore has no effect on outstanding subscriptions. + +3.5. Termination + + The Transport Session can be terminated at any point. When native + QUIC is used, the session is closed using the CONNECTION_CLOSE frame + ([QUIC], Section 19.19). When WebTransport is used, the session is + closed using the CLOSE_WEBTRANSPORT_SESSION capsule ([WebTransport], + Section 5). + + The application MAY use any error message and SHOULD use a relevant + code, as defined below: + + +======+===========================+ + | Code | Reason | + +======+===========================+ + | 0x0 | No Error | + +------+---------------------------+ + | 0x1 | Internal Error | + +------+---------------------------+ + | 0x2 | Unauthorized | + +------+---------------------------+ + | 0x3 | Protocol Violation | + +------+---------------------------+ + | 0x4 | Duplicate Track Alias | + +------+---------------------------+ + | 0x5 | Parameter Length Mismatch | + +------+---------------------------+ + | 0x6 | Too Many Subscribes | + +------+---------------------------+ + | 0x10 | GOAWAY Timeout | + +------+---------------------------+ + | 0x11 | Control Message Timeout | + +------+---------------------------+ + | 0x12 | Data Stream Timeout | + +------+---------------------------+ + + Table 1 + + * No Error: The session is being terminated without an error. + + * Internal Error: An implementation specific error occurred. + + * Unauthorized: The endpoint breached an agreement, which MAY have + been pre-negotiated by the application. + + * Protocol Violation: The remote endpoint performed an action that + was disallowed by the specification. + + * Duplicate Track Alias: The endpoint attempted to use a Track Alias + that was already in use. + + * Too Many Subscribes: The session was closed because the subscriber + used a Subscribe ID equal or larger than the current Maximum + Subscribe ID. + + * GOAWAY Timeout: The session was closed because the peer took too + long to close the session in response to a GOAWAY (Section 7.3) + message. See session migration (Section 3.6). + + * Control Message Timeout: The session was closed because the peer + took too long to respond to a control message. + + * Data Stream Timeout: The session was closed because the peer took + too long to send data expected on an open Data Stream Section 8. + This includes fields of a stream header or an object header within + a data stream. If an endpoint times out waiting for a new object + header on an open subgroup stream, it MAY send a STOP_SENDING on + that stream, terminate the subscription, or close the session with + an error. + +3.6. Migration + + MOQT requires a long-lived and stateful session. However, a service + provider needs the ability to shutdown/restart a server without + waiting for all sessions to drain naturally, as that can take days + for long-form media. MOQT enables proactively draining sessions via + the GOAWAY message (Section 7.3). + + The server sends a GOAWAY message, signaling the client to establish + a new session and migrate any active subscriptions. The GOAWAY + message optionally contains a new URI for the new session, otherwise + the current URI is reused. The server SHOULD terminate the session + with 'GOAWAY Timeout' after a sufficient timeout if there are still + open subscriptions or fetches on a connection. + + When the server is a subscriber, it SHOULD send a GOAWAY message to + downstream subscribers prior to any UNSUBSCRIBE messages to upstream + publishers. + + After the client receives a GOAWAY, it's RECOMMENDED that the client + waits until there are no more active subscriptions before closing the + session with NO_ERROR. Ideally this is transparent to the + application using MOQT, which involves establishing a new session in + the background and migrating active subscriptions and announcements. + The client can choose to delay closing the session if it expects more + OBJECTs to be delivered. The server closes the session with a + 'GOAWAY Timeout' if the client doesn't close the session quickly + enough. + +4. Track Discovery and Retrieval + + Discovery of MoQT servers is always done out-of-band. Namespace + discovery can be done in the context of an established MoQT session. + + Given sufficient out of band information, it is valid for a + subscriber to send a SUBSCRIBE or FETCH message to a publisher + (including a relay) without any previous MoQT messages besides SETUP. + However, SUBSCRIBE_ANNOUNCES and ANNOUNCE messages provide an in-band + means of discovery of subscribers and publishers for a namespace. + + The syntax of these messages is described in Section 7. + +4.1. SUBSCRIBE_ANNOUNCES + + If the subscriber is aware of a namespace of interest, it can send + SUBSCRIBE_ANNOUNCES to publishers/relays it has established a session + with. The recipient of this message will send any relevant ANNOUNCE + or UNANNOUNCE messages for that namespace, or subset of that + namespace. + + A publisher MUST send exactly one SUBSCRIBE_ANNOUNCES_OK or + SUBSCRIBE_ANNOUNCES_ERROR in response to a SUBSCRIBE_ANNOUNCES. The + subscriber SHOULD close the session with a protocol error if it + detects receiving more than one. + + The receiver of a SUBSCRIBE_ANNOUNCES_OK or SUBSCRIBE_ANNOUNCES_ERROR + ought to forward the result to the application, so that it can make + decisions about further publishers to contact. + + An UNSUBSCRIBE_ANNOUNCES withdraws a previous SUBSCRIBE_ANNOUNCES. + It does not prohibit the receiver (publisher) from sending further + ANNOUNCE messages. + +4.2. ANNOUNCE + + A publisher MAY send ANNOUNCE messages to any subscriber. An + ANNOUNCE indicates to the subscriber where to route a SUBSCRIBE or + FETCH for that namespace. A subscriber MAY send SUBSCRIBE or FETCH + for a namespace without having received an ANNOUNCE for it. + + If a publisher is authoritative for a given namespace, or is a relay + that has received an authorized ANNOUNCE for that namespace from an + upstream publisher, it MUST send an ANNOUNCE to any subscriber that + has subscribed to ANNOUNCE for that namespace, or a subset of that + namespace. A publisher MAY send the ANNOUNCE to any other + subscriber. + + An endpoint SHOULD NOT, however, send an ANNOUNCE advertising a + namespace that exactly matches a namespace for which the peer sent an + earlier ANNOUNCE (i.e. an ANNOUNCE ought not to be echoed back to its + sender). + + The receiver of an ANNOUNCE_OK or ANNOUNCE_ERROR SHOULD report this + to the application to inform the search for additional subscribers + for a namespace, or abandoning the attempt to publish under this + namespace. This might be especially useful in upload or chat + applications. A subscriber MUST send exactly one ANNOUNCE_OK or + ANNOUNCE_ERROR in response to an ANNOUNCE. The publisher SHOULD + close the session with a protocol error if it receives more than one. + + An UNANNOUNCE message withdraws a previous ANNOUNCE, although it is + not a protocol error for the subscriber to send a SUBSCRIBE or FETCH + message after receiving an UNANNOUNCE. + + A subscriber can send ANNOUNCE_CANCEL to revoke acceptance of an + ANNOUNCE, for example due to expiration of authorization credentials. + The message enables the publisher to ANNOUNCE again with refreshed + authorization, or discard associated state. After receiving an + ANNOUNCE_CANCEL, the publisher does not send UNANNOUNCE. + + While ANNOUNCE does provide hints on where to route a SUBSCRIBE or + FETCH, it is not a full-fledged routing protocol and does not protect + against loops and other phenomena. In particular, ANNOUNCE SHOULD + NOT be used to find paths through richly connected networks of + relays. + +4.3. SUBSCRIBE/FETCH + + The central interaction with a publisher is to send SUBSCRIBE and/or + FETCH for a particular track. The subscriber expects to receive a + SUBSCRIBE_OK/FETCH_OK and objects from the track. + + A subscriber MAY send a SUBSCRIBE or FETCH for a track to any + publisher. If it has accepted an ANNOUNCE with a namespace that + exactly matches the namespace for that track, it SHOULD only request + it from the senders of those ANNOUNCE messages. + + A publisher MUST send exactly one SUBSCRIBE_OK or SUBSCRIBE_ERROR in + response to a SUBSCRIBE. It MUST send exactly one FETCH_OK or + FETCH_ERROR in response to a FETCH. The subscriber SHOULD close the + session with a protocol error if it receives more than one. + + A subscriber keeps SUBSCRIBE state until it sends UNSUBSCRIBE, or + after receipt of a SUBSCRIBE_DONE or SUBSCRIBE_ERROR. Note that + SUBSCRIBE_DONE does not usually indicate that state can immediately + be destroyed, see Section 7.19. + + A subscriber keeps FETCH state until it sends FETCH_CANCEL, receives + FETCH_ERROR, or receives a FIN or RESET_STREAM for the FETCH data + stream. If the data stream is already open, it MAY send STOP_SENDING + for the data stream along with FETCH_CANCEL, but MUST send + FETCH_CANCEL. + + The Publisher can destroy subscription or fetch state as soon as it + has received UNSUBSCRIBE or FETCH_CANCEL, respectively. It MUST + reset any open streams associated with the SUBSCRIBE or FETCH. It + can also destroy state after closing the FETCH data stream. + + The publisher can immediately delete SUBSCRIBE state after sending + SUBSCRIBE_DONE, but MUST NOT send it until it has closed all related + streams. It can destroy all FETCH state after closing the data + stream. + + A SUBSCRIBE_ERROR or FETCH_ERROR indicates no objects will be + delivered, and both endpoints can immediately destroy relevant state. + Objects MUST NOT be sent for requests that end with an error. + +5. Priorities + + MoQ priorities allow a subscriber and original publisher to influence + the transmission order of Objects within a session in the presence of + congestion. + +5.1. Definitions + + MoQT maintains priorities between different _schedulable objects_. A + schedulable object in MoQT is either: + + 1. An object that belongs to a subgroup where that object would be + the next object to be sent in that subgroup. + + 2. An object that belongs to a track with delivery preference + Datagram. + + Since a single subgroup or datagram has a single publisher priority, + it can be useful to conceptualize this process as scheduling + subgroups or datagrams instead of individual objects on them. + + A _priority number_ is an unsigned integer with a value between 0 and + 255. A lower priority number indicates higher priority; the highest + priority is 0. + + _Subscriber Priority_ is a priority number associated with an + individual subscription. It is specified in the SUBSCRIBE message, + and can be updated via SUBSCRIBE_UPDATE message. The subscriber + priority of an individual schedulable object is the subscriber + priority of the subscription that caused that object to be sent. + When subscriber priority is changed, a best effort SHOULD be made to + apply the change to all objects that have not been sent, but it is + implementation dependent what happens to objects that have already + been received and possibly scheduled. + + _Publisher Priority_ is a priority number associated with an + individual schedulable object. It is specified in the header of the + respective subgroup or datagram, and is the same for all objects in a + single subgroup. + + _Group Order_ is a property of an invidual subscription. It can be + either 'Ascending' (groups with lower group ID are sent first), or + 'Descending' (groups with higher group ID are sent first). The + publisher communicates its group order in the SUBSCRIBE_OK message; + the subscriber can override it in its SUBSCRIBE message. The group + order of an existing subscription cannot be changed. + +5.2. Scheduling Algorithm + + When an MoQT publisher has multiple schedulable objects it can choose + between, the objects SHOULD be selected as follows: + + 1. If two objects have a different subscriber priority associated + with them, the one with *the highest subscriber priority* is sent + first. + + 2. If two objects have the same subscriber priority, but a different + publisher priority, the one with *the highest publisher priority* + is sent first. + + 3. If two objects have the same subscriber and publisher priority, + but belong to two different groups of the same track, *the group + order* of the associated subscription is used to decide the one + that is sent first. + + 4. If two objects belong to the same group of the same track, the + one with *the lowest Subgroup ID* (for tracks with delivery + preference Subgroup), or *the lowest Object ID* (for tracks with + delivery preference Datagram) is sent first. + + This algorithm does not provide a well-defined ordering for objects + that belong to different subscriptions, but have the same subscriber + and publisher priority. The ordering in those cases is + implementation-defined, though the expectation is that all + subscriptions will be able to send some data. + + Given the critical nature of control messages and their relatively + small size, the control stream SHOULD be prioritized higher than all + subscribed Objects. + +5.3. Considerations for Setting Priorities + + Relays SHOULD respect the subscriber and original publisher's + priorities. Relays SHOULD NOT directly use Subscriber Priority or + Group Order from incoming subscriptions for upstream subscriptions. + Relays use of Subscriber Priority for upstream subscriptions can be + based on factors specific to it, such as the popularity of the + content or policy, or relays can specify the same value for all + upstream subscriptions. + + MoQ Sessions can span multiple namespaces, and priorities might not + be coordinated across namespaces. The subscriber's priority is + considered first, so there is a mechanism for a subscriber to fix + incompatibilities between different namespaces prioritization + schemes. Additionally, it is anticipated that when multiple + namespaces are present within a session, the namespaces could be + coordinating, possibly part of the same application. In cases when + pooling among namespaces is expected to cause issues, multiple MoQ + sessions, either within a single connection or on multiple + connections can be used. + + Implementations that have a default priority SHOULD set it to a value + in the middle of the range (eg: 128) to allow non-default priorities + to be set either higher or lower. + +6. Relays + + Relays are leveraged to enable distribution scale in the MoQ + architecture. Relays can be used to form an overlay delivery + network, similar in functionality to Content Delivery Networks + (CDNs). Additionally, relays serve as policy enforcement points by + validating subscribe and publish requests at the edge of a network. + + Relays are endpoints, which means they terminate Transport Sessions + in order to have visibility of MoQ Object metadata. + + Relays MAY cache Objects, but are not required to. + +6.1. Subscriber Interactions + + Subscribers subscribe to tracks by sending a SUBSCRIBE (Section 7.4) + control message for each track of interest. Relays MUST ensure + subscribers are authorized to access the content associated with the + track. The authorization information can be part of subscription + request itself or part of the encompassing session. The specifics of + how a relay authorizes a user are outside the scope of this + specification. + + The relay will have to send an upstream SUBSCRIBE and/or FETCH if it + does not have all the objects in the FETCH, or is not currently + subscribed to the full requested range. In this case, it SHOULD + withhold sending its own SUBSCRIBE_OK until receiving one from + upstream. It MUST withhold FETCH_OK until receiving one from + upstream. + + For successful subscriptions, the publisher maintains a list of + subscribers for each track. Each new OBJECT belonging to the track + within the subscription range is forwarded to each active subscriber, + dependent on the congestion response. + + A caching relay saves Objects to its cache identified by the Object's + Full Track Name, Group ID and Object ID. Relays MUST be able to + process objects for the same Full Track Name from multiple publishers + and forward objects to active matching subscriptions. If multiple + objects are received with the same Full Track Name, Group ID and + Object ID, Relays MAY ignore subsequently received Objects or MAY use + them to update the cache. Implementations that update the cache need + to protect against cache poisoning. + + A relay MUST NOT reorder or drop objects received on a multi-object + stream when forwarding to subscribers, unless it has application + specific information. + + Relays MAY aggregate authorized subscriptions for a given track when + multiple subscribers request the same track. Subscription + aggregation allows relays to make only a single upstream subscription + for the track. The published content received from the upstream + subscription request is cached and shared among the pending + subscribers. + +6.1.1. Graceful Subscriber Relay Switchover + + This section describes behavior a subscriber MAY implement to allow + for a better user experience when a relay sends a GOAWAY. + + When a subscriber receives the GOAWAY message, it starts the process + of connecting to a new relay and sending the SUBSCRIBE requests for + all active subscriptions to the new relay. The new relay will send a + response to the subscribes and if they are successful, the + subscriptions to the old relay can be stopped with an UNSUBSCRIBE. + +6.2. Publisher Interactions + + Publishing through the relay starts with publisher sending ANNOUNCE + control message with a Track Namespace (Section 2.4). The ANNOUNCE + enables the relay to know which publisher to forward a SUBSCRIBE to. + + Relays MUST verify that publishers are authorized to publish the + content associated with the set of tracks whose Track Namespace + matches the announced namespace. Where the authorization and + identification of the publisher occurs depends on the way the relay + is managed and is application specific. + + A Relay can receive announcements from multiple publishers for the + same Track Namespace and it SHOULD respond with the same response to + each of the publishers, as though it was responding to an ANNOUNCE + from a single publisher for a given track namespace. + + When a publisher wants to stop new subscriptions for an announced + namespace it sends an UNANNOUNCE. A subscriber indicates it will no + longer route subscriptions for a namespace it previously responded + ANNOUNCE_OK to by sending an ANNOUNCE_CANCEL. + + A relay manages sessions from multiple publishers and subscribers, + connecting them based on the track namespace. This MUST use an exact + match on track namespace unless otherwise negotiated by the + application. For example, a SUBSCRIBE namespace=foobar message will + be forwarded to the session that sent ANNOUNCE namespace=foobar. + + When a relay receives an incoming SUBSCRIBE request that triggers an + upstream subscription, it SHOULD send a SUBSCRIBE request to each + publisher that has announced the subscription's namespace, unless it + already has an active subscription for the Objects requested by the + incoming SUBSCRIBE request from all available publishers. + + When a relay receives an incoming ANNOUNCE for a given namespace, for + each active upstream subscription that matches that namespace, it + SHOULD send a SUBSCRIBE to the publisher that sent the ANNOUNCE. + + OBJECT message headers carry a short hop-by-hop Track Alias that maps + to the Full Track Name (see Section 7.15). Relays use the Track + Alias of an incoming OBJECT message to identify its track and find + the active subscribers for that track. Relays MUST forward OBJECT + messages to matching subscribers in accordance to each subscription's + priority, group order, and delivery timeout. + +6.2.1. Graceful Publisher Network Switchover + + This section describes behavior that a publisher MAY choose to + implement to allow for a better users experience when switching + between networks, such as WiFi to Cellular or vice versa. + + If the original publisher detects it is likely to need to switch + networks, for example because the WiFi signal is getting weaker, and + it does not have QUIC connection migration available, it establishes + a new session over the new interface and sends an ANNOUCE. The relay + will forward matching subscribes and the publisher publishes objects + on both sessions. Once the subscriptions have migrated over to + session on the new network, the publisher can stop publishing objects + on the old network. The relay will drop duplicate objects received + on both subscriptions. Ideally, the subscriptions downstream from + the relay do no observe this change, and keep receiving the objects + on the same subscription. + +6.2.2. Graceful Publisher Relay Switchover + + This section describes behavior that a publisher MAY choose to + implement to allow for a better user experience when a relay sends + them a GOAWAY. + + When a publisher receives a GOAWAY, it starts the process of + connecting to a new relay and sends announces, but it does not + immediately stop publishing objects to the old relay. The new relay + will send subscribes and the publisher can start sending new objects + to the new relay instead of the old relay. Once objects are going to + the new relay, the announcement and subscription to the old relay can + be stopped. + +6.3. Relay Object Handling + + MOQT encodes the delivery information for a stream via OBJECT headers + (Section 8.1). A relay MUST NOT modify Object properties when + forwarding. + + A relay MUST treat the object payload as opaque. A relay MUST NOT + combine, split, or otherwise modify object payloads. A relay SHOULD + prioritize sending Objects based on Section 5. + + A publisher SHOULD begin sending incomplete objects when available to + avoid incurring additional latency. + + A relay that reads from one stream and writes to another in order can + introduce head-of-line blocking. Packet loss will cause stream data + to be buffered in the library, awaiting in-order delivery, which + could increase latency over additional hops. To mitigate this, a + relay MAY read and write stream data out of order subject to flow + control limits. See section 2.2 in [QUIC]. + +7. Control Messages + + MOQT uses a single bidirectional stream to exchange control messages, + as defined in Section 3.3. Every single message on the control + stream is formatted as follows: + + MOQT Control Message { + Message Type (i), + Message Length (i), + Message Payload (..), + } + + Figure 1: MOQT Message + + +======+=========================================+ + | ID | Messages | + +======+=========================================+ + | 0x2 | SUBSCRIBE_UPDATE (Section 7.5) | + +------+-----------------------------------------+ + | 0x3 | SUBSCRIBE (Section 7.4) | + +------+-----------------------------------------+ + | 0x4 | SUBSCRIBE_OK (Section 7.15) | + +------+-----------------------------------------+ + | 0x5 | SUBSCRIBE_ERROR (Section 7.16) | + +------+-----------------------------------------+ + | 0x6 | ANNOUNCE (Section 7.22) | + +------+-----------------------------------------+ + | 0x7 | ANNOUNCE_OK (Section 7.9) | + +------+-----------------------------------------+ + | 0x8 | ANNOUNCE_ERROR (Section 7.10) | + +------+-----------------------------------------+ + | 0x9 | UNANNOUNCE (Section 7.23) | + +------+-----------------------------------------+ + | 0xA | UNSUBSCRIBE (Section 7.6) | + +------+-----------------------------------------+ + | 0xB | SUBSCRIBE_DONE (Section 7.19) | + +------+-----------------------------------------+ + | 0xC | ANNOUNCE_CANCEL (Section 7.11) | + +------+-----------------------------------------+ + | 0xD | TRACK_STATUS_REQUEST (Section 7.12) | + +------+-----------------------------------------+ + | 0xE | TRACK_STATUS (Section 7.24) | + +------+-----------------------------------------+ + | 0x10 | GOAWAY (Section 7.3) | + +------+-----------------------------------------+ + | 0x11 | SUBSCRIBE_ANNOUNCES (Section 7.13) | + +------+-----------------------------------------+ + | 0x12 | SUBSCRIBE_ANNOUNCES_OK (Section 7.25) | + +------+-----------------------------------------+ + | 0x13 | SUBSCRIBE_ANNOUNCES_ERROR (Section 7.26 | + +------+-----------------------------------------+ + | 0x14 | UNSUBSCRIBE_ANNOUNCES (Section 7.14) | + +------+-----------------------------------------+ + | 0x15 | MAX_SUBSCRIBE_ID (Section 7.20) | + +------+-----------------------------------------+ + | 0x1A | SUBSCRIBES_BLOCKED (Section 7.21) | + +------+-----------------------------------------+ + | 0x16 | FETCH (Section 7.7) | + +------+-----------------------------------------+ + | 0x17 | FETCH_CANCEL (Section 7.8) | + +------+-----------------------------------------+ + | 0x18 | FETCH_OK (Section 7.17) | + +------+-----------------------------------------+ + | 0x19 | FETCH_ERROR (Section 7.18) | + +------+-----------------------------------------+ + | 0x40 | CLIENT_SETUP (Section 7.2) | + +------+-----------------------------------------+ + | 0x41 | SERVER_SETUP (Section 7.2) | + +------+-----------------------------------------+ + + Table 2 + + An endpoint that receives an unknown message type MUST close the + session. Control messages have a length to make parsing easier, but + no control messages are intended to be ignored. If the length does + not match the length of the message content, the receiver MUST close + the session. + +7.1. Parameters + + Some messages include a Parameters field that encode optional message + elements. They contain a type, length, and value. + + Senders MUST NOT repeat the same parameter type in a message. + Receivers SHOULD check that there are no duplicate parameters and + close the session as a 'Protocol Violation' if found. + + Receivers ignore unrecognized parameters. + + The format of Parameters is as follows: + + Parameter { + Parameter Type (i), + Parameter Length (i), + Parameter Value (..), + } + + Figure 2: MOQT Parameter + + Parameter Type is an integer that indicates the semantic meaning of + the parameter. Setup message parameters use a namespace that is + constant across all MoQ Transport versions. All other messages use a + version-specific namespace. For example, the integer '1' can refer + to different parameters for Setup messages and for all other message + types. + + SETUP message parameter types are defined in Section 7.2.2. Version- + specific parameter types are defined in Section 7.1.1. + + The Parameter Length field of the String Parameter encodes the length + of the Parameter Value field in bytes. + + Each parameter description will indicate the data type in the + Parameter Value field. If a receiver understands a parameter type, + and the parameter length implied by that type does not match the + Parameter Length field, the receiver MUST terminate the session with + error code 'Parameter Length Mismatch'. + +7.1.1. Version Specific Parameters + + Each version-specific parameter definition indicates the message + types in which it can appear. If it appears in some other type of + message, it MUST be ignored. Note that since Setup parameters use a + separate namespace, it is impossible for these parameters to appear + in Setup messages. + +7.1.1.1. AUTHORIZATION INFO + + AUTHORIZATION INFO parameter (Parameter Type 0x02) identifies a + track's authorization information in a SUBSCRIBE, + SUBSCRIBE_ANNOUNCES, ANNOUNCE or FETCH message. This parameter is + populated for cases where the authorization is required at the track + level. The value is an ASCII string. + +7.1.1.2. DELIVERY TIMEOUT Parameter + + The DELIVERY TIMEOUT parameter (Parameter Type 0x03) MAY appear in a + SUBSCRIBE, SUBSCRIBE_OK, or a SUBSCRIBE_UDPATE message. It is the + duration in milliseconds the relay SHOULD continue to attempt + forwarding Objects after they have been received. The start time for + the timeout is based on when the beginning of the Object is received, + and does not depend upon the forwarding preference. There is no + explicit signal that an Object was not sent because the delivery + timeout was exceeded. + + If both the subscriber and publisher specify the parameter, they use + the min of the two values for the subscription. The publisher SHOULD + always specify the value received from an upstream subscription when + there is one, and nothing otherwise. If an earlier Object arrives + later than subsequent Objects, relays can consider the receipt time + as that of the next later Object, with the assumption that the + Object's data was reordered. + + If neither the subscriber or publisher specify DELIVERY TIMEOUT, all + Objects in the track matching the subscription filter are delivered + as indicated by their Group Order and Priority. If a subscriber + exceeds the publisher's resource limits by failing to consume objects + at a sufficient rate, the publisher MAY terminate the subscription + with error 'Too Far Behind'. + + If an object in a subgroup exceeds the delivery timeout, the + publisher MUST reset the underlying transport stream (see + Section 8.4.2). + + When sent by a subscriber, this parameter is intended to be specific + to a subscription, so it SHOULD NOT be forwarded upstream by a relay + that intends to serve multiple subscriptions for the same track. + + Publishers SHOULD consider whether the entire Object is likely to be + delivered before sending any data for that Object, taking into + account priorities, congestion control, and any other relevant + information. + +7.1.1.3. MAX CACHE DURATION Parameter + + MAX_CACHE_DURATION (Parameter Type 0x04): An integer expressing a + number of milliseconds. If present, the relay MUST NOT start + forwarding any individual Object received through this subscription + after the specified number of milliseconds has elapsed since the + beginning of the Object was received. This means Objects earlier in + a multi-object stream will expire earlier than Objects later in the + stream. Once Objects have expired, their state becomes unknown, and + a relay that handles a subscription that includes those Objects re- + requests them. + +7.2. CLIENT_SETUP and SERVER_SETUP + + The CLIENT_SETUP and SERVER_SETUP messages are the first messages + exchanged by the client and the server; they allow the endpoints to + establish the mutually supported version and agree on the initial + configuration before any objects are exchanged. It is a sequence of + key-value pairs called Setup parameters; the semantics and format of + which can vary based on whether the client or server is sending. To + ensure future extensibility of MOQT, endpoints MUST ignore unknown + setup parameters. TODO: describe GREASE for those. + + The wire format of the Setup messages are as follows: + + CLIENT_SETUP Message { + Type (i) = 0x40, + Length (i), + Number of Supported Versions (i), + Supported Version (i) ..., + Number of Parameters (i) ..., + Setup Parameters (..) ..., + } + + SERVER_SETUP Message { + Type (i) = 0x41, + Length (i), + Selected Version (i), + Number of Parameters (i) ..., + Setup Parameters (..) ..., + } + + Figure 3: MOQT Setup Messages + + The available versions and Setup parameters are detailed in the next + sections. + +7.2.1. Versions + + MoQ Transport versions are a 32-bit unsigned integer, encoded as a + varint. This version of the specification is identified by the + number 0x00000001. Versions with the most significant 16 bits of the + version number cleared are reserved for use in future IETF consensus + documents. + + The client offers the list of the protocol versions it supports; the + server MUST reply with one of the versions offered by the client. If + the server does not support any of the versions offered by the + client, or the client receives a server version that it did not + offer, the corresponding peer MUST close the session. + + [[RFC editor: please remove the remainder of this section before + publication.]] + + The version number for the final version of this specification + (0x00000001), is reserved for the version of the protocol that is + published as an RFC. Version numbers used to identify IETF drafts + are created by adding the draft number to 0xff000000. For example, + draft-ietf-moq-transport-13 would be identified as 0xff00000D. + +7.2.2. Setup Parameters + +7.2.2.1. PATH + + The PATH parameter (Parameter Type 0x01) allows the client to specify + the path of the MoQ URI when using native QUIC ([QUIC]). It MUST NOT + be used by the server, or when WebTransport is used. If the peer + receives a PATH parameter from the server, or when WebTransport is + used, it MUST close the connection. It follows the URI formatting + rules [RFC3986]. + + When connecting to a server using a URI with the "moqt" scheme, the + client MUST set the PATH parameter to the path-abempty portion of the + URI; if query is present, the client MUST concatenate ?, followed by + the query portion of the URI to the parameter. + +7.2.2.2. MAX_SUBSCRIBE_ID + + The MAX_SUBSCRIBE_ID parameter (Parameter Type 0x02) communicates an + initial value for the Maximum Subscribe ID to the receiving + subscriber. The default value is 0, so if not specified, the peer + MUST NOT create subscriptions. + +7.3. GOAWAY + + An endpoint sends a GOAWAY message to inform the peer it intends to + close the session soon. Servers can use GOAWAY to initiate session + migration (Section 3.6) with an optional URI. + + The GOAWAY message does not impact subscription state. A subscriber + SHOULD individually UNSUBSCRIBE for each existing subscription, while + a publisher MAY reject new requests while in the draining state. + + Upon receiving a GOAWAY, an endpoint SHOULD NOT initiate new requests + to the peer including SUBSCRIBE, FETCH, ANNOUNCE and + SUBSCRIBE_ANNOUNCE. + + The endpoint MUST terminate the session with a Protocol Violation + (Section 3.5) if it receives multiple GOAWAY messages. + + GOAWAY Message { + Type (i) = 0x10, + Length (i), + New Session URI Length (i), + New Session URI (..), + } + + Figure 4: MOQT GOAWAY Message + + * New Session URI: When received by a client, indicates where the + client can connect to continue this session. The client MUST use + this URI for the new session if provided. If the URI is zero + bytes long, the client can reuse the current URI is reused + instead. The new session URI SHOULD use the same scheme as the + current URL to ensure compatibility. + + If a server receives a GOAWAY with a non-zero New Session URI + Length it MUST terminate the session with a Protocol Violation. + +7.4. SUBSCRIBE + + A subscription causes the publisher to send newly published objects + for a track. A subscriber MUST NOT make multiple active + subscriptions for a track within a single session and publishers + SHOULD treat this as a protocol violation. + + *Filter Types* + + The subscriber specifies a filter on the subscription to allow the + publisher to identify which objects need to be delivered. + + There are 3 types of filters: + + Latest Object (0x2): Specifies an open-ended subscription beginning + from the current object of the current group. If no content has been + delivered yet, the subscription starts with the first published or + received group. + + AbsoluteStart (0x3): Specifies an open-ended subscription beginning + from the object identified in the StartGroup and StartObject fields. + If the StartGroup is prior to the current group, the subscription + starts at the beginning of the current object like the 'Latest + Object' filter. + + AbsoluteRange (0x4): Specifies a closed subscription starting at + StartObject in StartGroup and ending at the largest object in + EndGroup. The start and end of the range are inclusive. EndGroup + MUST specify the same or a later group than StartGroup. If the + StartGroup is prior to the current group, the subscription starts at + the beginning of the current object like the 'Latest Object' filter. + + A filter type other than the above MUST be treated as error. + + If a subscriber wants to subscribe to Objects both before and after + the Latest Object, it can send a SUBSCRIBE for the Latest Object + followed by a FETCH. Depending upon the application, one might want + to send both messages at the same time or wait for the first to + return before sending the second. + + The format of SUBSCRIBE is as follows: + + SUBSCRIBE Message { + Type (i) = 0x3, + Length (i), + Subscribe ID (i), + Track Alias (i), + Track Namespace (tuple), + Track Name Length (i), + Track Name (..), + Subscriber Priority (8), + Group Order (8), + Filter Type (i), + [StartGroup (i), + StartObject (i)], + [EndGroup (i)], + Number of Parameters (i), + Subscribe Parameters (..) ... + } + + Figure 5: MOQT SUBSCRIBE Message + + * Subscribe ID: The subscriber specified identifier used to manage a + subscription. Subscribe ID is a variable length integer that MUST + be unique and monotonically increasing within a session and MUST + be less than the session's Maximum Subscribe ID. + + * Track Alias: A session specific identifier for the track. + Messages that reference a track, such as OBJECT (Section 8.1), + reference this Track Alias instead of the Track Name and Track + Namespace to reduce overhead. If the Track Alias is already being + used for a different track, the publisher MUST close the session + with a Duplicate Track Alias error (Section 3.5). + + * Track Namespace: Identifies the namespace of the track as defined + in (Section 2.4.1). + + * Track Name: Identifies the track name as defined in + (Section 2.4.1). + + * Subscriber Priority: Specifies the priority of a subscription + relative to other subscriptions in the same session. Lower + numbers get higher priority. See Section 5. + + * Group Order: Allows the subscriber to request Objects be delivered + in Ascending (0x1) or Descending (0x2) order by group. See + Section 5. A value of 0x0 indicates the original publisher's + Group Order SHOULD be used. Values larger than 0x2 are a protocol + error. + + * Filter Type: Identifies the type of filter, which also indicates + whether the StartGroup/StartObject and EndGroup/EndObject fields + will be present. + + * StartGroup: The start Group ID. Only present for "AbsoluteStart" + and "AbsoluteRange" filter types. + + * StartObject: The start Object ID. Only present for + "AbsoluteStart" and "AbsoluteRange" filter types. + + * EndGroup: The end Group ID, inclusive. Only present for the + "AbsoluteRange" filter type. + + * Subscribe Parameters: The parameters are defined in Section 7.1.1. + + On successful subscription, the publisher MUST reply with a + SUBSCRIBE_OK, allowing the subscriber to determine the start group/ + object when not explicitly specified and the publisher SHOULD start + delivering objects. + + If a publisher cannot satisfy the requested start or end or if the + end has already been published it SHOULD send a SUBSCRIBE_ERROR with + code 'Invalid Range'. A publisher MUST NOT send objects from outside + the requested start and end. + +7.5. SUBSCRIBE_UPDATE + + A subscriber issues a SUBSCRIBE_UPDATE to a publisher to request a + change to an existing subscription. Subscriptions can only become + more narrow, not wider, because an attempt to widen a subscription + could fail. If Objects before the start or after the end of the + current subscription are needed, a fetch might be able to retrieve + objects before the start. The start Object MUST NOT decrease and + when it increases, there is no guarantee that a publisher will not + have already sent Objects before the new start Object. The end Group + MUST NOT increase and when it decreases, there is no guarantee that a + publisher will not have already sent Objects after the new end + Object. A publisher SHOULD close the Session as a 'Protocol + Violation' if the SUBSCRIBE_UPDATE violates either rule or if the + subscriber specifies a Subscribe ID that has not existed within the + Session. + + There is no control message in response to a SUBSCRIBE_UPDATE, + because it is expected that it will always succeed and the worst + outcome is that it is not processed promptly and some extra objects + from the existing subscription are delivered. + + Unlike a new subscription, SUBSCRIBE_UPDATE can not cause an Object + to be delivered multiple times. Like SUBSCRIBE, EndGroup MUST + specify the same or a later object than StartGroup and StartObject. + + The format of SUBSCRIBE_UPDATE is as follows: + + SUBSCRIBE_UPDATE Message { + Type (i) = 0x2, + Length (i), + Subscribe ID (i), + StartGroup (i), + StartObject (i), + EndGroup (i), + Subscriber Priority (8), + Number of Parameters (i), + Subscribe Parameters (..) ... + } + + Figure 6: MOQT SUBSCRIBE_UPDATE Message + + * Subscribe ID: The subscription identifier that is unique within + the session. This MUST match an existing Subscribe ID. + + * StartGroup: The start Group ID. + + * StartObject: The start Object ID. + + * EndGroup: The end Group ID, plus 1. A value of 0 means the + subscription is open-ended. + + * Subscriber Priority: Specifies the priority of a subscription + relative to other subscriptions in the same session. Lower + numbers get higher priority. See Section 5. + + * Subscribe Parameters: The parameters are defined in Section 7.1.1. + +7.6. UNSUBSCRIBE + + A subscriber issues a UNSUBSCRIBE message to a publisher indicating + it is no longer interested in receiving media for the specified track + and requesting that the publisher stop sending Objects as soon as + possible. + + The format of UNSUBSCRIBE is as follows: + + UNSUBSCRIBE Message { + Type (i) = 0xA, + Length (i), + Subscribe ID (i) + } + + Figure 7: MOQT UNSUBSCRIBE Message + + * Subscribe ID: Subscription Identifier as defined in Section 7.4. + +7.7. FETCH + + A subscriber issues a FETCH to a publisher to request a range of + already published objects within a track. The publisher responding + to a FETCH is responsible for retrieving all available Objects. If + there are gaps between Objects, the publisher omits them from the + fetch response. All omitted objects have status Object Does Not + Exist. + + *Fetch Types* + + There are two types of Fetch messages: + + Standalone Fetch (0x1) : A Fetch of Objects performed independently + of any Subscribe. + + Joining Fetch (0x2) : A Fetch joined together with a Subscribe by + specifying the Subscribe ID of an active subscription. A publisher + receiving a Joining Fetch uses properties of the associated Subscribe + to determine the Track Namespace, Track, StartGroup, StartObject, + EndGroup, and EndObject such that it is contiguous with the + associated Subscribe. The Joining Fetch begins the Preceding Group + Offset prior to the associated subscription. + + A Subscriber can use a Joining Fetch to, for example, fill a playback + buffer with a certain number of groups prior to the live edge of a + track. + + A Joining Fetch is only permitted when the associated Subscribe has + the Filter Type Latest Object. + + A Fetch Type other than 0x1 or 0x2 MUST be treated as an error. + + A publisher responds to a FETCH request with either a FETCH_OK or a + FETCH_ERROR message. If it responds with FETCH_OK, the publisher + creates a new unidirectional stream that is used to send the Objects. + A relay MAY start sending objects immediately in response to a FETCH, + even if sending the FETCH_OK takes longer because it requires going + upstream to populate the latest object. + + The Object Forwarding Preference does not apply to fetches. + + Fetch specifies an inclusive range of Objects starting at StartObject + in StartGroup and ending at EndObject in EndGroup. EndGroup and + EndObject MUST specify the same or a later object than StartGroup and + StartObject. + + The format of FETCH is as follows: + + FETCH Message { + Type (i) = 0x16, + Length (i), + Subscribe ID (i), + Subscriber Priority (8), + Group Order (8), + Fetch Type (i), + [Track Namespace (tuple), + Track Name Length (i), + Track Name (..), + StartGroup (i), + StartObject (i), + EndGroup (i), + EndObject (i),] + [Joining Subscribe ID (i), + Preceding Group Offset (i),] + Number of Parameters (i), + Parameters (..) ... + } + + Figure 8: MOQT FETCH Message + + Fields common to all Fetch Types: + + * Subscribe ID: The Subscribe ID identifies a given fetch request. + Subscribe ID is a variable length integer that MUST be unique and + monotonically increasing within a session. + + * Subscriber Priority: Specifies the priority of a fetch request + relative to other subscriptions or fetches in the same session. + Lower numbers get higher priority. See Section 5. + + * Group Order: Allows the subscriber to request Objects be delivered + in Ascending (0x1) or Descending (0x2) order by group. See + Section 5. A value of 0x0 indicates the original publisher's + Group Order SHOULD be used. Values larger than 0x2 are a protocol + error. + + * Fetch Type: Identifies the type of Fetch, whether joining or + standalone. + + * Parameters: The parameters are defined in Section 7.1.1. + + Fields present only for Standalone Fetch (0x1): + + * Track Namespace: Identifies the namespace of the track as defined + in (Section 2.4.1). + + * Track Name: Identifies the track name as defined in + (Section 2.4.1). + + * StartGroup: The start Group ID. + + * StartObject: The start Object ID. + + * EndGroup: The end Group ID. + + * EndObject: The end Object ID, plus 1. A value of 0 means the + entire group is requested. + + Fields present only for Joining Fetch (0x2): + + * Joining Subscribe ID: The Subscribe ID of the existing + subscription to be joined. If a publisher receives a Joining + Fetch with a Subscribe ID that does not correspond to an existing + Subscribe, it MUST respond with a Fetch Error. + + * Preceding Group Offset: The group offset for the Fetch prior and + relative to the Current Group of the corresponding Subscribe. A + value of 0 indicates the Fetch starts at the beginning of the + Current Group. + + Objects that are not yet published will not be retrieved by a FETCH. + The latest available Object is indicated in the FETCH_OK, and is the + last Object a fetch will return if the EndGroup and EndObject have + not yet been published. + + A publisher MUST send fetched groups in the determined group order, + either ascending or descending. Within each group, objects are sent + in Object ID order; subgroup ID is not used for ordering. + + If StartGroup/StartObject is greater than the latest published Object + group, the publisher MUST return FETCH_ERROR with error code 'No + Objects'. + +7.7.1. Calculating the Range of a Joining Fetch + + A publisher that receives a Fetch of type Type 0x2 treats it as a + Fetch with a range dynamically determined by the Preceding Group + Offset and field values derived from the corresponding subscription. + + The Largest Group ID and Largest Object ID values from the + corresponding subscription are used to calculate the end of a Joining + Fetch so the Objects retrieved by the FETCH and SUBSCRIBE are + contiguous and non-overlapping. If no Objects have been published + for the track, and the SUBSCRIBE_OK has a ContentExists value of 0, + the publisher responds with a FETCH_ERROR with error code 'No + Objects'. + + The publisher receiving a Joining Fetch computes the range as + follows: + + * Fetch StartGroup: Subscribe Largest Group - Preceding Group Offset + + * Fetch StartObject: 0 + + * Fetch EndGroup: Subscribe Largest Group + + * Fetch EndObject: Subscribe Largest Object + + A Fetch EndObject of 0 requests the entire group, but Fetch will not + retrieve Objects that have not yet been published, so 1 is subtracted + from the Fetch EndGroup if Fetch EndObject is 0. + +7.8. FETCH_CANCEL + + A subscriber issues a FETCH_CANCEL message to a publisher indicating + it is no longer interested in receiving Objects for the fetch + specified by 'Subscribe ID'. The publisher SHOULD close the + unidirectional stream as soon as possible. + + The format of FETCH_CANCEL is as follows: + + FETCH_CANCEL Message { + Type (i) = 0x17, + Length (i), + Subscribe ID (i) + } + + Figure 9: MOQT FETCH_CANCEL Message + + * Subscribe ID: Subscription Identifier as defined in Section 7.7. + +7.9. ANNOUNCE_OK + + The subscriber sends an ANNOUNCE_OK control message to acknowledge + the successful authorization and acceptance of an ANNOUNCE message. + + ANNOUNCE_OK Message + { + Type (i) = 0x7, + Length (i), + Track Namespace (tuple), + } + + Figure 10: MOQT ANNOUNCE_OK Message + + * Track Namespace: Identifies the track namespace in the ANNOUNCE + message for which this response is provided. + +7.10. ANNOUNCE_ERROR + + The subscriber sends an ANNOUNCE_ERROR control message for tracks + that failed authorization. + + ANNOUNCE_ERROR Message + { + Type (i) = 0x8, + Length (i), + Track Namespace (tuple), + Error Code (i), + Reason Phrase Length (i), + Reason Phrase (..), + } + + Figure 11: MOQT ANNOUNCE_ERROR Message + + * Track Namespace: Identifies the track namespace in the ANNOUNCE + message for which this response is provided. + + * Error Code: Identifies an integer error code for announcement + failure. + + * Reason Phrase: Provides the reason for announcement error. + + The application SHOULD use a relevant error code in ANNOUNCE_ERROR, + as defined below: + + +======+================+ + | Code | Reason | + +======+================+ + | 0x0 | Internal Error | + +------+----------------+ + | 0x1 | Unauthorized | + +------+----------------+ + | 0x2 | Timeout | + +------+----------------+ + | 0x3 | Not Supported | + +------+----------------+ + | 0x4 | Uninterested | + +------+----------------+ + + Table 3 + +7.11. ANNOUNCE_CANCEL + + The subscriber sends an ANNOUNCE_CANCEL control message to indicate + it will stop sending new subscriptions for tracks within the provided + Track Namespace. + + ANNOUNCE_CANCEL Message { + Type (i) = 0xC, + Length (i), + Track Namespace (tuple), + Error Code (i), + Reason Phrase Length (i), + Reason Phrase Length (..), + } + + Figure 12: MOQT ANNOUNCE_CANCEL Message + + * Track Namespace: Identifies a track's namespace as defined in + (Section 2.4.1). + + * Error Code: Identifies an integer error code for canceling the + announcement. ANNOUNCE_CANCEL uses the same error codes as + ANNOUNCE_ERROR (Section 7.10). + + * Reason Phrase: Provides the reason for announcement cancelation. + +7.12. TRACK_STATUS_REQUEST + + A potential subscriber sends a 'TRACK_STATUS_REQUEST' message on the + control stream to obtain information about the current status of a + given track. + + A TRACK_STATUS message MUST be sent in response to each + TRACK_STATUS_REQUEST. + + TRACK_STATUS_REQUEST Message { + Type (i) = 0xD, + Length (i), + Track Namespace (tuple), + Track Name Length (i), + Track Name (..), + } + + Figure 13: MOQT TRACK_STATUS_REQUEST Message + +7.13. SUBSCRIBE_ANNOUNCES + + The subscriber sends the SUBSCRIBE_ANNOUNCES control message to a + publisher to request the current set of matching announcements, as + well as future updates to the set. + + SUBSCRIBE_ANNOUNCES Message { + Type (i) = 0x11, + Length (i), + Track Namespace Prefix (tuple), + Number of Parameters (i), + Parameters (..) ..., + } + + Figure 14: MOQT SUBSCRIBE_ANNOUNCES Message + + * Track Namespace Prefix: An ordered N-Tuple of byte fields which + are matched against track namespaces known to the publisher. For + example, if the publisher is a relay that has received ANNOUNCE + messages for namespaces ("example.com", "meeting=123", + "participant=100") and ("example.com", "meeting=123", + "participant=200"), a SUBSCRIBE_ANNOUNCES for ("example.com", + "meeting=123") would match both. If an endpoint receives a Track + Namespace Prefix tuple with an N of 0 or more than 32, it MUST + close the session with a Protocol Violation. + + * Parameters: The parameters are defined in Section 7.1.1. + + The publisher will respond with SUBSCRIBE_ANNOUNCES_OK or + SUBSCRIBE_ANNOUNCES_ERROR. If the SUBSCRIBE_ANNOUNCES is successful, + the publisher will forward any matching ANNOUNCE messages to the + subscriber that it has not yet sent. If the set of matching ANNOUNCE + messages changes, the publisher sends the corresponding ANNOUNCE or + UNANNOUNCE message. + + A subscriber cannot make overlapping namespace subscriptions on a + single session. Within a session, if a publisher receives a + SUBSCRIBE_ANNOUNCES with a Track Namespace Prefix that is a prefix of + an earlier SUBSCRIBE_ANNOUNCES or vice versa, it MUST respond with + SUBSCRIBE_ANNOUNCES_ERROR, with error code + SUBSCRIBE_ANNOUNCES_OVERLAP. + + The publisher MUST ensure the subscriber is authorized to perform + this namespace subscription. + + SUBSCRIBE_ANNOUNCES is not required for a publisher to send ANNOUNCE + and UNANNOUNCE messages to a subscriber. It is useful in + applications or relays where subscribers are only interested in or + authorized to access a subset of available announcements. + +7.14. UNSUBSCRIBE_ANNOUNCES + + A subscriber issues a UNSUBSCRIBE_ANNOUNCES message to a publisher + indicating it is no longer interested in ANNOUNCE and UNANNOUNCE + messages for the specified track namespace prefix. + + The format of UNSUBSCRIBE_ANNOUNCES is as follows: + + UNSUBSCRIBE_ANNOUNCES Message { + Type (i) = 0x14, + Length (i), + Track Namespace Prefix (tuple) + } + + Figure 15: MOQT UNSUBSCRIBE Message + + * Track Namespace Prefix: As defined in Section 7.13. + +7.15. SUBSCRIBE_OK + + A publisher sends a SUBSCRIBE_OK control message for successful + subscriptions. + + SUBSCRIBE_OK + { + Type (i) = 0x4, + Length (i), + Subscribe ID (i), + Expires (i), + Group Order (8), + ContentExists (8), + [Largest Group ID (i)], + [Largest Object ID (i)], + Number of Parameters (i), + Subscribe Parameters (..) ... + } + + Figure 16: MOQT SUBSCRIBE_OK Message + + * Subscribe ID: Subscription Identifier as defined in Section 7.4. + + * Expires: Time in milliseconds after which the subscription is no + longer valid. A value of 0 indicates that the subscription does + not expire or expires at an unknown time. Expires is advisory and + a subscription can end prior to the expiry time or last longer. + + * Group Order: Indicates the subscription will be delivered in + Ascending (0x1) or Descending (0x2) order by group. See + Section 5. Values of 0x0 and those larger than 0x2 are a protocol + error. + + * ContentExists: 1 if an object has been published on this track, 0 + if not. If 0, then the Largest Group ID and Largest Object ID + fields will not be present. Any other value is a protocol error + and MUST terminate the session with a Protocol Violation + (Section 3.5). + + * Largest Group ID: The largest Group ID available for this track. + This field is only present if ContentExists has a value of 1. + + * Largest Object ID: The largest Object ID available within the + largest Group ID for this track. This field is only present if + ContentExists has a value of 1. + + * Subscribe Parameters: The parameters are defined in Section 7.1.1. + +7.16. SUBSCRIBE_ERROR + + A publisher sends a SUBSCRIBE_ERROR control message in response to a + failed SUBSCRIBE. + + SUBSCRIBE_ERROR + { + Type (i) = 0x5, + Length (i), + Subscribe ID (i), + Error Code (i), + Reason Phrase Length (i), + Reason Phrase (..), + Track Alias (i), + } + + Figure 17: MOQT SUBSCRIBE_ERROR Message + + * Subscribe ID: Subscription Identifier as defined in Section 7.4. + + * Error Code: Identifies an integer error code for subscription + failure. + + * Reason Phrase: Provides the reason for subscription error. + + * Track Alias: When Error Code is 'Retry Track Alias', the + subscriber SHOULD re-issue the SUBSCRIBE with this Track Alias + instead. If this Track Alias is already in use, the subscriber + MUST close the connection with a Duplicate Track Alias error + (Section 3.5). + + The application SHOULD use a relevant error code in SUBSCRIBE_ERROR, + as defined below: + + +======+======================+ + | Code | Reason | + +======+======================+ + | 0x0 | Internal Error | + +------+----------------------+ + | 0x1 | Unauthorized | + +------+----------------------+ + | 0x2 | Timeout | + +------+----------------------+ + | 0x3 | Not Supported | + +------+----------------------+ + | 0x4 | Track Does Not Exist | + +------+----------------------+ + | 0x5 | Invalid Range | + +------+----------------------+ + | 0x6 | Retry Track Alias | + +------+----------------------+ + + Table 4 + +7.17. FETCH_OK + + A publisher sends a FETCH_OK control message in response to + successful fetches. A publisher MAY send Objects in response to a + FETCH before the FETCH_OK message is sent, but the FETCH_OK MUST NOT + be sent until the latest group and object are known. + + FETCH_OK + { + Type (i) = 0x18, + Length (i), + Subscribe ID (i), + Group Order (8), + End Of Track (8), + Largest Group ID (i), + Largest Object ID (i), + Number of Parameters (i), + Subscribe Parameters (..) ... + } + + Figure 18: MOQT FETCH_OK Message + + * Subscribe ID: Fetch Identifier as defined in Section 7.7. + + * Group Order: Indicates the fetch will be delivered in Ascending + (0x1) or Descending (0x2) order by group. See Section 5. Values + of 0x0 and those larger than 0x2 are a protocol error. + + * End Of Track: 1 if all objects have been published on this track, + so the Largest Group ID and Object Id indicate the last Object in + the track, 0 if not. + + * Largest Group ID: The largest Group ID available for this track. + + * Largest Object ID: The largest Object ID available within the + largest Group ID for this track. + + * Subscribe Parameters: The parameters are defined in Section 7.1.1. + +7.18. FETCH_ERROR + + A publisher sends a FETCH_ERROR control message in response to a + failed FETCH. + + FETCH_ERROR + { + Type (i) = 0x19, + Length (i), + Subscribe ID (i), + Error Code (i), + Reason Phrase Length (i), + Reason Phrase (..), + } + + Figure 19: MOQT FETCH_ERROR Message + + * Subscribe ID: Subscription Identifier as defined in Section 7.4. + + * Error Code: Identifies an integer error code for fetch failure. + + * Reason Phrase: Provides the reason for fetch error. + + The application SHOULD use a relevant error code in FETCH_ERROR, as + defined below: + + +======+======================+ + | Code | Reason | + +======+======================+ + | 0x0 | Internal Error | + +------+----------------------+ + | 0x1 | Unauthorized | + +------+----------------------+ + | 0x2 | Timeout | + +------+----------------------+ + | 0x3 | Not Supported | + +------+----------------------+ + | 0x4 | Track Does Not Exist | + +------+----------------------+ + | 0x5 | Invalid Range | + +------+----------------------+ + + Table 5 + +7.19. SUBSCRIBE_DONE + + A publisher sends a SUBSCRIBE_DONE message to indicate it is done + publishing Objects for that subscription. The Status Code indicates + why the subscription ended, and whether it was an error. Because + SUBSCRIBE_DONE is sent on the control stream, it is likely to arrive + at the receiver before late-arriving objects, and often even late- + opening streams. However, the receiver uses it as an indication that + it should receive any late-opening streams in a relatively short + time. + + Note that some objects in the subscribed track might never be + delivered, because a stream was reset, or never opened in the first + place, due to the delivery timeout. + + A sender MUST NOT send SUBSCRIBE_DONE until it has closed all streams + it will ever open, and has no further datagrams to send, for a + subscription. After sending SUBSCRIBE_DONE, the sender can + immediately destroy subscription state, although stream state can + persist until delivery completes. The sender might persist + subscription state to enforce the delivery timeout by resetting + streams on which it has already sent FIN, only deleting it when all + such streams have received ACK of the FIN. + + A sender MUST NOT destroy subscription state until it sends + SUBSCRIBE_DONE, though it can choose to stop sending objects (and + thus send SUBSCRIBE_DONE) for any reason. + + A subscriber that receives SUBSCRIBE_DONE SHOULD set a timer of at + least its delivery timeout in case some objects are still inbound due + to prioritization or packet loss. The subscriber MAY dispense with a + timer if it sent UNSUBSCRIBE or is otherwise no longer interested in + objects from the track. Once the timer has expired, the receiver + destroys subscription state once all open streams for the + subscription have closed. A subscriber MAY discard subscription + state earlier, at the cost of potentially not delivering some late + objects to the application. The subscriber SHOULD send STOP_SENDING + on all streams related to the subscription when it deletes + subscription state. + + The format of SUBSCRIBE_DONE is as follows: + + SUBSCRIBE_DONE Message { + Type (i) = 0xB, + Length (i), + Subscribe ID (i), + Status Code (i), + Stream Count (i), + Reason Phrase Length (i), + Reason Phrase (..), + } + + Figure 20: MOQT SUBSCRIBE_DONE Message + + * Subscribe ID: Subscription identifier as defined in Section 7.4. + + * Status Code: An integer status code indicating why the + subscription ended. + + * Stream Count: An integer indicating the number of data streams the + publisher opened for this subscription. This helps the subscriber + know if it has received all of the data published in this + subscription by comparing the number of streams received. The + subscriber can immediately remove all subscription state once the + same number of streams have been processed. If the track had + Forwarding Preference = Datagram, the publisher MUST set Stream + Count to 0. If the publisher is unable to set Stream Count to the + exact number of streams opened for the subscription, it MUST set + Stream Count to 2^62 - 1. Subscribers SHOULD use a timeout or + other mechanism to remove subscription state in case the publisher + set an incorrect value, reset a stream before the SUBGROUP_HEADER, + or set the maximum value. If a subscriber receives more streams + for a subscription than specified in Stream Count, it MAY close + the session with a Protocol Violation. + + * Reason Phrase: Provides the reason for subscription error. + + The application SHOULD use a relevant status code in SUBSCRIBE_DONE, + as defined below: + + +======+====================+ + | Code | Reason | + +======+====================+ + | 0x0 | Internal Error | + +------+--------------------+ + | 0x1 | Unauthorized | + +------+--------------------+ + | 0x2 | Track Ended | + +------+--------------------+ + | 0x3 | Subscription Ended | + +------+--------------------+ + | 0x4 | Going Away | + +------+--------------------+ + | 0x5 | Expired | + +------+--------------------+ + | 0x6 | Too Far Behind | + +------+--------------------+ + + Table 6 + +7.20. MAX_SUBSCRIBE_ID + + A publisher sends a MAX_SUBSCRIBE_ID message to increase the number + of subscriptions a subscriber can create within a session. + + The Maximum Subscribe Id MUST only increase within a session, and + receipt of a MAX_SUBSCRIBE_ID message with an equal or smaller + Subscribe ID value is a 'Protocol Violation'. + + MAX_SUBSCRIBE_ID + { + Type (i) = 0x15, + Length (i), + Subscribe ID (i), + } + + Figure 21: MOQT MAX_SUBSCRIBE_ID Message + + * Subscribe ID: The new Maximum Subscribe ID for the session. If a + Subscribe ID Section 7.4 equal or larger than this is received by + the publisher that sent the MAX_SUBSCRIBE_ID, the publisher MUST + close the session with an error of 'Too Many Subscribes'. + + MAX_SUBSCRIBE_ID is similar to MAX_STREAMS in ([RFC9000], + Section 4.6), and similar considerations apply when deciding how + often to send MAX_SUBSCRIBE_ID. For example, implementations might + choose to increase MAX_SUBSCRIBE_ID as subscriptions close to keep + the number of subscriptions available to subscribers roughly + consistent. + +7.21. SUBSCRIBES_BLOCKED + + The SUBSCRIBES_BLOCKED message is sent when a subscriber would like + to begin a new subscription, but cannot because the Subscribe ID + would exceed the Maximum Subscribe ID value sent by the peer. The + subscriber SHOULD send only one SUBSCRIBES_BLOCKED for a given + Maximum Subscribe ID. + + A publisher MAY send a MAX_SUBSCRIBE_ID upon receipt of + SUBSCRIBES_BLOCKED, but it MUST NOT rely on SUBSCRIBES_BLOCKED to + trigger sending a MAX_SUBSCRIBE_ID, because sending + SUBSCRIBES_BLOCKED is not required. + + SUBSCRIBES_BLOCKED + { + Type (i) = 0x1A, + Length (i), + Maximum Subscribe ID (i), + } + + Figure 22: MOQT SUBSCRIBES_BLOCKED Message + + * Maximum Subscribe ID: The Maximum Subscribe ID for the session on + which the subscriber is blocked. More on Subscribe ID in + Section 7.4. + +7.22. ANNOUNCE + + The publisher sends the ANNOUNCE control message to advertise where + the receiver can route SUBSCRIBEs for tracks within the announced + Track Namespace. The receiver verifies the publisher is authorized + to publish tracks under this namespace. + + ANNOUNCE Message { + Type (i) = 0x6, + Length (i), + Track Namespace (tuple), + Number of Parameters (i), + Parameters (..) ..., + } + + Figure 23: MOQT ANNOUNCE Message + + * Track Namespace: Identifies a track's namespace as defined in + (Section 2.4.1) + + * Parameters: The parameters are defined in Section 7.1.1. + +7.23. UNANNOUNCE + + The publisher sends the UNANNOUNCE control message to indicate its + intent to stop serving new subscriptions for tracks within the + provided Track Namespace. + + UNANNOUNCE Message { + Type (i) = 0x9, + Length (i), + Track Namespace (tuple), + } + + Figure 24: MOQT UNANNOUNCE Message + + * Track Namespace: Identifies a track's namespace as defined in + (Section 2.4.1). + +7.24. TRACK_STATUS + + A publisher sends a 'TRACK_STATUS' message on the control stream in + response to a TRACK_STATUS_REQUEST message. + + TRACK_STATUS Message { + Type (i) = 0xE, + Length (i), + Track Namespace (tuple), + Track Name Length(i), + Track Name (..), + Status Code (i), + Last Group ID (i), + Last Object ID (i), + } + + Figure 25: MOQT TRACK_STATUS Message + + The 'Status Code' field provides additional information about the + status of the track. It MUST hold one of the following values. Any + other value is a malformed message. + + 0x00: The track is in progress, and subsequent fields contain the + highest group and object ID for that track. + + 0x01: The track does not exist. Subsequent fields MUST be zero, and + any other value is a malformed message. + + 0x02: The track has not yet begun. Subsequent fields MUST be zero. + Any other value is a malformed message. + + 0x03: The track has finished, so there is no "live edge." Subsequent + fields contain the highest Group and object ID known. + + 0x04: The publisher is a relay that cannot obtain the current track + status from upstream. Subsequent fields contain the largest group + and object ID known. + + Any other value in the Status Code field is a malformed message. + + When a relay is subscribed to a track, it can simply return the + highest group and object ID it has observed, whether or not that + object was cached or completely delivered. If not subscribed, a + relay SHOULD send a TRACK_STATUS_REQUEST upstream to obtain updated + information. + + Alternatively, the relay MAY subscribe to the track to obtain the + same information. + + If a relay cannot or will not do either, it should return its best + available information with status code 0x04. + + The receiver of multiple TRACK_STATUS messages for a track uses the + information from the latest arriving message, as they are delivered + in order on a single stream. + +7.25. SUBSCRIBE_ANNOUNCES_OK + + A publisher sends a SUBSCRIBE_ANNOUNCES_OK control message for + successful namespace subscriptions. + + SUBSCRIBE_ANNOUNCES_OK + { + Type (i) = 0x12, + Length (i), + Track Namespace Prefix (tuple), + } + + Figure 26: MOQT SUBSCRIBE_ANNOUNCES_OK Message + + * Track Namespace Prefix: As defined in Section 7.13. + +7.26. SUBSCRIBE_ANNOUNCES_ERROR + + A publisher sends a SUBSCRIBE_ANNOUNCES_ERROR control message in + response to a failed SUBSCRIBE_ANNOUNCES. + + SUBSCRIBE_ANNOUNCES_ERROR + { + Type (i) = 0x13, + Length (i), + Track Namespace Prefix (tuple), + Error Code (i), + Reason Phrase Length (i), + Reason Phrase (..), + } + + Figure 27: MOQT SUBSCRIBE_ANNOUNCES_ERROR Message + + * Track Namespace Prefix: As defined in Section 7.13. + + * Error Code: Identifies an integer error code for the namespace + subscription failure. + + * Reason Phrase: Provides the reason for the namespace subscription + error. + + The application SHOULD use a relevant error code in + SUBSCRIBE_ANNOUNCES_ERROR, as defined below: + + +======+==========================+ + | Code | Reason | + +======+==========================+ + | 0x0 | Internal Error | + +------+--------------------------+ + | 0x1 | Unauthorized | + +------+--------------------------+ + | 0x2 | Timeout | + +------+--------------------------+ + | 0x3 | Not Supported | + +------+--------------------------+ + | 0x4 | Namespace Prefix Unknown | + +------+--------------------------+ + + Table 7 + +8. Data Streams + + A publisher sends Objects matching a subscription on Data Streams. + + All unidirectional MOQT streams start with a variable-length integer + indicating the type of the stream in question. + + +=====+=================================+ + | ID | Type | + +=====+=================================+ + | 0x4 | SUBGROUP_HEADER (Section 8.4.1) | + +-----+---------------------------------+ + | 0x5 | FETCH_HEADER (Section 8.4.3) | + +-----+---------------------------------+ + + Table 8 + + All MOQT datagrams start with a variable-length integer indicating + the type of the datagram. + + +=====+======================================+ + | ID | Type | + +=====+======================================+ + | 0x1 | OBJECT_DATAGRAM (Section 8.2) | + +-----+--------------------------------------+ + | 0x2 | OBJECT_DATAGRAM_STATUS (Section 8.2) | + +-----+--------------------------------------+ + + Table 9 + + An endpoint that receives an unknown stream or datagram type MUST + close the session. + + The publisher only sends Objects after receiving a SUBSCRIBE or + FETCH. The publisher MUST NOT send Objects that are not requested. + If an endpoint receives an Object it never requested, it SHOULD + terminate the session with a protocol violation. Objects can arrive + after a subscription or fetch has been cancelled, so the session MUST + NOT be teriminated in that case. + + Every Track has a single 'Object Forwarding Preference' and the + Original Publisher MUST NOT mix different forwarding preferences + within a single track. If a subscriber receives different forwarding + preferences for a track, it SHOULD close the session with an error of + 'Protocol Violation'. + +8.1. Object Headers + + An OBJECT message contains a range of contiguous bytes from from the + specified track, as well as associated metadata required to deliver, + cache, and forward it. Objects are sent by publishers. + +8.1.1. Canonical Object Fields + + A canonical MoQ Object has the following information: + + * Track Namespace and Track Name: The track this object belongs to. + + * Group ID: The object is a member of the indicated group ID + Section 2.3 within the track. + + * Object ID: The order of the object within the group. The IDs + starts at 0, increasing sequentially for each object within the + group. + + * Publisher Priority: An 8 bit integer indicating the publisher's + priority for the Object Section 5. + + * Object Forwarding Preference: An enumeration indicating how a + publisher sends an object. The preferences are Subgroup and + Datagram. An Object MUST be sent according to its Object + Forwarding Preference, described below. + + * Subgroup ID: The object is a member of the indicated subgroup ID + (Section 2.2) within the group. This field is omitted if the + Object Forwarding Preference is Track or Datagram. + + * Object Status: As enumeration used to indicate missing objects or + mark the end of a group or track. See Section 8.1.1.1 below. + + * Object Extension Length: The total length of the Object Extension + Headers block, in bytes. + + * Object Extensions : A sequence of Object Extension Headers. See + Section 8.1.1.2 below. + + * Object Payload: An opaque payload intended for an End Subscriber + and SHOULD NOT be processed by a relay. Only present when 'Object + Status' is Normal (0x0). + +8.1.1.1. Object Status + + The Object Status informs subscribers what objects will not be + received because they were never produced, are no longer available, + or because they are beyond the end of a group or track. + + Status can have following values: + + * 0x0 := Normal object. This status is implicit for any non-zero + length object. Zero-length objects explicitly encode the Normal + status. + + * 0x1 := Indicates Object does not exist. Indicates that this + object does not exist at any publisher and it will not be + published in the future. This SHOULD be cached. + + * 0x3 := Indicates end of Group. ObjectId is one greater that the + largest object produced in the group identified by the GroupID. + This is sent right after the last object in the group. If the + ObjectID is 0, it indicates there are no Objects in this Group. + This SHOULD be cached. A publisher MAY use an end of Group object + to signal the end of all open Subgroups in a Group. + + * 0x4 := Indicates end of Track and Group. GroupID is the largest + group produced in this track and the ObjectId is one greater than + the largest object produced in that group. An object with this + status that has a Group ID less than any other Group ID, or an + Object ID less than or equal to the largest in the group, is a + protocol error, and the receiver MUST terminate the session. This + SHOULD be cached. + + * 0x5 := Indicates end of Track. GroupID is one greater than the + largest group produced in this track and the ObjectId is zero. An + object with this status that has a Group ID less than or equal to + any other Group ID, or an Object ID other than zero, is a protocol + error, and the receiver MUST terminate the session. This SHOULD + be cached. + + Any other value SHOULD be treated as a protocol error and terminate + the session with a Protocol Violation (Section 3.5). Any object with + a status code other than zero MUST have an empty payload. + + Though some status information could be inferred from QUIC stream + state, that information is not reliable and cacheable. + +8.1.1.2. Object Extension Header + + Object Extension Headers are visible to relays and allow the + transmission of future metadata relevant to MOQT Object distribution. + Any Object metadata never accessed by the transport or relays SHOULD + be serialized as part of the Object payload and not as an extension + header. + + Extension Headers are defined in external specifications and + registered in an IANA table Section 10. These specifications define + the type and value of the header, along with any rules concerning + processing, modification, caching and forwarding. A relay which is + coded to implement these rules is said to "support" the extension. + + If unsupported by the relay, Extension Headers MUST NOT be modified, + MUST be cached as part of the Object and MUST be forwarded by relays. + + If supported by the relay and subject to the processing rules + specified in the definition of the extension, Extension Headers MAY + be modified, added, removed, and/or cached by relays. + + Object Extension Headers are serialized as defined below: + + Extension Header { + Header Type (i), + [Header Value (i)] + [Header Length (i), + Header Value (..)] + } + + Figure 28: Object Extension Header Format + + * Header type: an unsigned integer, encoded as a varint, identifying + the type of the extension and also the subsequent serialization. + + * Header values: even types are followed by a single varint encoded + value. Odd types are followed by a varint encoded length and then + the header value. Header types are registered in the IANA table + 'MOQ Extension Headers'. See Section 10. + +8.2. Object Datagram + + An OBJECT_DATAGRAM carries a single object in a datagram. + + An Object received in an OBJECT_DATAGRAM message has an Object + Forwarding Preference = Datagram. To send an Object with Object + Forwarding Preference = Datagram, determine the length of the header + and payload and send the Object as datagram. In certain scenarios + where the object size can be larger than maximum datagram size for + the session, the Object will be dropped. + + OBJECT_DATAGRAM { + Track Alias (i), + Group ID (i), + Object ID (i), + Publisher Priority (8), + Extension Headers Length (i), + [Extension headers (...)], + Object Payload (..), + } + + Figure 29: MOQT OBJECT_DATAGRAM + + There is no explicit length field. The entirety of the transport + datagram following Publisher Priority contains the Object Payload. + +8.3. Object Datagram Status + + An OBJECT_DATAGRAM_STATUS is similar to OBEJCT_DATAGRAM except it + conveys an Object Status and has no payload. + + OBJECT_DATAGRAM_STATUS { + Track Alias (i), + Group ID (i), + Object ID (i), + Publisher Priority (8), + Extension Headers Length (i), + [Extension headers (...)], + Object Status (i), + } + + Figure 30: MOQT OBJECT_DATAGRAM_STATUS + +8.4. Streams + + When objects are sent on streams, the stream begins with a Subgroup + Header and is followed by one or more sets of serialized object + fields. If a stream ends gracefully in the middle of a serialized + Object, the session SHOULD be terminated with a Protocol Violation. + + A publisher SHOULD NOT open more than one stream at a time with the + same Subgroup Header field values. + +8.4.1. Subgroup Header + + When a stream begins with SUBGROUP_HEADER, all Objects on the stream + belong to the track requested in the Subscribe message identified by + Track Alias and the subgroup indicated by 'Group ID' and Subgroup ID. + + SUBGROUP_HEADER { + Track Alias (i), + Group ID (i), + Subgroup ID (i), + Publisher Priority (8), + } + + Figure 31: MOQT SUBGROUP_HEADER + + All Objects received on a stream opened with SUBGROUP_HEADER have an + Object Forwarding Preference = Subgroup. + + To send an Object with Object Forwarding Preference = Subgroup, find + the open stream that is associated with the subscription, Group ID + and Subgroup ID, or open a new one and send the SUBGROUP_HEADER. + Then serialize the following fields. + + The Object Status field is only sent if the Object Payload Length is + zero. + + { + Object ID (i), + Extension Headers Length (i), + [Extension headers (...)], + Object Payload Length (i), + [Object Status (i)], + Object Payload (..), + } + + Figure 32: MOQT Subgroup Fields + + A publisher MUST NOT send an Object on a stream if its Object ID is + less than a previously sent Object ID within a given group in that + stream. + +8.4.2. Closing Subgroup Streams + + Subscribers will often need to know if they have received all objects + in a Subgroup, particularly if they serve as a relay or cache. QUIC + and Webtransport streams provide signals that can be used for this + purpose. Closing Subgroups promptly frees system resources and often + unlocks flow control credit to open more streams. + + If a sender has delivered all objects in a Subgroup to the QUIC + stream, except any objects before the beginning of a subscription, it + MUST close the stream with a FIN. + + If a sender closes the stream before delivering all such objects to + the QUIC stream, it MUST use a RESET_STREAM or RESET_STREAM_AT + [I-D.draft-ietf-quic-reliable-stream-reset] frame. This includes an + open Subgroup exceeding its Delivery Timeout, early termination of + subscription due to an UNSUBSCRIBE message, a publisher's decision to + end the subscription early, or a SUBSCRIBE_UPDATE moving the end of + the subscription to before the current Group or the start after the + current Group. When RESET_STREAM_AT is used, the reliable_size + SHOULD include the stream header so the receiver can identify the + corresponding subscription and accurately account for reset data + streams when handling SUBSCRIBE_DONE (see Section 7.19). Publishers + that reset data streams without using RESET_STREAM_AT with an + appropriate reliable_size can cause subscribers to hold on to + subscription state until a timeout expires. + + A sender might send all objects in a Subgroup and the FIN on a QUIC + stream, and then reset the stream. In this case, the receiving + application would receive the FIN if and only if all objects were + received. If the application receives all data on the stream and the + FIN, it can ignore any RESET_STREAM it receives. + + If a sender will not deliver any objects from a Subgroup, it MAY send + a SUBGROUP_HEADER on a new stream, with no objects, and then send + RESET_STREAM_AT with a reliable_size equal to the length of the + stream header. This explicitly tells the receiver there is an unsent + Subgroup. + + Since SUBSCRIBEs always end on a group boundary, an ending + subscription can always cleanly close all its subgroups. A sender + that terminates a stream early for any other reason (e.g., to handoff + to a different sender) MUST use RESET_STREAM or RESET_STREAM_AT. + Senders SHOULD terminate a stream on Group boundaries to avoid doing + so. + + An MoQT implementation that processes a stream FIN is assured it has + received all objects in a subgroup from the start of the + subscription. If a relay, it can forward stream FINs to its own + subscribers once those objects have been sent. A relay MAY treat + receipt of EndOfGroup, GroupDoesNotExist, or EndOfTrack objects as a + signal to close corresponding streams even if the FIN has not + arrived, as further objects on the stream would be a protocol + violation. + + Similarly, an EndOfGroup message indicates the maximum Object ID in + the Group, so if all Objects in the Group have been received, a FIN + can be sent on any stream where the entire subgroup has been sent. + This might be complex to implement. + + Processing a RESET_STREAM or RESET_STREAM_AT means that there might + be other objects in the Subgroup beyond the last one received. A + relay might immediately reset the corresponding downstream stream, or + it might attempt to recover the missing Objects in an effort send all + the objects in the subgroups and the FIN. It also might send + RESET_STREAM_AT with reliable_size set to the last object it has, so + as to reliably deliver the objects it has while signaling that other + objects might exist. + + A subscriber MAY send a QUIC STOP_SENDING frame for a subgroup stream + if the Group or Subgroup is no longer of interest to it. The + publisher SHOULD respond with RESET_STREAM or RESET_STREAM_AT. If + RESET_STREAM_AT is sent, note that the receiver has indicated no + interest in the objects, so setting a reliable_size beyond the stream + header is of questionable utility. + + RESET_STREAM and STOP_SENDING on SUBSCRIBE data streams have no + impact on other Subgroups in the Group or the subscription, although + applications might cancel all Subgroups in a Group at once. + +8.4.3. Fetch Header + + When a stream begins with FETCH_HEADER, all objects on the stream + belong to the track requested in the Fetch message identified by + Subscribe ID. + + FETCH_HEADER { + Subscribe ID (i), + } + + Figure 33: MOQT FETCH_HEADER + + Each object sent on a fetch stream after the FETCH_HEADER has the + following format: + + { + Group ID (i), + Subgroup ID (i), + Object ID (i), + Publisher Priority (8), + Extension Headers Length (i), + [Extension headers (...)], + Object Payload Length (i), + [Object Status (i)], + Object Payload (..), + } + + Figure 34: MOQT Fetch Object Fields + + The Object Status field is only sent if the Object Payload Length is + zero. + + The Subgroup ID field of an object with a Forwarding Preference of + "Datagram" (see Section 8.1.1) is set to the Object ID. + +8.5. Examples + + Sending a subgroup on one stream: + + Stream = 2 + + SUBGROUP_HEADER { + Track Alias = 2 + Group ID = 0 + Subgroup ID = 0 + Publisher Priority = 0 + } + { + Object ID = 0 + Extension Headers Length = 0 + Object Payload Length = 4 + Payload = "abcd" + } + { + Object ID = 1 + Extension Headers Length = 0 + Object Payload Length = 4 + Payload = "efgh" + } + + Sending a group on one stream, with the first object containing two + Extension Headers. + + Stream = 2 + + STREAM_HEADER_GROUP { + Subscribe ID = 2 + Track Alias = 2 + Group ID = 0 + Publisher Priority = 0 + } + { + Object ID = 0 + Extension Headers Length = 33 + { Type = 4 + Value = 2186796243 + }, + { Type = 77 + Length = 21 + Value = "traceID:123456" + } + Object Payload Length = 4 + Payload = "abcd" + } + { + Object ID = 1 + Extension Headers Length = 0 + Object Payload Length = 4 + Payload = "efgh" + } + +9. Security Considerations + + TODO: Expand this section, including subscriptions. + +9.1. Resource Exhaustion + + Live content requires significant bandwidth and resources. Failure + to set limits will quickly cause resource exhaustion. + + MOQT uses stream limits and flow control to impose resource limits at + the network layer. Endpoints SHOULD set flow control limits based on + the anticipated bitrate. + + Endpoints MAY impose a MAX STREAM count limit which would restrict + the number of concurrent streams which a MOQT Streaming Format could + have in flight. + + The publisher prioritizes and transmits streams out of order. + Streams might be starved indefinitely during congestion. The + publisher and subscriber MUST cancel a stream, preferably the lowest + priority, after reaching a resource limit. + +9.2. Timeouts + + Implementations are advised to use timeouts to prevent resource + exhaustion attacks by a peer that does not send expected data within + an expected time. Each implementation is expected to set its own + limits. + +10. IANA Considerations + + TODO: fill out currently missing registries: + + * MOQT version numbers + + * Setup parameters + + * Subscribe parameters + + * Subscribe Error codes + + * Subscribe Namespace Error codes + + * Announce Error codes + + * Announce Cancel Reason codes + + * Message types + + * MOQ Extension headers - we wish to reserve extension types 0-63 + for standards utilization where space is a premium, 64 - 16383 for + standards utilization where space is less of a concern, and 16384 + and above for first-come-first-served non-standardization usage. + + TODO: register the URI scheme and the ALPN and grease the Extension + types + +Contributors + + * Alan Frindell + + * Ali Begen + + * Charles Krasic + + * Christian Huitema + + * Cullen Jennings + + * James Hurley + + * Jordi Cenzano + + * Mike English + + * Mo Zanaty + + * Will Law + +References + +Normative References + + [I-D.draft-ietf-quic-reliable-stream-reset] + Seemann, M. and K. Oku, "QUIC Stream Resets with Partial + Delivery", Work in Progress, Internet-Draft, draft-ietf- + quic-reliable-stream-reset-06, 28 February 2024, + . + + [QUIC] Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based + Multiplexed and Secure Transport", RFC 9000, + DOI 10.17487/RFC9000, May 2021, + . + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, + DOI 10.17487/RFC2119, March 1997, + . + + [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform + Resource Identifier (URI): Generic Syntax", STD 66, + RFC 3986, DOI 10.17487/RFC3986, January 2005, + . + + [RFC7301] Friedl, S., Popov, A., Langley, A., and E. Stephan, + "Transport Layer Security (TLS) Application-Layer Protocol + Negotiation Extension", RFC 7301, DOI 10.17487/RFC7301, + July 2014, . + + [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC + 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, + May 2017, . + + [RFC8615] Nottingham, M., "Well-Known Uniform Resource Identifiers + (URIs)", RFC 8615, DOI 10.17487/RFC8615, May 2019, + . + + [RFC9110] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, + Ed., "HTTP Semantics", STD 97, RFC 9110, + DOI 10.17487/RFC9110, June 2022, + . + + [WebTransport] + Frindell, A., Kinnear, E., and V. Vasiliev, "WebTransport + over HTTP/3", Work in Progress, Internet-Draft, draft- + ietf-webtrans-http3-11, 21 October 2024, + . + +Informative References + + [I-D.ietf-webtrans-overview] + Vasiliev, V., "The WebTransport Protocol Framework", Work + in Progress, Internet-Draft, draft-ietf-webtrans-overview- + 09, 25 February 2025, + . + + [RFC9000] Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based + Multiplexed and Secure Transport", RFC 9000, + DOI 10.17487/RFC9000, May 2021, + . + +Authors' Addresses + + Luke Curley + Discord + Email: kixelated@gmail.com + + + Kirill Pugin + Meta + Email: ikir@meta.com + + + Suhas Nandakumar + Cisco + Email: snandaku@cisco.com + + + Victor Vasiliev + Google + Email: vasilvv@google.com + + + Ian Swett (editor) + Google + Email: ianswett@google.com diff --git a/ianswett-move-connection-url/index.html b/ianswett-move-connection-url/index.html new file mode 100644 index 00000000..4a965263 --- /dev/null +++ b/ianswett-move-connection-url/index.html @@ -0,0 +1,45 @@ + + + + moq-wg/moq-transport ianswett-move-connection-url preview + + + + +

Editor's drafts for ianswett-move-connection-url branch of moq-wg/moq-transport

+ + + + + + +
moq-transportplain textsame as main
+ + + diff --git a/index.html b/index.html index b5067a69..21d1b07c 100644 --- a/index.html +++ b/index.html @@ -120,6 +120,14 @@

Preview for branch fix-08-datagrams

diff with main +

Preview for branch ianswett-move-connection-url

+ + + + + + +
moq-transportplain textdiff with main

Preview for branch edit6