Code change:
6.2.2.1. <del> The ROLE parameter (key 0x00) allows the client to specify what roles it expects the parties to have in the MOQT connection.  It has three possible values, which are of type varint: </del> <ins> The ROLE parameter (key 0x00) allows each endpoint to independently specify what funnctionality they support for the session.  It has three possible values, which are of type varint: </ins> <del> The client MUST send a ROLE parameter with one of the three values specified above.  The server MUST close the session if the ROLE parameter is missing, is not one of the three above-specified values, or it is different from what the server expects based on the application. </del> <ins> Both endpoints MUST send a ROLE parameter with one of the three values specified above.  Both endpoints MUST close the session if the ROLE parameter is missing or is not one of the three above-specified values. </ins> 6.2.2.2.

Related discussion:
text: Add some normative text and requires both client and server to send their role. I can also see the argument for removing this entirely, but it's in the current draft, so if we're going to keep it, I'd like to define it better.
Having a flag in SETUP doesn't stop from someone sending unsupported messages. A faulty implementation or intentionally malicious endpoint can send unsupported messages. A receiver should be prepared to handle unsupported messages regardless.
Right, an implementation is still going to crash if it receives an unsupported message, but there's a difference between signaling that upfront and yolo. A one-sided implementation will look something like this: The purpose of the ROLE parameter is to avoid accidentally triggering that default, as it will close the connection. For example, I absolutely want to have a way to get per-viewer feedback: a track produced by each viewer. Without this ROLE field, a viewer might cause a crash if it sends an to the server, or the server might cause a crash if it sends a to the viewer. It will only work if both endpoints explicitly flag . The only alternative to the ROLE field is to implement the entire protocol, but that's unnecessarily restrictive. Take HTTP for example, it's almost taken for granted that an implementation is for a client or a server, but rarely both. I imagine that will also be the case with MoQ with the sole exception of relays. OBS is not going to implement subscribing, and VLC is not going to implement publishing. Even in my URL library that does support both modes, I ran into a deadlock because of ROLE=both. My publisher was not consuming ANNOUNCE messages because it was not expecting them. Explicitly signaling ROLE=publisher would have prevented this, making it a protocol violation to send half of the messages in the draft.
A resilient implementation state machine will be something like Since for unsupported messages, you don't want a protocol action as it will be DOS surface, for example. Also, Many of the conferencing examples will mostly always be send and receive by default. Our client for example does pub and subscribe always. I personally feel the implementation constraints are resolvable and I feel still unconvinced for a ROLE parameter.
Heh, please don't do that. This is exactly why we have version/extension negotiation; not supporting a message after negotiating it is a protocol violation.