Skip to content
Open
Changes from 27 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
25a2c7e
Put PUBLISH_NAMESPACE on its own bidi stream and allow only subscribi…
ianswett Oct 31, 2025
89e380b
Update draft-ietf-moq-transport.md
ianswett Nov 1, 2025
abafb02
Update draft-ietf-moq-transport.md
ianswett Nov 1, 2025
1a6fe39
Change to Track Namespace Suffix
ianswett Nov 1, 2025
7e16420
Fix whitespace and a trailing sentence.
ianswett Nov 1, 2025
a30cd61
Remove UNSUBSCRIBE_NAMESPACE
ianswett Nov 1, 2025
4b21ba2
Ref conflict
ianswett Nov 1, 2025
9c8cc68
Update draft-ietf-moq-transport.md
ianswett Nov 1, 2025
9ae1039
Alan's suggestion
ianswett Nov 1, 2025
c71ae77
Update draft-ietf-moq-transport.md
ianswett Nov 3, 2025
a31e5b3
Update draft-ietf-moq-transport.md
ianswett Nov 3, 2025
b5e6711
Change the codepoint of NAMESPACE to 0x8
ianswett Nov 3, 2025
0132f29
Fix table formatting
ianswett Nov 3, 2025
2465b19
Describe the case when a SUBSCRIBE_NAMESPACE arrives first
ianswett Nov 3, 2025
bd3ebc8
Add NAMESPACE_DONE
ianswett Nov 3, 2025
d58eff5
Merge branch 'main' into ianswett-streamy-namespaces
ianswett Nov 4, 2025
9e37747
Update draft-ietf-moq-transport.md
ianswett Nov 4, 2025
13a3a6f
Merge branch 'main' into ianswett-streamy-namespaces
ianswett Nov 13, 2025
2e23347
Fix subscribe-ns references
ianswett Nov 13, 2025
c5e7fbf
Update draft-ietf-moq-transport.md
ianswett Nov 18, 2025
49d3c32
Update draft-ietf-moq-transport.md
ianswett Nov 20, 2025
4a76892
Update draft-ietf-moq-transport.md
ianswett Nov 20, 2025
9949625
Update draft-ietf-moq-transport.md
afrind Nov 21, 2025
b969d51
Update draft-ietf-moq-transport.md
afrind Nov 21, 2025
24b2efe
Merge branch 'main' into ianswett-streamy-namespaces
ianswett Nov 22, 2025
6aba921
Merge branch 'main' into ianswett-streamy-namespaces
ianswett Nov 26, 2025
e6a6368
Merge branch 'main' into ianswett-streamy-namespaces
ianswett Dec 1, 2025
fe00420
Update draft-ietf-moq-transport.md
ianswett Dec 1, 2025
a0e6b3b
Update draft-ietf-moq-transport.md
ianswett Dec 2, 2025
8d39c86
Reflow
ianswett Dec 2, 2025
35695e0
Update draft-ietf-moq-transport.md
ianswett Dec 2, 2025
17e0d0a
Merge branch 'main' into ianswett-streamy-namespaces
ianswett Dec 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 87 additions & 51 deletions draft-ietf-moq-transport.md
Original file line number Diff line number Diff line change
Expand Up @@ -724,10 +724,14 @@ The first stream opened is a client-initiated bidirectional control stream where
the endpoints exchange Setup messages ({{message-setup}}), followed by other
messages defined in {{message}}.

This specification 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 close the session as a `PROTOCOL_VIOLATION` if
it receives a second bidirectional stream.
This specification only specifies two uses of bidirectional streams, the control
stream and SUBSCRIBE_NAMESPACE. Objects are sent on unidirectional streams.

A unidirectional stream or bidirectional stream containing a SUBSCRIBE_NAMESPACE
could arrive prior to the control stream, in which case the data SHOULD be buffered
until the control stream arrives and setup is complete.
If an implementation does not want to buffer, it MAY reset other bidirectional
streams before the session and control stream are established.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR does not really provide a good way for implementations to figure out what stream is the control stream.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a type identifier at the beginning of the control stream, which is the SETUP messages.


The 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
Expand Down Expand Up @@ -1156,26 +1160,28 @@ The syntax of these messages is described in {{message}}.

If the subscriber is aware of a namespace of interest, it can send
SUBSCRIBE_NAMESPACE to publishers/relays it has established a session with. The
recipient of this message will send any relevant PUBLISH_NAMESPACE,
PUBLISH_NAMESPACE_DONE or PUBLISH messages for that namespace, or more specific
part of that namespace. This includes echoing back PUBLISH or PUBLISH_NAMESPACE
messages to the endpoint that sent them. If an endpoint accepts its own
PUBLISH, this behaves as self-subscription described in {{subscriptions}}.

A publisher MUST send exactly one REQUEST_OK or
REQUEST_ERROR in response to a SUBSCRIBE_NAMESPACE. The subscriber
SHOULD close the session with a protocol error if it detects receiving more than
one.
recipient of this message will send any relevant NAMESPACE,
NAMESPACE_DONE or PUBLISH messages for that namespace, or more specific
part of that namespace. This includes echoing back published Tracks and/or Track
Namespaces under the SUBSCRIBE_NAMESPACE prefix to the endpoint that sent them.
If an endpoint accepts its own PUBLISH, this behaves as self-subscription described
in {{subscriptions}}.

The subscriber sends SUBSCRIBE_NAMESPACE on a new bidirectional stream and the
publisher MUST send REQUEST_OK or REQUEST_ERROR as the first message on the
bidirectional stream in response to a SUBSCRIBE_NAMESPACE. The subscriber
SHOULD close the session with a protocol error if it detects receiving more
than one.

The receiver of a REQUEST_OK or REQUEST_ERROR ought to
forward the result to the application, so the application can decide which other
publishers to contact, if any.

An UNSUBSCRIBE_NAMESPACE withdraws a previous SUBSCRIBE_NAMESPACE. It does not
prohibit original publishers from sending further PUBLISH_NAMESPACE or PUBLISH
messages, but relays MUST NOT send any further PUBLISH messages to a client
without knowing the client is interested in and authorized to receive the
content.
A SUBSCRIBE_NAMESPACE can be cancelled by closing the stream with
either a FIN or RESET_STREAM. Cancelling does not prohibit original publishers
Comment on lines +1180 to +1181
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A SUBSCRIBE_NAMESPACE can be cancelled by closing the stream with
either a FIN or RESET_STREAM. Cancelling does not prohibit original publishers
A SUBSCRIBE_NAMESPACE can be cancelled by the creator the stream, by closing the stream with
either a FIN or RESET_STREAM. Cancelling does not prohibit original publishers

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be cancelled by either the creator or the peer.

from sending further PUBLISH_NAMESPACE or PUBLISH messages, but relays MUST NOT
send any further PUBLISH messages to a client without knowing the client is
interested in and authorized to receive the content.

## Publishing Namespaces

Expand Down Expand Up @@ -1639,14 +1645,16 @@ The following Message Types are defined:
|-------|-----------------------------------------------------|
| 0x6 | PUBLISH_NAMESPACE ({{message-pub-ns}}) |
|-------|-----------------------------------------------------|
| 0x8 | NAMESPACE ({{message-namespace}}) |
|-------|-----------------------------------------------------|
| 0x9 | PUBLISH_NAMESPACE_DONE ({{message-pub-ns-done}}) |
|-------|-----------------------------------------------------|
| 0xE | NAMESPACE_DONE ({{message-namespace-done}}) |
|-------|-----------------------------------------------------|
| 0xC | PUBLISH_NAMESPACE_CANCEL ({{message-pub-ns-cancel}})|
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like we're repeating the mistake we had in HTTP/3 where we are adding streams without type identifiers and then have some semantic rules about what messages can appear where. Can we have an explicit type for bidi streams instead?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vasilvv the current PR is adequate, in that it either starts with CLIENT_SETUP or it starts with SUBSCRIBE_NAMESPACE. This is extensible since have varint frame type so have unlimited ways to start streams. It seems like it would be fairly redundant to have:

SETUP_STREAM
CLIENT_SETUP

and

SUB_NS_STREAM
SUB_NS

Right?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the counter-argument is if in the future you want to start a stream with a non-message. This is what webtransport ran into and it got a little ugly, but ultimately resolved it by reserving a frame type and giving it new semantics.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I definitely don't want to repeat that mistake, but in this case we are adding type/message identifiers.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see that this works, but I don't see why we would want to do that. If there are two types of streams, and they have basically disjoint message type list, why do we want them to have the same format?

|-------|-----------------------------------------------------|
| 0x11 | SUBSCRIBE_NAMESPACE ({{message-subscribe-ns}}) |
|-------|-----------------------------------------------------|
| 0x14 | UNSUBSCRIBE_NAMESPACE ({{message-unsub-ns}}) |
|-------|-----------------------------------------------------|

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
Expand Down Expand Up @@ -2965,6 +2973,27 @@ PUBLISH_NAMESPACE Message {

* Parameters: The parameters are defined in {{version-specific-params}}.

## NAMESPACE {#message-namespace}

The NAMESPACE message is similar to the PUBLISH_NAMESPACE message, except
it is sent on the response stream of a SUBSCRIBE_NAMESPACE request.
All NAMESPACE messages are in response to a SUBSCRIBE_NAMESPACE, so only
the namespace tuples after the 'Track Namespace Prefix' are included
in the 'Track Namespace Suffix'.

~~~
NAMESPACE Message {
Type (i) = 0x8,
Length (16),
Track Namespace Suffix (..),
}
~~~
{: #moq-transport-ns-format title="MOQT NAMESPACE Message"}

* Track Namespace Suffix: Specifies the final portion of a track's
namespace as defined in {{track-name}} after removing namespace tuples included in
'Track Namespace Prefix' {message-subscribe-ns}.

## PUBLISH_NAMESPACE_DONE {#message-pub-ns-done}

The publisher sends the `PUBLISH_NAMESPACE_DONE` control message to indicate its
Expand All @@ -2983,6 +3012,27 @@ PUBLISH_NAMESPACE_DONE Message {
* Request ID: The Request ID of the PUBLISH_NAMESPACE that is being terminated. See
{{message-subscribe-req}}.

## NAMESPACE_DONE {#message-namespace-done}

The publisher sends the `NAMESPACE_DONE` control message to indicate its
intent to stop serving new subscriptions for tracks within the provided Track
Namespace. All NAMESPACE_DONE messages are in response to a SUBSCRIBE_NAMESPACE,
so only the namespace tuples after the 'Track Namespace Prefix' are included
in the 'Track Namespace Suffix'.

~~~
NAMESPACE_DONE Message {
Type (i) = 0xE,
Length (16),
Track Namespace Suffix (..)
}
~~~
{: #moq-transport-ns-done-format title="MOQT NAMESPACE_DONE Message"}

* Track Namespace Suffix: Specifies the final portion of a track's
namespace as defined in {{track-name}}. The namespace begins with the
'Track Namespace Prefix' specified in {message-subscribe-ns}.

## PUBLISH_NAMESPACE_CANCEL {#message-pub-ns-cancel}

The subscriber sends an `PUBLISH_NAMESPACE_CANCEL` control message to
Expand Down Expand Up @@ -3012,16 +3062,18 @@ PUBLISH_NAMESPACE_CANCEL Message {

## SUBSCRIBE_NAMESPACE {#message-subscribe-ns}

The subscriber sends the SUBSCRIBE_NAMESPACE control message to a publisher to
request the current set of matching published namespaces and `Established`
subscriptions, as well as future updates to the set.
The subscriber sends a SUBSCRIBE_NAMESPACE control message on a new
bidirectional stream to a publisher to request the current set of matching
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you distinguish the control stream from this stream?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a new bidi stream and it starts with the SUBSCRIBE_NAMESPACE message.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So if the first stream I receive starts with SUBSCRIBE_NAMESPACE, I hold it pending one that starts with CLIENT_SETUP?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without 0RTT clearly described, which it isn't today, I'm unsure how that could happen?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah @afrind if right.

It depends on if the QUIC library returns streams in stream_id order, but any bidirectional stream should be buffered until the CLIENT_SETUP is processed. In fact, the same is true for any unidirectional streams if pipelining a PUBLISH is valid (debatable with max_request_id), but that's a lot easier to implement.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I understand the issue now. Yes, I can call out this potential issue.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PTAL at 2465b19

published namespaces and/or `Established` subscriptions, as well as future
updates to the set.

~~~
SUBSCRIBE_NAMESPACE Message {
Type (i) = 0x11,
Length (16),
Request ID (i),
Track Namespace Prefix (..),
Subscribe Options (i),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can one send 2 subscribe_namespace with 2 different options

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this falls under duplicate prefix text elsewhere.

Number of Parameters (i),
Parameters (..) ...
}
Expand All @@ -3040,15 +3092,20 @@ SUBSCRIBE_NAMESPACE Message {
Track Namespace Prefix consisting of 0 or greater than than 32 Track Namespace
Fields, it MUST close the session with a `PROTOCOL_VIOLATION`.

* Subscribe Options: Allows subscribers to request PUBLISH (0x00),
NAMESPACE (0x01), or both (0x02) for a given SUBSCRIBE_NAMESPACE request.

* Parameters: The parameters are defined in {{version-specific-params}}.

The publisher will respond with REQUEST_OK or
REQUEST_ERROR. If the SUBSCRIBE_NAMESPACE is successful, the publisher will
immediately forward existing PUBLISH_NAMESPACE and PUBLISH messages that match
the Track Namespace Prefix that have not already been sent to this subscriber.
If the set of matching PUBLISH_NAMESPACE messages changes, the publisher sends
the corresponding PUBLISH_NAMESPACE or PUBLISH_NAMESPACE_DONE message.
The publisher will respond with REQUEST_OK or REQUEST_ERROR on the response half
of the stream. If the SUBSCRIBE_NAMESPACE is successful, the publisher will
send matching NAMESPACE messages on the response stream if they are requested.
If it is an error, the stream will be immediately closed via FIN.
Also, any matching PUBLISH messages without an `Established` Subscription will be
sent on the control stream. When there are changes to the namespaces or
subscriptions being published and the subscriber is subscribed to them,
the publisher sends the corresponding NAMESPACE, PUBLISH_NAMESPACE_DONE,
or PUBLISH messages.

A subscriber cannot make overlapping namespace subscriptions on a single
session. Within a session, if a publisher receives a SUBSCRIBE_NAMESPACE with a
Expand All @@ -3072,27 +3129,6 @@ set the FORWARD parameter to 1, or indicate that value by omitting the parameter
(see {{subscriptions}}).


## UNSUBSCRIBE_NAMESPACE {#message-unsub-ns}

A subscriber issues a `UNSUBSCRIBE_NAMESPACE` message to a publisher indicating
it is no longer interested in PUBLISH_NAMESPACE, PUBLISH_NAMESPACE_DONE and
PUBLISH messages for the specified track namespace prefix.

The format of `UNSUBSCRIBE_NAMESPACE` is as follows:

~~~
UNSUBSCRIBE_NAMESPACE Message {
Type (i) = 0x14,
Length (16),
Request ID (i),
}
~~~
{: #moq-transport-unsub-ann-format title="MOQT UNSUBSCRIBE_NAMESPACE Message"}

* Request ID: The Request ID of the SUBSCRIBE_NAMESPACE
({{message-subscribe-ns}}) being cancelled by this message.


# Data Streams and Datagrams {#data-streams}

A publisher sends Objects matching a subscription on Data Streams or Datagrams
Expand Down