fn encode_parameters_in(
parameters: &[KeyValuePair],
buf: &mut impl BufMut,
message_namespace: bool,
) -> Result<(), CodecError>Expand description
Encode a count-prefixed parameter list with delta-encoded Types, refusing
every list decode_parameters_in would refuse over a value.
The duplicate rule is the sender’s own and does not consult a registry, so
there is nothing for the two namespaces to disagree about there. The value
rules are the reader’s, and message_namespace says which of them apply for
the same reason it does on the decode side: a setup 0x21 or 0x22 is not the
parameter the version-specific rules describe.
They are applied on the way out because each of them states a close. A value that is not what its Type defines is one the receiver must close the session over, so writing it is not a way to send it — the sender’s first sign of trouble would be the session going.
§The one rule that is decode-only, and why
check_message_parameters_are_known is not called here. That is the rule
whose sentence has a second half: Section 9.2 says “All Message Parameters MUST be defined
in the negotiated version of MOQT or negotiated via Setup Parameters”, and
it is that second clause the neighbouring function’s own doc says a codec
cannot settle — it describes an extension the two endpoints agreed on in
their SETUP, which this codec does not implement.
A decoder has to resolve that the conservative way. It was handed bytes, it
has no record of what the two peers negotiated, and the draft’s answer to a
parameter it cannot name is a close. An encoder is in the opposite position:
its caller is the endpoint that negotiated, and is the only party that
knows the type was agreed. Refusing here would make a negotiated extension
unsendable through this codec — and unreplayable, which is the same argument
data_stream.rs’s extensions_permitted_at makes about a rule that
addresses the receiving endpoint: a writer that refused it could not
reproduce a capture containing one.
Draft-17 takes the same position in the same place, with a fallback arm in
its encode_parameters that writes an unknown Type as a plain even/odd pair
while its decoder answers UnknownMessageParameter for the same number.
This is a difference between the two directions, not between the drafts.
It is also a gated one rather than an accident.
tests/unknown_message_parameter.rs’s an_unknown_message_parameter_is_refused
drives exactly this asymmetry on this draft: it hands the encoder type 0x41,
requires it to be written — its expect says in so many words that the
encoder writes the parameters it is given — and requires the decoder to
answer UnknownMessageParameter. A check here would fail that test on the
line before the one it is about.