MOQT uses a pair of unidirectional streams for creating the session and exchanging control messages. Each peer opens one control stream beginning with a SETUP message. Using a pair of unidirectional streams rather than a single bidirectional stream allows either peer to send data as soon as it is able. Depending on whether 0-RTT is available on the QUIC connection, either client or server might be able to send stream data first.
In addition to the control streams, this specification uses bidirectional streams
to carry requests. A request stream begins with one of these seven message types:
TRACK_STATUS, SUBSCRIBE, PUBLISH, FETCH, PUBLISH_NAMESPACE,
SUBSCRIBE_NAMESPACE, and SUBSCRIBE_TRACKS. Bidirectional streams MUST NOT
begin with any other message type unless negotiated. If they do, the peer MUST
close the Session with a PROTOCOL_VIOLATION. Objects are sent on unidirectional
streams.
As such, a client can initiate a MOQT session, subscribe, and start publishing Objects all in parallel.
Unidirectional streams containing Objects or bidirectional stream(s) beginning with a request message could arrive prior to the control streams, in which case the data SHOULD be buffered until both control streams arrive and setup is complete. If an implementation does not want to buffer or if the message type is not supported, it MAY reset such bidirectional streams before the session and control streams are established.
A control stream MUST NOT be closed at the underlying transport layer during the
session's lifetime. Doing so results in the session being closed as a
PROTOCOL_VIOLATION.
Prior to receiving the peer's SETUP message, it's unknown what extensions a peer will support. Message Parameters requiring negotiation SHOULD NOT be used prior to receiving the peer's SETUP message unless the application requires the extension or the endpoint knows the peer supports the extension. If an unsupported Message Parameter is used, the peer will be unable to process it and the session will be terminated. See Section 10.2.
3.3.1. 0-RTT
QUIC supports 0-RTT (Section 2.3 of [RFC8446]), but WebTransport over QUIC is not expected to use 0-RTT, because initializing a WebTransport session uses CONNECT, which is not a safe method. [RFC8470] describes the use of 0-RTT with HTTP in more detail. If 0-RTT is used with an existing or future version of WebTransport, the following would apply to it as well as QUIC.
MOQT Messages and Objects as defined in this draft are safe to replay in most circumstances.
-
TRACK_STATUS gets the Largest Object and Track Properties, but does not change the state of a Track or any Object in the Track.
-
SUBSCRIBE requests Objects be delivered, but does not change the Objects being requested.
-
PUBLISH initiates a Subscription. Objects can be immediately sent to the Subscriber. Processing the same Objects multiple times is idempotent, as the subscriber or relay can identify and discard duplicates based on the Group ID and Object ID.
-
SUBSCRIBE_NAMESPACE requests a list of namespaces and the establishment of new subscriptions, but does not change the available Namespaces, Tracks, or Objects contained within a Track.
-
PUBLISH_NAMESPACE requests that Subscriptions under the namespace be sent to that Publisher. If a Subscription was sent to the replaying endpoint, it would fail because the endpoint cannot complete the handshake.
Some potential side effects of replay are:
-
Publishing Objects that were previously published could cause those Objects to be distributed to active Subscriptions if the relays do not identify them as already having been published. This re-distribution could also make them available in cache again after they previously expired.
Replays could increase load on the MOQT network. For relay to client traffic, this is no worse than 0-RTT in HTTP/3, since the server is limited by the amplification factor until address validation. However, it could cause the relay to initiate new upstream Subscriptions. For a SUBSCRIBE_NAMESPACE that requested Subscriptions in the Namespace, sending that upstream could cause the Relay to receive a number of new Subscriptions on the replaying client's behalf.
Relays MAY defer initiating upstream subscriptions until the handshake is complete or reject 0-RTT entirely to mitigate resource exhaustion from replayed packets.
3.3.2. Request Cancellation and Rejection
Once a request stream has been opened, the request MAY be cancelled by either endpoint. Senders cancel requests if the response is no longer of interest; Receivers cancel requests if they are unable to or choose not to respond.
Implementations SHOULD cancel requests by abruptly terminating any directions of a stream that are still open by resetting or sending STOP_SENDING.
When an endpoint rejects a request without performing any application processing, it SHOULD send a REQUEST_ERROR and FIN the stream.
The application SHOULD use a relevant error code when resetting or sending STOP_SENDING on a request stream, as defined in Section 3.3.3.
3.3.3. Stream Reset Error Codes
The application SHOULD use a relevant error code when resetting or sending STOP_SENDING on any stream.
- INTERNAL_ERROR (0x0):
-
An implementation specific error.
- CANCELLED (0x1):
-
The stream was cancelled by either endpoint. For Subscriptions, PUBLISH_DONE (Section 10.11) may have a more detailed status code.
- DELIVERY_TIMEOUT (0x2):
-
A delivery timeout (Section 8) was exceeded for this stream.
- SESSION_CLOSED (0x3):
-
The session is being closed.
- GOING_AWAY (0x4):
-
The endpoint is rejecting this request because it has sent or received a GOAWAY.
- TOO_FAR_BEHIND (0x5):
-
The corresponding subscription has exceeded the publisher's resource limits and is being terminated (see Section 8).
- UNKNOWN_OBJECT_STATUS (0x6):
-
In response to a FETCH, the publisher is unable to determine the status of the next Object in the requested range.
- EXPIRED_AUTH_TOKEN (0x7):
-
The authorization token for the request has expired.
- EXCESSIVE_LOAD (0x9):
-
The endpoint is overloaded and is resetting this stream.
- MALFORMED_TRACK (0x12):
-
A relay publisher detected that the track was malformed (see Section 2.4.2).