Code change:
and . if messages must be known, explicit message lengths are redundanct except for OBJECT and messages with parameters. This also eliminates a whole class of potential errors where the message length does not match the actual parsing of the message. Not checking this -- and not have any message type be potentially zero-length -- greatly simplifies the parser.
And trying to use messages without negotiating an extension/version just won't work for MoQ. We're designing a protocol explicitly for relays so you do need relay cooperation, or at the very least some information on how to forward unknown messages.
Also I love that you're using "parameter count" instead of "parameter size (bytes)". It makes it much easier to build a streaming encoder/decoder without allocating temporary buffers.
I thought we agreed to allow extensibility by allowing new message types to be created.
Like to see us agree on a extensibility strategy before deciding what to do on this. We also need to decide if messages can have optional fields
We have version negotiation, and presumably we'll have extension negotiation too. What's the use-case for adding new messages without negotiating them? The problem is that we can't relay unknown messages, so all it takes is a single uncooperative relay on the chain to shallow them. I think we need explicit negotiation as a result.
If we have extension negotiation, I agree. But if our extension negotiation mechanism relies on not getting an error on unknown messages .... PR is wrong place to discuss this but I think what I would like to see is a good way to do extension negotiation, and then like you have here, error on any message that is not part of a negotiated extension. I think I would lean that way if we had an extension negotiation mechanism. Note this is the opposite direction of HTTP which is often our model for things. HTTP just skips past unknown headers.
Fail, or pass over?
IMO fail. We have version negotiation and should add extension negotiation so it should never happen. The problem with ignoring messages is that MoqTransport is designed for relays. If an intermediate relay doesn't support a message, it then gets silently dropped. At the very least we need enough information on where to forward unknown messages.
If it's going to Fail, then most Message types don't need a length field at all (OBJECT and ANNOUNCE_OK would be the exceptions)
Individual Comment: Is there any reasonable action a relay can take on an unknown message, besides discarding it? See how HTTP recently added a "Capsule" concept which is an envelop with a default relay action of "forward", which allows for end-to-end extensions without upgrading all intermediaries. Given that MoQ handles forwarding on a per-track level, I think there probably isn't any way to generically forward a message that isn't associated with an active subscription. That said, it makes me wonder if we want to add a capsule-like extension message, or does the existing OBJECT definition give enough flexibility?
Yeah exactly. It's impossible to know the intended destination of an unknown message with the current ANNOUNCE/SUBSCRIBE mechanisms. I'm using the (as the track namespace) and instead of . This actually does let you forward unknown messages from publisher -> subscribers and subscribers -> publisher since each session is associated with only a single track namespace. Session pooling is always the issue...
I think we need extensibility. We want the protocol to be extensible so a given server might support extension A and C and another server supports extension A and B. It is very hard to do that using just a version number.
Rereading all this - II think this whole issue just need to be uplevel to what is the extensibility strategy then this detailed part of it will be easy.
There was support for not requiring a length and failing on unknown message types at the Interim, so the intent is to land PR after review.
LG. The agreement at the interim was to follow up with separate frame types for object with and without length, but do that in a separate PR.I love it. It also means you can implement streaming encoders. Prefixing each message with the length required a temporary buffer or 2nd pass to compute the length.LGTM

Related discussion:
text: Both unidirectional and bidirectional QUIC streams contain sequences of length-delimited messages. <del> The Message Length field contains the length of the Message Payload field in bytes.  A length of 0 indicates the message is unbounded and continues until the end of the stream. </del> <ins> An endpoint that receives an unknown message type MUST close the connection. </ins> 6.1.