A second approach that was considered but not chosen was to decouple the management of the media control objects from session descriptions, instead offering APIs that would control each component <del> directly.  This was rejected based on a feeling that requiring </del>  exposure of this level of complexity to the application programmer would not be beneficial; it would result in an API where even a simple example would require a significant amount of code to

Section 1.2 second paragraph - "This was rejected based on a feeling". Can you write something that speaks to consensus here? "Based on a feeling" isn't quite right. Maybe "using the argument"?
Sure.
LGTM

A second approach that was considered but not chosen was to decouple the management of the media control objects from session descriptions, instead offering APIs that would control each component  <ins> directly.  This was rejected based on the argument that requiring </ins> exposure of this level of complexity to the application programmer would not be beneficial; it would result in an API where even a simple example would require a significant amount of code to


of codecs sent to a remote party indicates what the local side is willing to receive, which, when intersected with the set of codecs the remote side supports, specifies what the remote side should send. <del> However, not all parameters follow this rule; for example, the fingerprints RFC8122 sent to a remote party are calculated based on the local certificate(s) offered; the remote party MUST either accept these parameters or reject them altogether, with no option to choose different values. </del>  In addition, various RFCs put different conditions on the format of offers versus answers.  For example, an offer may propose an

Second paragraph of 3.2, last sentence: at "these parameters or reject them" - "these" and "them" have ambiguous antecedents. It's not clear if you are trying to point to the parameters that don't follow the earlier stated rule, or all parameters. The sentence is complex. Splitting it up and finding a way to avoid the need for the semicolon will likely make it easier to say what you mean.
I agree that this is messy. Editorial.
LGTMLG with comment

of codecs sent to a remote party indicates what the local side is willing to receive, which, when intersected with the set of codecs the remote side supports, specifies what the remote side should send.  <ins> However, not all parameters follow this rule; some parameters are declarative and the remote side MUST either accept them or reject them altogether.  An example of such a parameter is the DTLS fingerprints RFC8122, which are calculated based on the local certificate(s) offered, and are not subject to negotiation. </ins> In addition, various RFCs put different conditions on the format of offers versus answers.  For example, an offer may propose an


security considerations for this document. While formally the JSEP interface is an API, it is better to think of <del> it is an Internet protocol, with the JS being untrustworthy from the perspective of the endpoint.  Thus, the threat model of RFC3552 applies.  In particular, JS can call the API in any order and with any inputs, including malicious ones.  This is particularly relevant when we consider the SDP which is passed to setLocalDescription(). While correct API usage requires that the application pass in SDP which was derived from createOffer() or createAnswer(), there is no guarantee that applications do so.  The JSEP implementation MUST be prepared for the JS to pass in bogus data instead. Conversely, the application programmer needs to be aware that the JS does not have complete control of endpoint behavior.  One case that bears particular mention is that editing ICE candidates out of the SDP or suppressing trickled candidates does not have the expected behavior: implementations will still perform checks from those candidates even if they are not sent to the other side.  Thus, for instance, it is not possible to prevent the remote peer from learning your public IP address by removing server reflexive candidates. Applications which wish to conceal their public IP address should instead configure the ICE agent to use only relay candidates. </del>  9.

From "Opsdir last call review of draft-ietf-rtcweb-jsep-21" A minor observation, not even a nit, is that the text in the Security Considerations "While formally the JSEP interface is an API, it is better to think of it is an Internet protocol, with the JS being untrustworthy from the perspective of the endpoint. " could be more clear.
I have no idea what to do with this. Obviously I thought it was clear when wrote it, and still do.
This is the only place in the document where we use "JS". I think it would be good to spell out "JavaScript", and potentially use "application JavaScript" in the first usage. Finally, I think we should use "implementation" rather than "endpoint" in this para.
LGTM

security considerations for this document. While formally the JSEP interface is an API, it is better to think of  <ins> it is an Internet protocol, with the application JavaScript being untrustworthy from the perspective of the JSEP implementation.  Thus, the threat model of RFC3552 applies.  In particular, JavaScript can call the API in any order and with any inputs, including malicious ones.  This is particularly relevant when we consider the SDP which is passed to setLocalDescription().  While correct API usage requires that the application pass in SDP which was derived from createOffer() or createAnswer(), there is no guarantee that applications do so. The JSEP implementation MUST be prepared for the JavaScript to pass in bogus data instead. Conversely, the application programmer needs to be aware that the JavaScript does not have complete control of endpoint behavior.  One case that bears particular mention is that editing ICE candidates out of the SDP or suppressing trickled candidates does not have the expected behavior: implementations will still perform checks from those candidates even if they are not sent to the other side.  Thus, for instance, it is not possible to prevent the remote peer from learning your public IP address by removing server reflexive candidates.  Applications which wish to conceal their public IP address should instead configure the ICE agent to use only relay candidates. </ins> 9.


header extension defined in I-D.ietf-mmusic-sdp-bundle- negotiation, Section 11.  An "a=msid" line, as specified in I-D.ietf-mmusic-msid, Section 2. An "a=sendrecv" line, as specified in RFC3264, Section 5.1.

lgtm
I think the dummy candidates should be v4 not v6 as many things just don't do v6 but other than that looks reasonable. You don't really need to specify the address at all the the lines when you don't know the port can just look like a=rtcp:9 With no IP address or family
NAME The IP6 vs IP4 is described in URL, so this isn't a JSEP thing. Given that this is part of the trickle spec, and only trickle endpoints will get these candidates, I don't see any problem. As to whether a=rtcp can just have the port, consider the case where RTP candidates have been gathered, but no RTCP candidates have yet been gathered. In that case, we certainly need to have the full a=rtcp:9 IP6 ::, so I think it makes sense to include it in all cases where RTCP candidates have not yet been gathered.
I don't care much about this so fine if not change is made. I agree it is a trickle-ice draft issue. However, when I read that, it seems that it would be fine with "a=rtcp:9" with no address. It seems the reason we used 9 was to provide something that stuff that did not implement trickle ICE would not barf on. I have no tested but an address of "IP6 ::" seems like something that has high odds of stuff barfing on. Anyways, no big deal with me one way or the other. On Sep 12, 2014, at 7:49 PM, Justin Uberti EMAIL wrote:
Only trickle endpoints will even receive an offer with these dummy addresses and ports, so compatibility with old non-trickle stuff is not an issue. LMK if you have any further concerns, otherwise I will merge later today.
I concur that we should merge this. , Justin Uberti EMAIL wrote:
On Sep 18, 2014, at 9:34 AM, Justin Uberti EMAIL wrote: ah - my bad - makes sense Merge it !

header extension defined in I-D.ietf-mmusic-sdp-bundle- negotiation, Section 11. <ins> An "a=rtcp" line, as specified in RFC3605, Section 2.1, containing the dummy value "9 IN IP6 ::", because no candidates have yet been gathered. </ins> An "a=msid" line, as specified in I-D.ietf-mmusic-msid, Section 2. An "a=sendrecv" line, as specified in RFC3264, Section 5.1.


Each "m=" and c=" line MUST be filled in with the port and address of the default candidate for the m= section, as described in <del> RFC5245, Section 4.3.  If no candidates have yet been gathered, the dummy values MUST be used, as described above.  [TODO: update profile UDP/TCP per default candidate] </del>  Each "a=mid" line MUST stay the same.

Each "m=" and c=" line MUST be filled in with the port and address of the default candidate for the m= section, as described in  <ins> RFC5245, Section 4.3.  Each "a=rtcp" attribute line MUST also be filled in with the port and address of the appropriate default candidate, either the default RTP or RTCP candidate, depending on whether RTCP multiplexing is currently active or not.  Note that if RTCP multiplexing is being offered, but not yet active, the default RTCP candidate MUST be used, as indicated in RFC5761, section 5.1.3.  In each case, if no candidates of the desired type have yet been gathered, dummy values MUST be used, as described above.  [TODO: update profile UDP/TCP per default candidate] </ins> Each "a=mid" line MUST stay the same.


Section 9.1.  The "mid" value MUST match that specified in the offer.  If a local MediaStreamTrack has been associated, an "a=msid" line, as specified in I-D.ietf-mmusic-msid, Section 2.

Section 9.1.  The "mid" value MUST match that specified in the offer. <ins> An "a=rtcp" line, as specified in RFC3605, Section 2.1, containing the dummy value "9 IN IP6 ::", because no candidates have yet been gathered. </ins> If a local MediaStreamTrack has been associated, an "a=msid" line, as specified in I-D.ietf-mmusic-msid, Section 2.


JSEP's handling of session descriptions is simple and straightforward.  Whenever an offer/answer exchange is needed, the <del> initiating side creates an offer by calling a createOffer() API.  The </del>  application then uses that offer to set up its local config via the <del> setLocalDescription() API.  The offer is finally sent off to the remote side over its preferred signaling mechanism (e.g., WebSockets); upon receipt of that offer, the remote party installs it using the setRemoteDescription() API. </del>  To complete the offer/answer exchange, the remote party uses the <del> createAnswer() API to generate an appropriate answer, applies it using the setLocalDescription() API, and sends the answer back to the </del>  initiator over the signaling channel.  When the initiator gets that <del> answer, it installs it using the setRemoteDescription() API, and </del>  initial setup is complete.  This process can be repeated for additional offer/answer exchanges.

Various fixes for 60.2: Removed parens from API names, removed comment. - put the term stable in quotes, removed comment. - put the term sess-id in angle brackets to match SDP spec, removed comment. - made the tls-id attribute consistent with other SDP attributes, removed comment. - removed quotes from IceRestart option, removed comment.

"IceRestart" option / IceRestart option Justin: LGTM
tls-id value / "a=tls-id" value Justin: The source RFC seems to prefer "tls-id" when discussing values.
During the editing of the Cluster 238 docs, it was decided that it's author's choice when formatting SDP attributes. Although RFC 8842 uses the format '"tls-id" attribute', this document more consistently uses "a=attribute-name" format for SDP attributes, which is the format that the SDP spec [RFC8866] uses. I'll update this document to consistently use "a=tls-id"
sess-id / (Section 5.2.1, second bullet item) Justin: LGTM
the stable state (1 instance) / the "stable" state (3 instances) >(Also, should 'the previous stable state' be 'a previous stable state' (per Section 5.7) or 'the previous "stable" state'?) Justin: The quoted form is preferred, including the case of "previous stable state".
[Breaking up issue /60 into smaller bites] The following terms appear to be used inconsistently in this document. Please let us know which form is preferred. Justin: There seems to be a pretty clear preponderance for the non-parenthetical form, so let's keep that. W3C also does not use (). Jean: We'll remove the parens (camelCase is sufficient formatting).

JSEP's handling of session descriptions is simple and straightforward.  Whenever an offer/answer exchange is needed, the  <ins> initiating side creates an offer by calling a createOffer API.  The </ins> application then uses that offer to set up its local config via the  <ins> setLocalDescription API.  The offer is finally sent off to the remote side over its preferred signaling mechanism (e.g., WebSockets); upon receipt of that offer, the remote party installs it using the setRemoteDescription API. </ins> To complete the offer/answer exchange, the remote party uses the  <ins> createAnswer API to generate an appropriate answer, applies it using the setLocalDescription API, and sends the answer back to the </ins> initiator over the signaling channel.  When the initiator gets that  <ins> answer, it installs it using the setRemoteDescription API, and </ins> initial setup is complete.  This process can be repeated for additional offer/answer exchanges.


using SIP for signaling, if one offer is sent and is then canceled using a SIP CANCEL, another offer can be generated even though no answer was received for the first offer.  To support this, the JSEP <del> media layer can provide an offer via the createOffer() method whenever the JavaScript application needs one for the signaling.  The answerer can send back zero or more provisional answers and then finally end the offer/answer exchange by sending a final answer.  The state machine for this is as follows: </del>  Aside from these state transitions, there is no other difference between the handling of provisional ("pranswer") and final ("answer")

using SIP for signaling, if one offer is sent and is then canceled using a SIP CANCEL, another offer can be generated even though no answer was received for the first offer.  To support this, the JSEP  <ins> media layer can provide an offer via the createOffer method whenever the JavaScript application needs one for the signaling.  The answerer can send back zero or more provisional answers and then finally end the offer/answer exchange by sending a final answer.  The state machine for this is as follows: </ins> Aside from these state transitions, there is no other difference between the handling of provisional ("pranswer") and final ("answer")


in RFC5888.  addTrack attempts to minimize the number of transceivers as follows: if the PeerConnection is in the "have-remote-offer" state, the track will be attached to the first compatible transceiver <del> that was created by the most recent call to setRemoteDescription() and does not have a local track.  Otherwise, a new transceiver will be created, as described in sec.addTransceiver. </del>  4.1.3.

in RFC5888.  addTrack attempts to minimize the number of transceivers as follows: if the PeerConnection is in the "have-remote-offer" state, the track will be attached to the first compatible transceiver  <ins> that was created by the most recent call to setRemoteDescription and does not have a local track.  Otherwise, a new transceiver will be created, as described in sec.addTransceiver. </ins> 4.1.3.


"offer" indicates that a description should be parsed as an offer; said description may include many possible media configurations.  A description used as an "offer" may be applied any time the <del> PeerConnection is in a stable state or applied as an update to a </del>  previously supplied but unanswered "offer". "pranswer" indicates that a description should be parsed as an

"offer" indicates that a description should be parsed as an offer; said description may include many possible media configurations.  A description used as an "offer" may be applied any time the  <ins> PeerConnection is in a "stable" state or applied as an update to a </ins> previously supplied but unanswered "offer". "pranswer" indicates that a description should be parsed as an


voicemail). "rollback" is a special session description type implying that the <del> state machine should be rolled back to the previous stable state, as described in sec.rollback.  The contents MUST be empty. </del>  4.1.8.1.

voicemail). "rollback" is a special session description type implying that the  <ins> state machine should be rolled back to the previous "stable" state, as described in sec.rollback.  The contents MUST be empty. </ins> 4.1.8.1.


after setRemoteDescription, decides it does not want to accept the new parameters and sends a reject message back to the offerer.  Now, the offerer, and possibly the answerer as well, needs to return to a <del> stable state and the previous local/remote description.  To support </del>  this, we introduce the concept of "rollback", which discards any proposed changes to the session, returning the state machine to the <del> stable state.  A rollback is performed by supplying a session </del>  description of type "rollback" with empty contents to either setLocalDescription or setRemoteDescription.

after setRemoteDescription, decides it does not want to accept the new parameters and sends a reject message back to the offerer.  Now, the offerer, and possibly the answerer as well, needs to return to a  <ins> "stable" state and the previous local/remote description.  To support </ins> this, we introduce the concept of "rollback", which discards any proposed changes to the session, returning the state machine to the  <ins> "stable" state.  A rollback is performed by supplying a session </ins> description of type "rollback" with empty contents to either setLocalDescription or setRemoteDescription.


5.2.3.1. <del> If the "IceRestart" option is specified, with a value of "true", the </del>  offer MUST indicate an ICE restart by generating new ICE ufrag and pwd attributes, as specified in RFC8839.  If this option is specified on an initial offer, it has no effect (since a new ICE ufrag and pwd

5.2.3.1.  <ins> If the IceRestart option is specified, with a value of "true", the </ins> offer MUST indicate an ICE restart by generating new ICE ufrag and pwd attributes, as specified in RFC8839.  If this option is specified on an initial offer, it has no effect (since a new ICE ufrag and pwd


A rollback may be performed if the PeerConnection is in any state except for "stable".  This means that both offers and provisional answers can be rolled back.  Rollback can only be used to cancel <del> proposed changes; there is no support for rolling back from a stable state to a previous stable state.  If a rollback is attempted in the "stable" state, processing MUST stop and an error MUST be returned. Note that this implies that once the answerer has performed setLocalDescription with its answer, this cannot be rolled back. </del>  The effect of rollback MUST be the same regardless of whether setLocalDescription or setRemoteDescription is called.

A rollback may be performed if the PeerConnection is in any state except for "stable".  This means that both offers and provisional answers can be rolled back.  Rollback can only be used to cancel  <ins> proposed changes; there is no support for rolling back from a "stable" state to a previous "stable" state.  If a rollback is attempted in the "stable" state, processing MUST stop and an error MUST be returned.  Note that this implies that once the answerer has performed setLocalDescription with its answer, this cannot be rolled back. </ins> The effect of rollback MUST be the same regardless of whether setLocalDescription or setRemoteDescription is called.


the threat model of RFC3552 applies.  In particular, JavaScript can call the API in any order and with any inputs, including malicious ones.  This is particularly relevant when we consider the SDP that is <del> passed to setLocalDescription().  While correct API usage requires that the application pass in SDP that was derived from createOffer() or createAnswer(), there is no guarantee that applications do so. The JSEP implementation MUST be prepared for the JavaScript to pass in bogus data instead. </del>  Conversely, the application programmer needs to be aware that the JavaScript does not have complete control of endpoint behavior.  One

the threat model of RFC3552 applies.  In particular, JavaScript can call the API in any order and with any inputs, including malicious ones.  This is particularly relevant when we consider the SDP that is  <ins> passed to setLocalDescription.  While correct API usage requires that the application pass in SDP that was derived from createOffer or createAnswer, there is no guarantee that applications do so.  The JSEP implementation MUST be prepared for the JavaScript to pass in bogus data instead. </ins> Conversely, the application programmer needs to be aware that the JavaScript does not have complete control of endpoint behavior.  One


BCP 14 RFC2119 RFC8174 when, and only when, they appear in all capitals, as shown here. <del> This document uses the Augmented BNF defined in HTTP to specify valid protocol elements.  Additionally, it uses the modified "parameter" rule from RFC5987 and the "URI-Template" rule from URI-TEMPLATE. </del>  2. <del> The Link-Template header field provides a means for serialising one or more links into HTTP message metadata.  It is semantically equivalent to the Link header field defined in WEB-LINKING, except that it uses URI Templates URI-TEMPLATE to convey the structure of links. </del>  For example:

Emerging best practice is to use for new headers, so that parsing is well-defined. Arguments for sticking with a -like syntax: Consistence with (IMO a very poor justification) Reuse of parsers / other software (it's not well-defined, tho) ???
We could also talk about creating a SF version of (maybe ?).
Matching SF and headers would be appealing.
In the meantime (or maybe before ;) -- URL

BCP 14 RFC2119 RFC8174 when, and only when, they appear in all capitals, as shown here.  <ins> This specification uses the following terms from STRUCTURED-FIELDS: List, String, Parameter. </ins> 2.  <ins> The Link-Template header field is a Structured Field STRUCTURED- FIELDS that serializes one or more links into HTTP message metadata. It is semantically equivalent to the Link header field defined in WEB-LINKING, except that it uses URI Templates URI-TEMPLATE to convey the structure of links. Its value is a List of Strings.  Each String is a URI Template, and Parameters on it carry associated metadata. </ins> For example:


Parameters on a templated-link have identical semantics to those of a Link header field.  This includes (but is not limited to) the use of the "rel" parameter to convey the relation type, the "anchor" <del> parameter to modify the context IRI, and so on. </del>  Likewise, the requirements for parameters on templated-links are the <del> same as those for a Link header field; in particular, the "rel" parameter MUST NOT appear more than once, and if it does, the templated-link MUST be ignored by parsers. </del>  This specification defines additional semantics for the "var-base" parameter on templated-links; see below.

Parameters on a templated-link have identical semantics to those of a Link header field.  This includes (but is not limited to) the use of the "rel" parameter to convey the relation type, the "anchor"  <ins> parameter to modify the context IRI, and so on.  Parameter values MUST be Strings. </ins> Likewise, the requirements for parameters on templated-links are the  <ins> same as those for a Link header field. </ins> This specification defines additional semantics for the "var-base" parameter on templated-links; see below.


Load balancers SHOULD drop short header packets with unroutable DCIDs. <del> The routing of long headers with unroutable DCIDs depends on the server ID allocation strategy, described in sid-allocation.  However, the load balancer MUST NOT drop these packets, with one exception. </del>  Load balancers MAY drop packets with long headers and unroutable DCIDs if and only if it knows that the encoded QUIC version does not

and .
In light of , NAME concerns about the framework, and NAME declining interest in implementing, I think it's time to simply eliminate this from the document.
Thanks for all the hard work, but sorry to be the cause of it.
Fixed by
How does a dynamic framework survive an HA handover? It would seem to lose all the SID allocations and break all connections.

Load balancers SHOULD drop short header packets with unroutable DCIDs.  <ins> When forwarding a packet with a long header and unroutable DCID, load balancers MUST use a fallback algorithm as specified in fallback- algorithm. </ins> Load balancers MAY drop packets with long headers and unroutable DCIDs if and only if it knows that the encoded QUIC version does not


4.3. <del> For any given configuration, the configuration agent must specify if server IDs will be statically or dynamically allocated.  Load Balancer configurations with statically allocated server IDs explicitly include a mapping of server IDs to forwarding addresses. The corresponding server configurations contain one or more unique server IDs. </del>  <del> A dynamically allocated configuration does not have a pre-defined assignment, reducing configuration complexity.  However, it places limits on the maximum server ID length and requires more state at the load balancer.  In certain edge cases, it can force parts of the system to fail over to 5-tuple routing for a short time. In either case, the configuration agent chooses a server ID length for each configuration that MUST be at least one octet.  For Static Allocation, the maximum length depends on the algorithm.  For dynamic allocation, the maximum length is 7 octets. </del>  A QUIC-LB configuration MAY significantly over-provision the server ID space (i.e., provide far more codepoints than there are servers) to increase the probability that a randomly generated Destination Connection ID is unroutable.  Conceptually, each configuration has its own set of server ID allocations, though two static configurations with identical server ID lengths MAY use a common allocation between them.

4.3.  <ins> Load Balancer configurations include a mapping of server IDs to forwarding addresses.  The corresponding server configurations contain one or more unique server IDs. </ins>  <ins> The configuration agent chooses a server ID length for each configuration that MUST be at least one octet. </ins> A QUIC-LB configuration MAY significantly over-provision the server ID space (i.e., provide far more codepoints than there are servers) to increase the probability that a randomly generated Destination Connection ID is unroutable. <ins> The configuration agent SHOULD provide a means for servers to express the number of server IDs it can usefully employ, because a single routing address actually corresponds to multiple server entities (see lb-chains). </ins> Conceptually, each configuration has its own set of server ID allocations, though two static configurations with identical server ID lengths MAY use a common allocation between them.


A server encodes one of its assigned server IDs in any CID it generates using the relevant configuration. <del> 4.3.1. In the static allocation method, the configuration agent assigns at least one server ID to each server. When forwarding a packet with a long header and unroutable DCID, load balancers MUST forward packets with long headers and unroutable DCIDs using an fallback algorithm as specified in fallback-algorithm. 4.3.2. In the dynamic allocation method, the load balancer assigns server IDs dynamically so that configuration does not require fixed server ID assignment.  This reduces linkability and simplifies configuration.  However, it also limits the length of the server ID and requires the load balancer to lie on the path of outbound packets.  As the server mapping is no longer part of the configuration, standby load balancers need an out-of-band mechanism to synchronize server ID allocations in the event of failures of the primary device. To summarize, the load balancer forwards incoming Initial packets arbitrarily and both load balancer and server are sometimes able to infer a potential server ID allocation from the CID in the packet. The server can signal acceptance of that allocation by using it immediately, in which case both entities add it to their permanent table.  Usually, however, the server will reject the allocation by not using it, in which case it is not added to the permanent assignment list. 4.3.2.1. The configuration agent does not assign server IDs, but does configure a server ID length.  The server ID MUST be at least one and no more than seven octets.  See sid-limits for other considerations if also using the Plaintext CID algorithm. 4.3.2.2. The load balancer maintains a mapping of assigned server IDs to routing information for servers, initialized as empty.  This mapping is independent for each operating configuration. Note that when the load balancer's tables for a configuration are empty, all incoming DCIDs corresponding to that configuration are unroutable by definition. The load balancer processes a long header packet as follows: If the config rotation bits do not match a known configuration, the load balancer routes the packet using a fallback algorithm (see fallback-algorithm).  It does not extract a server ID. If there is a matching configuration, but the CID is not long enough to apply the algorithm, the load balancer pads the connection ID with zeros to the required length. Otherwise, the load balancer extracts the server ID in accordance with the configured algorithm and parameters. If the load balancer extracted a server ID already in its mapping, it routes the packet accordingly.  If the server ID is not in the mapping, it routes the packet according to a fallback algorithm and awaits the first long header the server sends in response. If the load balancer extracted an unassigned server ID and observes that the first long header packet the server sends has a Source Connection ID that encodes the same server ID, it adds that server ID to the mapping.  Otherwise, it takes no action. 4.3.2.3. Each server maintains a list of server IDs assigned to it, initialized empty. Upon receipt of a packet with a client-generated DCID, the server MUST follow these steps in order: If the config rotation bits do not correspond to a known configuration, do not attempt to extract a server ID. If the DCID is not long enough to decode using the configured algorithm, pad it with zeros to the required length and extract a server ID. If the DCID is long enough to decode, extract the server ID. If the server ID is not already in its list, the server MUST decide whether or not to immediately use it to encode a CID on the new connection.  If it chooses to use it, it adds the server ID to its list.  If it does not, it MUST NOT use the server ID in future CIDs. The server SHOULD NOT use more than one CID, unless it is close to exhausting the nonces for an existing assignment.  Note also that the load balancer may observe a single entity claiming multiple server IDs because that entity actually represents multiple servers devices or processors. The server MUST generate a new connection ID if the client-generated CID is of insufficient length for the configuration. The server then processes the packet normally. When a server needs a new connection ID, it uses one of the server IDs in its list to populate the server ID field of that CID.  It MAY vary this selection to reduce linkability within a connection. After loading a new configuration, a server may not have any available SIDs.  This is because an incoming packet may not contain the config rotation bits necessary to extract a server ID in accordance with the algorithm above.  When required to generate a CID under these conditions, the server MUST generate CIDs using the 5-tuple routing codepoint (see config-failover.  Note that these connections will not be robust to client address changes while they use this connection ID.  For this reason, a server SHOULD retire these connection IDs and replace them with routable ones once it receives a client-generated CID that allows it to acquire a server ID.  As, statistically, one in every four such CIDs can provide a server ID, this is typically a short interval. </del> 4.4. All connection IDs use the following format:

A server encodes one of its assigned server IDs in any CID it generates using the relevant configuration.  4.4. All connection IDs use the following format:


QUIC-LB requires common configuration to synchronize understanding of encodings and guarantee explicit consent of the server. <del> The load balancer and server MUST agree on a routing algorithm, server ID allocation method, and the relevant parameters for that algorithm. </del>  All algorithm configurations can have a server ID length, nonce length, and key.  However, for Plaintext CID, there is no key. <del> If server IDs are statically allocated, the load balancer MUST receive the full table of mappings, and each server must receive its assigned SID(s), from the configuration agent. </del>  Note that server IDs are opaque bytes, not integers, so there is no notion of network order or host order.

QUIC-LB requires common configuration to synchronize understanding of encodings and guarantee explicit consent of the server.  <ins> The load balancer and server MUST agree on a routing algorithm and the relevant parameters for that algorithm. </ins> All algorithm configurations can have a server ID length, nonce length, and key.  However, for Plaintext CID, there is no key.  <ins> The load balancer MUST receive the full table of mappings, and each server must receive its assigned SID(s), from the configuration agent. </ins> Note that server IDs are opaque bytes, not integers, so there is no notion of network order or host order.


fewer than 2^40 tokens are generated with a single key, the risk of collisions is lower than 0.001%. <del> 11.8. When using Dynamic SID allocation, the load balancer's SID table can be as large as 2^56 entries, which is prohibitively large.  To constrain the size of this table, servers are encouraged to accept as few SIDs as possible, so that the remainder do not enter the load balancer's table. </del> 12. There are no IANA requirements.

fewer than 2^40 tokens are generated with a single key, the risk of collisions is lower than 0.001%.  12. There are no IANA requirements.


The Stream Cipher CID algorithm provides cryptographic protection at the cost of additional per-packet processing at the load balancer to <del> decrypt every incoming connection ID.  The CID format is depicted below. </del>  5.2.1.

The CID format figure has been removed since draft-ietf-quic-load-balancers-08

The Stream Cipher CID algorithm provides cryptographic protection at the cost of additional per-packet processing at the load balancer to  <ins> decrypt every incoming connection ID. </ins> 5.2.1.


octet of the Connection ID are reserved to express the length of the following connection ID, not including the first octet. <del> A server not using this functionality SHOULD make the six bits appear to be random. </del>  2.4.

URL is probably not your intent, but that is what you get with this phrasing. I think that the point is that the values are not predictable to entities other than the one generating it. This appears in several places in the document.
Well URL uses "indistinguishable from random" :-) But OK, I'll seek a new formulation.

octet of the Connection ID are reserved to express the length of the following connection ID, not including the first octet.  <ins> A server not using this functionality SHOULD choose the six bits so as to have no observable relationship to previous connection IDs issued for that connection. </ins> 2.4.


respective fields. If there is no key in the configuration, the server MUST fill the <del> Nonce field with bytes that appear to be random.  If there is a key, the server fills the nonce field with a nonce of its choosing.  See cid-entropy for details. </del>  The server MAY append additional bytes to the connection ID, up to the limit specified in that version of QUIC, for its own use.  These

respective fields. If there is no key in the configuration, the server MUST fill the  <ins> Nonce field with bytes that have no observable relationship to the field in previously issued connection IDs.  If there is a key, the server fills the nonce field with a nonce of its choosing.  See cid- entropy for details. </ins> The server MAY append additional bytes to the connection ID, up to the limit specified in that version of QUIC, for its own use.  These


two connection IDs to the same connection, client, or server.  In particular, all servers using a configuration MUST consistently add the same length to each connection ID, to preserve the linkability <del> objectives of QUIC-LB.  Any additional bytes SHOULD appear random unless individual servers are not distinguishable (e.g. any server using that configuration appends identical bytes to every connection ID). </del>  If there is no key in the configuration, the Connection ID is complete.  Otherwise, there are further steps, as described in the

two connection IDs to the same connection, client, or server.  In particular, all servers using a configuration MUST consistently add the same length to each connection ID, to preserve the linkability  <ins> objectives of QUIC-LB.  Any additional bytes SHOULD NOT provide any observable correlation to previous connection IDs for that connection (e.g., the bytes can be chosen at random). </ins> If there is no key in the configuration, the Connection ID is complete.  Otherwise, there are further steps, as described in the


Whether or not it implements the counter method, the server MUST NOT reuse a nonce until it switches to a configuration with new keys. <del> If the nonce is sent in plaintext, servers MUST generate nonces so that they appear to be random.  Observable correlations between plaintext nonces would provide trivial linkability between individual connections, rather than just to a common server. </del>  For any algorithm, configuration agents SHOULD implement an out-of- band method to discover when servers are in danger of exhausting

Whether or not it implements the counter method, the server MUST NOT reuse a nonce until it switches to a configuration with new keys.  <ins> Servers are forbidden from generating linkable plaintext nonces, because observable correlations between plaintext nonces would provide trivial linkability between individual connections, rather than just to a common server. </ins> For any algorithm, configuration agents SHOULD implement an out-of- band method to discover when servers are in danger of exhausting


shifting necessary in the event that there are an odd number of octets. <del> The expand_left() function outputs 16 octets, with its first argument in the most significant bits, its second argument in the least significant byte, its third argument in the second least significant byte, and zeros in all other positions.  Thus, </del>  <del> expand_right() is similar, except that the second argument is in the most significant byte, the third is in the second most significant byte, and the first argument is in the least significant bits. Therefore, </del>  <del> Similarly, truncate_left() and truncate_right() take the most significant and least significant bits, respectively, from a ciphertext.  For example, to take 28 bits of a ciphertext: </del>  The example at the end of this section helps to clarify the steps described below. The server concatenates the server ID and nonce to create <del> plaintext_CID. </del>  The server splits plaintext_CID into components left_0 and right_0 <del> of equal length, splitting an odd octet in half if necessary.  For example, 0x7040b81b55ccf3 would split into a left_0 of 0x7040b81 and right_0 of 0xb55ccf3. </del>  <del> Encrypt the result of expand_left(left_0, index)) to obtain a ciphertext, where 'index' is one octet: the two most significant bits of which are 0b00, and the six least significant bits are the length of the resulting connection ID in bytes, cid_len. </del>  <del> XOR the least significant bits of the ciphertext with right_0 to form right_1. </del>  <del> Thus steps 3 and 4 can be expressed as "right_1 = right_0 ^ truncate_right( AES_ECB(key, expand_left(left_0, cid_len, 1)), len(right_0)) " </del>  Repeat steps 3 and 4, but use them to compute left_1 by expanding <del> and encrypting right_1 with the most significant octet as the concatenation of 0b01 and cid_len, and XOR the results with </del>  left_0. <del> "left_1 = left_0 ^ truncate_left( AES_ECB(key, expand_right(right_1, cid_len, 2)), len(left_0)) " </del>  Repeat steps 3 and 4, but use them to compute right_2 by expanding <del> and encrypting left_1 with the least significant octet as the concatenation of 0b10 and cid_len, and XOR the results with </del>  right_1. <del> "right_2 = right_1 ^ truncate_right( AES_ECB(key, expand_left(left_1, cid_len, 3), len(right_1)) " </del>  Repeat steps 3 and 4, but use them to compute left_2 by expanding <del> and encrypting right_2 with the most significant octet as the concatenation of 0b11 ands cid_len, and XOR the results with </del>  left_1. <del> "left_2 = left_1 ^ truncate_left( AES_ECB(key, expand_right(right_2, cid_len, 4), len(left_1)) " </del>  The server concatenates left_2 with right_2 to form the ciphertext <del> CID, which it appends to the first octet. </del>  The following example executes the steps for the provided inputs. Note that the plaintext is of odd octet length, so the middle octet

Attempt to , . Examples and test vectors not yet updated. PTAL at the description. Is the algorithm accurately described Are things clearer or not
NAME Thanks for all the formatting suggestions. It's cleaned up a bit, although I wasn't able to get aasvg to work. PTAL
Correction. I got aasvg to work but it did not look good at all, probably due to user incompetence. If you would like to submit a PR after this that is prettier, I would welcome it.
Stefan Kolbl points out this problem with the 4-pass method: Indeed, there are ways to avoid ugly and error-prone bit shifting while avoiding this property. In particular, we can always use expand-left, but just padding odd-bytes with zeros to preserve byte boundaries and avoid bit-shifting.
Fixed by
Several problems here: A lot of the description relies on examples rather than normative language. The split of a CID that has an odd length produces HEX sequences with an odd number of characters, which in many circumstances will be interpreted as being (left-)padded with 4 zero bits. If that happened, then bad things would occur. You really need to retain the number of bits. Step 3 passes two arguments to , when it has three. The encryption doesn't bind to the configuration that is in use; instead the high bits of the first octet are set to 0. The formatting of the operations wraps awkwardly. The operators that this uses (^ and primarily) aren't defined. The third input to seems to increment without explanation. Given the examples, I could no doubt work this all out satisfactorily, but that shouldn't be necessary.
Fixed by
A lot.
Yes, the new text seems clear, and correct.

shifting necessary in the event that there are an odd number of octets.  <ins> When configured with both a key, and a nonce length and server ID length that sum to any number other than 16, the server MUST follow the algorith below to encrypt the connection ID. </ins>  <ins> 4.3.2.1. </ins>  <ins> The 4-pass algorithm is a four-round Feistel Network with the round function being AES-ECB.  Most modern applications of Feistel Networks have more than four rounds.  The implications of this choice, which is meant to limit the per-packet compute overhead at load balancers, are discussed in distinguishing-attacks. The server concatenates the server ID and nonce into a single field, which is then split into equal halves.  In successive passes, one of these halves is expanded into a 16B plaintext, encrypted with AES- ECB, and the result XORed with the other half.  The diagram below shows the conceptual processing of a plaintext server ID and nonce into a connection ID.  'FO' stands for 'First Octet'. 4.3.2.2. Two functions are useful to define: The expand(length, pass, input_bytes) function concatenates three arguments and outputs 16 zero-padded octets. The first argument 'length' is an 8-bit integer that reports the sum of the configured nonce length and server id length in octets, and forms the most significant octet of the output.  The 'length' argument MUST NOT exceed 28. The second argument is an 8-bit integer that is the 'pass' of the algorithm, and forms the second-most significant octet of the output. The third argument is a variable-length stream of octets, which is copied into the third-most significant octet of the output and beyond.  The length of this octet stream is half the 'length', rounded up.  All remaining octets of the output are zero. For example, Similarly, truncate(input, n) returns the first n octets of 'input'. Let 'half_len' be equal to 'plaintext_len' / 2, rounded up. 4.3.2.3. </ins> The example at the end of this section helps to clarify the steps described below. The server concatenates the server ID and nonce to create  <ins> plaintext_CID.  The length of the result in octets is plaintext_len. </ins> The server splits plaintext_CID into components left_0 and right_0  <ins> of equal length half_len.  If plaintext_len is odd, right_0 clears its first four bits, and left_0 clears its last four bits.  For example, 0x7040b81b55ccf3 would split into a left_0 of 0x7040b810 and right_0 of 0x0b55ccf3. </ins>  <ins> Encrypt the result of expand(plaintext_len, 1, left_0) using an AES-ECB-128 cipher to obtain a ciphertext. </ins>  <ins> XOR the first half_len octets of the ciphertext with right_0 to form right_1.  Steps 3 and 4 can be summarized as </ins>  <ins> If the plaintext_len is odd, clear the first four bits of right_1. </ins> Repeat steps 3 and 4, but use them to compute left_1 by expanding  <ins> and encrypting right_1 with pass = 2, and XOR the results with </ins> left_0.  <ins> If the plaintext_len is odd, clear the last four bits of left_1. </ins> Repeat steps 3 and 4, but use them to compute right_2 by expanding  <ins> and encrypting left_1 with pass = 3, and XOR the results with </ins> right_1.  <ins> If the plaintext_len is odd, clear the first four bits of right_2. </ins> Repeat steps 3 and 4, but use them to compute left_2 by expanding  <ins> and encrypting right_2 with pass = 4, and XOR the results with </ins> left_1.  <ins> If the plaintext_len is odd, clear the last four bits of left_2. </ins> The server concatenates left_2 with right_2 to form the ciphertext  <ins> CID, which it appends to the first octet.  If plaintext_len is odd, the four least significant bits of left_2 and four most significant bits of right_2, which are all zero, are stripped off before concatenation to make the resulting ciphertext the same length as the original plaintext. 4.3.2.4. </ins> The following example executes the steps for the provided inputs. Note that the plaintext is of odd octet length, so the middle octet


(i.e., the nonce is at least as large as the server ID).  If the server ID is longer, a fourth pass is necessary: <del> "right_0 = right_1 ^ truncate_right( AES_ECB(key, expand_left(left_0, cid_len, 1), len(right_1)) " </del> and the load balancer has to concatenate left_0 and right_0 to obtain the complete server ID.

(i.e., the nonce is at least as large as the server ID).  If the server ID is longer, a fourth pass is necessary:  and the load balancer has to concatenate left_0 and right_0 to obtain the complete server ID.


connection if servers make reasonable selections when generating new IDs for that connection.  11. There are no IANA requirements.

Added two sections to Security Considerations (Stateless Reset Oracle and Local Configurations Only). and .
Can you speak a little about your reasoning for the recent changes? If this attack is limited to extracting the identity of server instances for other co-hosted entities, that's probably OK, but I'm having trouble connecting the SHOULD here with the preceding text.
Sure. If an attacker has the same QUIC-LB config as the victim, then it can extract the server mapping, which defeats the whole point of the spec. Obviously, an LB must have the QUIC-LB config for servers it routes to. If I'm an attacker within that group of servers I may already see the packet headers that give away the server mapping, so there's little added linkability here (though there is a little). The moment I share configuration among multiple server pools, I'm expanding the number of entities with access to the config, for no operational benefit except to make the administrator's life easier. In the absurd limit, all of AWS has the same QUIC-LB config, and essentially everyone can extract the server mapping from any CID that goes to AWS.
Add a security consideration to avoid the following scenario: MyCloudProvider has a single QUIC-LB config for all its load balancers. It rotates keys periodically, etc, but everyone gets the same config. Obviously, all the attacker has to do is open an account with MyCloudProvider and it is able to recover all the server IDs. Configs ought to be restricted to load balancers serving a finite set of servers. It is possible another MyCloudProvider customer is in the pool behind that load balancer, but that's already a privileged position as already described in the draft. Obviously, this will require some wordsmithing, as the statement above isn't very precise.
As server clusters increase in size, the need to reallocate server identifiers becomes more acute. In one model, the configuration ID is used to indicate a stable routing configuration. Server identifiers for a given configuration ID are routed to the same server, no matter how many other instances are added or removed. In order to allow for changes in the cluster, the configuration ID is used so that old servers can be removed from consideration and new ones added. If these changes happen frequently enough, the number of bits allocated to identifying a configuration might be insufficient. Why not make the length of the identifier flexible? That might mean that you need to make the length of the length similarly configurable.
It was not the intent of these bits to support long-lived configurations, instead supporting key rotation, upgrades, and the like. I would much rather people overprovisioned the server ID space than using this tool, TBH. However, the only cost is limiting the theoretical size of CIDs. At the moment, we can support up to 64B, future-proofing the encodings against future versions of QUIC. I'm open to another bit for this, but how would a configurable number of CR bits work with multiple configurations? How does a config that needs 5 bits and one that needs 2 coexist, especially if the latter needs length self-encoding?
As we talk through the implications of mutually mistrustful servers in , I think the case for adding another bit is compelling. I'm going to remove the needs-discussion label and come up with a PR that takes another bit.
I'm returning this to needs-discussion, as NAME points out there is a privacy tradeoff here. If the config codespace is large, it's straightforward to have each mistrustful server have its own totally unique config. On the other hand, keeping this long-lived config difference leaks the type of flow. Assuming it's routed based on SNI, it leaks the SNI of each CID, and in that sense also increases linkability.
Alright, I've reflected on this a bit more. In general, different server entities will have different external IP addresses and/or ports, so the load balancer can distinguish the correct QUIC-LB config without resorting to the CR bits. As IP and port are visible to everyone, there is no privacy leakage. The problem occurs when mutually mistrustful servers share the same IP/port and are switched on something else. That "something" may be something present only in the client hello, with the classical load balancer simply using the 4tuple after that. The only thing I am aware of in practice is the SNI. If there are others, please say so in this thread. If the SNI is encrypted, the unprivileged LB envisioned in QUIC-LB does not have access to it. So we can assume this use case only applies to unencrypted SNI. Option 1: mistrustful servers share the same config. a third party will be able to extract your server mapping, but in practice it will be hard for an attacker to obtain this position on purpose. If this is the best outcome, we can stick with 2 config rotation bits. Option 2: Issue them different config rotation codepoints. So an observer can see the SNI and associate it with certain CR bits; if the client later migrates, it will still be able to associate that connection with that SNI. If this is better than Option 1, we should probably add a third config rotation bit. Other (minor) costs of having 3 config rotation bits: length self-encoding can only support 31 byte connection IDs, instead of 63 (obviously this is only relevant for hypothetical future versions of QUIC) each config can have its own set of server IDs. So there is considerably more config state at the LB. As SIDs can be up to 18B, it's 18B x (# of servers) x (# of config rotation codepoints). This memory footprint will roughly double by going from 3 to 7 codepoints. I've talked myself into Option 1 as being a mildly better situation, thus sticking with 2 CR bits.
Update: the ECHO design might allow the LB privileged access to the SNI, so it might be encrypted. However, an attacker could connect to the domains at that IP and obtain the config rotation bits. So option 2 actually circumvents ESNI entirely!
Closing -- I have received no pushback on doing nothing (leaving it at 2 bits), so I'm going to do nothing.
The draft doesn't address the impact of each method of connection ID generation on how servers can use stateless resets. Most of this is likely bound up in decisions stemming from . If you can guess a valid but unused connection ID, then you might be able to induce a stateless reset that could be used to kill an open connection. As the draft only includes methods that include an explicit server identifier, it is possible that as long as valid values cannot be guessed, the effect is minimal and each server instance can have its own configured stateless reset key (or a shared key from which a per-server key is derived using a KDF).
I don't understand the attack here. A given CID will deterministically map to a specific server instance. So there is no way for another server to receive a packet with that CID and generate a stateless reset. What am I missing? There might be something here with the differing treatment of long-header vs. short-header packets, (and the option for servers to send resets on long headers), but I'll have to think about it more.
As to the last point, nope: even a long header with a DCID that conforms to the server's expectations (i.e. maps to a real server) will get delivered to that server, so I don't think that's an attack.
NAME Should we talk about this issue more, or are you satisfied enough that I can close it?
I don't see any mention of stateless reset in the draft at all. That's probably something worth addressing, even if it is to say what you have already.

connection if servers make reasonable selections when generating new IDs for that connection. <ins> 10.3. A simple deployment of QUIC-LB in a cloud provider might use the same global QUIC-LB configuration across all its load balancers that route to customer servers.  An attacker could then simply become a customer, obtain the configuration, and then extract server IDs of other customers' connections at will. To avoid this, the configuration agent SHOULD issue QUIC-LB configurations to mutually distrustful servers that have different keys (for the block cipher or stream cipher algorithms) or routing masks and divisors (for the obfuscated algorithm).  The load balancers can distinguish these configurations by external IP address, or by assigning different values to the config rotation bits (config-rotation).  Note that either of these techniques exposes information to outside observers, as traffic destined for each server set can be easily distinguished. These techniques are not necessary for the plaintext algorithm, as it does not attempt to conceal the server ID. 10.4. Section 21.9 of QUIC-TRANSPORT discusses the Stateless Reset Oracle attack.  For a server deployment to be vulnerable, an attacking client must be able to cause two packets with the same Destination CID to arrive at two different servers that share the same cryptographic context for Stateless Reset tokens.  As QUIC-LB requires deterministic routing of DCIDs over the life of a connection, it is a sufficient means of avoiding an Oracle without additional measures. </ins> 11. There are no IANA requirements.


The extracted server mapping might not correspond to an active server. <del> A field that should be all zeroes after decryption may not be so. </del> Load balancers MUST forward packets with long headers with non- compliant DCIDs to an active server using an algorithm of its own choosing.  It need not coordinate this algorithm with the servers.

The encrypted CID format includes a zero-pad field that is used to detect whether the decryption succeeded or not. I suggest merging this field with the server ID field, and test whether the decryption succeed by checking whether the server ID is valid or not. This assumes that the server ID field is sparsely populated. For example, if there are just 256 servers, in theory a 1-octed field would be sufficient; instead, we could use a 4 or 5 octet server ID field that would be sparsely populated, allowing for error detection. This would allow for unified validity detection across all supported methods: clear text: verify that the server ID is valid; obfuscated: the divider need to have the same size as the full length server ID; the modulo is the server ID; validity can be verified there. stream: decrypt and verify that the server-id is valid encrypt: decrypt and verify that the server-id is valid It would also allows for simplification of the configuration for the encrypted method, by specifying just one field instead of two.
Yes, I agree this is simpler with no cost at all. Care to do a PR?

The extracted server mapping might not correspond to an active server.  Load balancers MUST forward packets with long headers with non- compliant DCIDs to an active server using an algorithm of its own choosing.  It need not coordinate this algorithm with the servers.


The server ID will start in the second octet of the decrypted connection ID and occupy continuous octets beyond that. <del> The configuration agent selects a zero-padding length.  This SHOULD be at least four octets to allow detection of non-compliant DCIDs. The server ID and zero- padding length MUST sum to no more than 16 octets.  They SHOULD sum to no more than 12 octets, to provide servers adequate space to encode their own opaque data. </del>  The configuration agent also selects an 16-octet AES-ECB key to use for connection ID decryption.

The server ID will start in the second octet of the decrypted connection ID and occupy continuous octets beyond that.  <ins> They server ID length MUST be no more than 16 octets and SHOULD sum to no more than 12 octets, to provide servers adequate space to encode their own opaque data. </ins> The configuration agent also selects an 16-octet AES-ECB key to use for connection ID decryption.


octet to obtain the config rotation bits.  It then decrypts the subsequent 16 octets using AES-ECB decryption and the chosen key. <del> The decrypted plaintext contains the server id, zero padding, and opaque server data in that order.  The load balancer uses the server ID octets for routing. </del>  4.4.3. When generating a routable connection ID, the server MUST choose a connection ID length between 17 and 20 octets.  The server writes its <del> provided server ID into the server ID octets, zeroes into the zero- padding octets, and arbitrary bits into the remaining bits.  These arbitrary bits MAY encode additional information.  Bits in the first, eighteenth, nineteenth, and twentieth octets SHOULD appear essentially random to observers.  The first octet is reserved as described in first-octet. </del>  The server then encrypts the second through seventeenth octets using the 128-bit AES-ECB cipher.

octet to obtain the config rotation bits.  It then decrypts the subsequent 16 octets using AES-ECB decryption and the chosen key.  <ins> The decrypted plaintext contains the server id and opaque server data in that order.  The load balancer uses the server ID octets for routing. </ins> 4.4.3. When generating a routable connection ID, the server MUST choose a connection ID length between 17 and 20 octets.  The server writes its  <ins> provided server ID into the server ID octets and arbitrary bits into the remaining bits.  These arbitrary bits MAY encode additional information.  Bits in the eighteenth, nineteenth, and twentieth octets SHOULD appear essentially random to observers.  The first octet is reserved as described in first-octet. </ins> The server then encrypts the second through seventeenth octets using the 128-bit AES-ECB cipher.


state Retry Service also needs the token key, and to be aware if a NAT sits between it and the servers. <del> The following pseudocode describes the data items necessary to store a full QUIC-LB configuration at the server.  It is meant to describe the conceptual range and not specify the presentation of such configuration in an internet packet.  The comments signify the range of acceptable values where applicable. </del>  9.

As the config gets more complicated, the C-ish pseudocode is getting more unwieldy. YANG is the standard for configuration models, so I should bite the bullet and just figure out YANG.

state Retry Service also needs the token key, and to be aware if a NAT sits between it and the servers.  <ins> yang-model provides a YANG Model of the a full QUIC-LB configuration. </ins> 9.


The bandwidth is per L2VPN service. <del> 'svc-inbound-bandwidth' indicates the inbound bandwidth of the </del>  connection (i.e., download bandwidth from the service provider to the site). <del> 'svc-outbound-bandwidth' indicates the outbound bandwidth of the </del>  connection (i.e., upload bandwidth from the site to the service provider).

RFC8299 and RFC8466 use "inbound-bandwidth" and "outbound-bandwidth" from the point of view of the customer site. L3NM also uses this terminology from the point of view of the customer's site. L2NM flips the terminology, for example "inbound" is from PE's perspective. To avoid confusion, it would better in both L3NM and L2NM to use explicit terminology so that the direction is obvious, e.g. "PE-to-CE-bandwidth" "CE-to-PE-bandwidth" In the description field, it would be good to say which field in RFC8299/RFC8466 this corresponds to.
practically it is ingress-Policer and egress-Shaper, because the BW is controlled only from the PE side. in addition there is policer and shaper per CoS/Queue which should be addressed.
I guess you meant "input-bandwidth" and "output-bandwidth". We do have the following for the L3NM: 'inbound-bandwidth': Indicates, in bits per second (bps), the inbound bandwidth of the connection (i.e., download bandwidth from the service provider to the site). 'outbound-bandwidth': Indicates, in bps, the outbound bandwidth of the connection (i.e., upload bandwidth from the site to the service provider). >L2NM flips the terminology, for example "inbound" is from PE's perspective. 'svc-inbound-bandwidth' indicates the inbound bandwidth of the connection (i.e., download bandwidth from the service provider to the site). 'svc-outbound-bandwidth' indicates the outbound bandwidth of the connection (i.e., upload bandwidth from the site to the service provider). Please note that we do already have the following in the common I-D: "Indicates support for the inbound bandwidth in a VPN. That is, support for specifying the download bandwidth from the service provider network to the VPN site. Note that the L3SM uses 'input' to identify the same feature. That terminology should be deprecated in favor of the one defined in this module."; Which was echoed in the L3NM, e.g., "Note that the L3SM uses 'input- -bandwidth' to refer to the same concept.";
Hi Med In URL it says as follows, maybe it is a typo? container svc-outbound-bandwidth { if-feature "vpn-common:outbound-bw"; description "From the PE perspective, the service outbound bandwidth of the connection."; But I would urge you to change the terminology to "PE-to-CE-bandwidth" /"CE-to-PE-bandwidth" to make it super-explicit, the current terminology has been causing endless confusion to implementers (I realise it's inherited from the service models, but changing the terminology in LXNM would cure the problem well)
This is a typo. It needs to be fixed. Will move this one to the list.
Julian, please check the PR at 7e5286a
Med, this is great, thanks! Can it be changed similarly in L3NM as well? Julian

The bandwidth is per L2VPN service.  <ins> 'svc-pe-to-ce-bandwidth' indicates the inbound bandwidth of the </ins> connection (i.e., download bandwidth from the service provider to the site).  <ins> 'svc-ce-to-pe-bandwidth' indicates the outbound bandwidth of the </ins> connection (i.e., upload bandwidth from the site to the service provider).


away. When mDNS fails, ICE will attempt to fall back to either NAT hairpin, <del> if supported, or TURN relay, if not.  As noted in IPHandling, this may result in increased media latency and reduced connectivity/ increased cost (depending on whether the application chooses to use TURN). </del>  One potential mitigation, as discussed in {#privacy}, is to not conceal candidates created from RFC4941 IPv6 addresses.  This permits

Let's also consider data use cases here: Fallback to TURN has a severe effect on throughput in many cases.
Sure, could add a brief note on this.
The text here isn't normative, so I don't think we need to have a lengthy discussion of this - a few words should suffice.
Fixed by
LGTM

away. When mDNS fails, ICE will attempt to fall back to either NAT hairpin,  <ins> if supported, or TURN relay if not.  This may result in reduced connectivity, reduced throughput and increased latency, as well as increased cost in case of TURN relay. </ins> One potential mitigation, as discussed in {#privacy}, is to not conceal candidates created from RFC4941 IPv6 addresses.  This permits


".local" name may happen through Unicast DNS as noted in RFC6762, Section 3. <del> An ICE agent that supports mDNS candidates MUST support the situation where the hostname resolution results in more than one IP address. In this case, the ICE agent MUST take exactly one of the resolved IP addresses and ignore the others.  The ICE agent SHOULD use the first IPv6 address resolved, if one exists, or the first IPv4 address, if not. </del>  An ICE agent MAY add additional restrictions regarding the ICE candidates it will resolve using mDNS, as this mechanism allows

PR for I considered referring to RFC6724, but that raises more questions than it answers it seems.
From Tom Pusateri: When more than one IPv4 or more than one IPv6 address is present, it seems like it would be better to first prefer an address that is on a shared network instead of always taking the first one (which doesn’t mean anything in DNS). If you want others to use the same address you should prefer the lowest one or the highest one or something sortable instead of the first one which could be different depending on hashing in a cache.
Discussed and agreement was to find a simple alternate algorithm.
Closed by PR

".local" name may happen through Unicast DNS as noted in RFC6762, Section 3.  <ins> An ICE agent SHOULD ignore candidates where the hostname resolution returns more than one IP address. </ins> An ICE agent MAY add additional restrictions regarding the ICE candidates it will resolve using mDNS, as this mechanism allows


not end with ".local" or if the value contains more than one ".", then process the candidate as defined in RFC8445.  Otherwise, resolve the candidate using mDNS.  The ICE agent SHOULD set the unicast-response bit of the corresponding mDNS query message; this minimizes multicast traffic, as the response is

Fixes URL
See URL for details
I added a step where we ignore the candidate in that case. The term 'ignore' should probable be refined as it is used both here and in the context of URL We might want to update ignore in URL context.
LGTM

not end with ".local" or if the value contains more than one ".", then process the candidate as defined in RFC8445. <ins> If the ICE candidate policy is "relay", as defined in JSEP, ignore the candidate. </ins> Otherwise, resolve the candidate using mDNS.  The ICE agent SHOULD set the unicast-response bit of the corresponding mDNS query message; this minimizes multicast traffic, as the response is


section 5.1.1, the candidate is processed as follows: Check whether the ICE agent has a usable registered mDNS hostname <del> resolving to the ICE host candidate's IP address.  If one exists, skip ahead to Step 6. </del>  Generate a unique mDNS hostname.  The unique name MUST consist of a version 4 UUID as defined in RFC4122, followed by ".local".

PR for
Seems all feedback is addresses?
Host ICE candidates, ICE host candidates, or something else?

section 5.1.1, the candidate is processed as follows: Check whether the ICE agent has a usable registered mDNS hostname  <ins> resolving to the ICE candidate's IP address.  If one exists, skip ahead to Step 6. </ins> Generate a unique mDNS hostname.  The unique name MUST consist of a version 4 UUID as defined in RFC4122, followed by ".local".


Store the mDNS hostname and its related IP address in the ICE agent for future reuse. <del> Replace the IP address of the ICE host candidate with its mDNS </del>  hostname, and expose the candidate as usual. An ICE agent can implement this procedure in any way so long as it

Store the mDNS hostname and its related IP address in the ICE agent for future reuse.  <ins> Replace the IP address of the ICE candidate with its mDNS </ins> hostname, and expose the candidate as usual. An ICE agent can implement this procedure in any way so long as it


2.2. <del> For any remote host ICE candidate received by the ICE agent, the following procedure is used: </del>  If the connection-address field value of the ICE candidate does not end with ".local" or if the value contains more than one ".",

2.2.  <ins> For any remote ICE candidate received by the ICE agent, the following procedure is used: </ins> If the connection-address field value of the ICE candidate does not end with ".local" or if the value contains more than one ".",


Otherwise, resolve the candidate using mDNS. <del> If it resolves to an IP address, replace the value of the ICE host candidate by the resolved IP address and continue processing of the candidate. </del>  Otherwise, ignore the candidate.

Otherwise, resolve the candidate using mDNS.  <ins> If it resolves to an IP address, replace the mDNS hostname of the ICE candidate with the resolved IP address and continue processing of the candidate. </ins> Otherwise, ignore the candidate.


A peer-reflexive remote candidate could be learned and constructed from the source transport address of the STUN Binding request as an ICE connectivity check.  The peer-reflexive candidate could share the <del> same address as a remote host ICE candidate that will be signaled or has been signaled, received and is in the process of name resolution. In addition to the elimination procedure of redundant candidates defined in Section 5.1.3 of RFC8445, which could remove constructed peer-reflexive remote candidates, the address of any existing peer- reflexive remote candidate should not be exposed to Web applications by ICE agents that implement this proposal, as detailed in Section #guidelines. </del>  3.

A peer-reflexive remote candidate could be learned and constructed from the source transport address of the STUN Binding request as an ICE connectivity check.  The peer-reflexive candidate could share the  <ins> same address as a remote mDNS ICE candidate whose name is in the process of being resolved.  In addition to the elimination procedure of redundant candidates defined in Section 5.1.3 of RFC8445, which could remove constructed peer-reflexive remote candidates, the address of any existing peer-reflexive remote candidate should not be exposed to Web applications by ICE agents that implement this proposal, as detailed in Section #guidelines. </ins> 3.


When there is no user consent, the following filtering should be done to prevent private IP address leakage: <del> host ICE candidates with an IP address are not exposed as ICE candidate events. </del>  Server reflexive ICE candidate raddr field is set to 0.0.0.0 and rport to 0. <del> SDP does not expose any a=candidate line corresponding to a host ICE candidate which contains an IP address. </del>  Statistics related to ICE candidates MUST NOT contain the resolved IP address of a remote mDNS candidate or the IP address of a peer-

When there is no user consent, the following filtering should be done to prevent private IP address leakage:  <ins> ICE candidates with an IP address are not exposed as ICE candidate events. </ins> Server reflexive ICE candidate raddr field is set to 0.0.0.0 and rport to 0.  <ins> SDP does not expose any a=candidate line corresponding to an ICE candidate which contains an IP address. </ins> Statistics related to ICE candidates MUST NOT contain the resolved IP address of a remote mDNS candidate or the IP address of a peer-


1. As detailed in IPHandling, exposing client private IP addresses by <del> default maximizes the probability of successfully creating direct peer-to-peer connection between two clients, but creates a significant surface for user fingerprinting.  IPHandling recognizes </del>  this issue, but also admits that there is no current solution to this problem; implementations that choose to use Mode 3 to address the privacy concerns often suffer from failing or suboptimal connections

Also wrap long lines for #processing section.
Comments addressed, PTAL.
Will wait for NAME approval before merging.
LGTM, updated PR for line wrapping.
The changes to ICE candidate gathering are targeted to web browsers; the changes to ICE candidate processing affect all WebRTC endpoints.
If we add this indication, do we also need to clarify the use case for lite ICE agents?
What did you have in mind?
{{#gathering}} starts with "For any host candidate gathered by an ICE agent as part of {{RFC8445}} section 5.1.1," it seems the place we need to revise to resolve this issue. I was thinking of allowing ICE lite implementation to skip the mDNS wrapping, since lite agents only use host candidates (8445, section 2.5). The lite implementation is however not required restricted to ICE agents that always have public IPs from my reading of that section, but rather an alternative to simplify the implementation when possible. So I am still not sure if it makes sense to say lite ICE can be exempted from wrapping; or instead indicating mDNS wrapping can be skipped if host candidates are equivalent to srflx candidates, and automatically the intended use of lite ICE satisfies this condition.
Right, the public IPs exception probably covers this. also indicates that this is really for web browsers, which are not allowed to implement ICE Lite.
Started writing this up today, but realized it's not totally clear how this should work. The idea would be to use STUN to figure out if an IP is public or not, but... Should we wait to hand out the mDNS candidate until we determine if the IP is private (i.e., STUN finishes)? Should we not hand out the mDNS candidate if we get a srflx candidate that shows the IP is not private? If we hand out the mDNS candidate and then get a srflx candidate that matches the local IP, should we make that a host candidate? Once we learn an IP is not public, should we cache that for future ICE gathering sessions (i.e., not give out mDNS candidates?) The easiest thing would probably be to recommend handing out the mDNS and srflx candidates as usual, but allow implementations to skip mDNS for IPs it has learned are public. (Except for RFC1918 addresses, which would always be treated as private.)
Partially addressed in , will probably include some additional clarifying text once it lands
LGTM

1. As detailed in IPHandling, exposing client private IP addresses by  <ins> default to web applications maximizes the probability of successfully creating direct peer-to-peer connections between clients, but creates a significant surface for user fingerprinting.  IPHandling recognizes </ins> this issue, but also admits that there is no current solution to this problem; implementations that choose to use Mode 3 to address the privacy concerns often suffer from failing or suboptimal connections


not be supported. This document proposes an overall solution to this problem by <del> registering ephemeral mDNS RFC6762 names for each local private IP address, and then providing those names, rather than the IP addresses, to the web application when it gathers ICE candidates. WebRTC implementations resolve these names to IP addresses and perform ICE processing as usual, but the actual IP addresses are not exposed to the web application. </del>  2.

not be supported. This document proposes an overall solution to this problem by  <ins> providing a mechanism for WebRTC implementations to register ephemeral mDNS RFC6762 names for local private IP addresses, and then provide those names, rather than the IP addresses, in their ICE candidates.  While this technique is intended to benefit WebRTC implementations in web browsers, by preventing collection of private IP addresses by arbitrary web pages, it can also be used by any endpoint that wants to avoid disclosing information about its local network to remote peers on other networks. WebRTC and WebRTC-compatible endpoints Overview that receive ICE candidates with mDNS names will resolve these names to IP addresses and perform ICE processing as usual.  In the case where the endpoint is a web application, the WebRTC implementation will manage this resolution internally and will not disclose the actual IP addresses to the application. </ins> 2.


3.1.  For any host candidate gathered by an ICE agent as part of RFC8445, Section 5.1.1, the candidate is handled as follows:

3.1. <ins> This section outlines how mDNS should be used by ICE agents to conceal local IP addresses.  Naturally, if the ICE agent does not want to conceal its IPs, e.g., if it has a priori knowledge that its addresses are in fact public, this processing is unnecessary. </ins> For any host candidate gathered by an ICE agent as part of RFC8445, Section 5.1.1, the candidate is handled as follows:


3.2.  For any remote ICE candidate received by the ICE agent, the following procedure is used:

3.2. <ins> This section outlines how received ICE candidates with mDNS names are processed by ICE agents, and is relevant to all endpoints. </ins> For any remote ICE candidate received by the ICE agent, the following procedure is used:


An ICE agent that supports mDNS candidates MUST support the situation where the hostname resolution results in more than one IP address. In this case, the ICE agent MUST take exactly one of the resolved IP <del> addresses and ignore the others.  The ICE agent SHOULD, if available, use the first IPv6 address resolved, otherwise the first IPv4 address. </del>  4.

An ICE agent that supports mDNS candidates MUST support the situation where the hostname resolution results in more than one IP address. In this case, the ICE agent MUST take exactly one of the resolved IP  <ins> addresses and ignore the others.  The ICE agent SHOULD use the first IPv6 address resolved, if one exists, or the first IPv4 address, if not. </ins> 4.


want to conceal its IPs, e.g., if it has a priori knowledge that its addresses are in fact public, this processing is unnecessary. <del> For any host candidate gathered by an ICE agent as part of RFC8445, Section 5.1.1, the candidate is handled as follows: </del>  Check whether the ICE agent has a usable registered mDNS hostname resolving to the ICE candidate's IP address.  If one exists, skip

I think this is good to go, will plan to land at EOD.
Does it obfuscate, conceal, or obscure local IP addresses? My vote is for conceal.
Conceal/concealment sgtm.
As noted in , we don't need to use the same term in every case, but the terms should have the same meaning. conceal and hide are fairly synonymous, but conceal and obfuscate have slightly different meanings.
This section is largely normative, so it might make more sense to put some parts from it immediately after Principle, namely the various adjustments to the technique that need to be considered (TURN, IPv6, stats) Things where we merely provide discussion (e.g., session monitoring) rather than normative guidance could remain in the privacy section.
Due to their different sensitivity and lifetime.
If we add this indication, do we also need to clarify the use case for lite ICE agents?
What did you have in mind?
{{#gathering}} starts with "For any host candidate gathered by an ICE agent as part of {{RFC8445}} section 5.1.1," it seems the place we need to revise to resolve this issue. I was thinking of allowing ICE lite implementation to skip the mDNS wrapping, since lite agents only use host candidates (8445, section 2.5). The lite implementation is however not required restricted to ICE agents that always have public IPs from my reading of that section, but rather an alternative to simplify the implementation when possible. So I am still not sure if it makes sense to say lite ICE can be exempted from wrapping; or instead indicating mDNS wrapping can be skipped if host candidates are equivalent to srflx candidates, and automatically the intended use of lite ICE satisfies this condition.
Right, the public IPs exception probably covers this. also indicates that this is really for web browsers, which are not allowed to implement ICE Lite.
Started writing this up today, but realized it's not totally clear how this should work. The idea would be to use STUN to figure out if an IP is public or not, but... Should we wait to hand out the mDNS candidate until we determine if the IP is private (i.e., STUN finishes)? Should we not hand out the mDNS candidate if we get a srflx candidate that shows the IP is not private? If we hand out the mDNS candidate and then get a srflx candidate that matches the local IP, should we make that a host candidate? Once we learn an IP is not public, should we cache that for future ICE gathering sessions (i.e., not give out mDNS candidates?) The easiest thing would probably be to recommend handing out the mDNS and srflx candidates as usual, but allow implementations to skip mDNS for IPs it has learned are public. (Except for RFC1918 addresses, which would always be treated as private.)
Partially addressed in , will probably include some additional clarifying text once it lands
The rest LGTM

want to conceal its IPs, e.g., if it has a priori knowledge that its addresses are in fact public, this processing is unnecessary.  <ins> This section outlines how mDNS should be used by ICE agents to conceal local IP addresses. For each host candidate gathered by an ICE agent as part of the gathering process described in RFC8445, Section 5.1.1, the candidate is handled as described below. Check whether this IP address satisfies the ICE agent's policy regarding whether an address is safe to expose.  If so, expose the candidate and abort this process. </ins> Check whether the ICE agent has a usable registered mDNS hostname resolving to the ICE candidate's IP address.  If one exists, skip


Replace the IP address of the ICE candidate with its mDNS hostname and provide the candidate to the web application. <del> An ICE agent can implement this procedure in any way so long as it produces equivalent results to this procedure. </del>  <del> An implementation may for instance pre-register mDNS hostnames by executing steps 3 to 5 and prepopulate an ICE agent accordingly.  By doing so, only step 6 of the above procedure will be executed at the time of gathering candidates. </del>  An implementation may also detect that mDNS is not supported by the <del> available network interfaces.  The ICE agent may skip steps 2 and 3 </del>  and directly decide to not expose the host candidate. This procedure ensures that an mDNS name is used to replace only one

Replace the IP address of the ICE candidate with its mDNS hostname and provide the candidate to the web application.  <ins> ICE agents can implement this procedure in any way as long as it produces equivalent results.  An implementation may for instance pre- register mDNS hostnames by executing steps 3 to 6 and prepopulate an ICE agent accordingly.  By doing so, only step 7 of the above procedure will be executed at the time of gathering candidates. </ins>  <ins> ICE agents may also decide that certain local IP addresses are safe to expose.  This may be because the ICE agent has a priori knowledge that the address is in fact public, or because the agent has made a policy decision to not conceal certain types of IP addresses (e.g., those with built-in privacy protections) as a calculated choice to improve connectivity.  This topic is discussed further in {#privacy} below. </ins> An implementation may also detect that mDNS is not supported by the  <ins> available network interfaces.  The ICE agent may skip steps 3 and 4 </ins> and directly decide to not expose the host candidate. This procedure ensures that an mDNS name is used to replace only one


increased cost (depending on whether the application chooses to use TURN). <del> The exact impact of this technique is being researched experimentally and will be provided before publication of this document. </del>  4.2.

increased cost (depending on whether the application chooses to use TURN).  <ins> One potential mitigation, as discussed in {#privacy}, is to not conceal candidates created from RFC4941 IPv6 addresses.  This permits connectivity even in large internal networks or where mDNS is disabled. The exact impact of the mDNS technique is being researched experimentally and will be provided before publication of this document. </ins> 4.2.


6.4.  As noted in IPHandling, privacy may be breached if a web application running in two browsing contexts can determine whether it is running on the same device.  While the approach in this document prevents the

6.4. <ins> Naturally, an address that is already exposed to the Internet does not need to be protected by mDNS, as it can be trivially observed by the web server or remote endpoint.  However, determining this ahead of time is not straightforward; while the fact that an IPv4 address is private can sometimes be inferred by its value, e.g., whether it is an RFC1918 address, the reverse is not necessarily true.  IPv6 addresses present their own complications, e.g., private IPv6 addresses as a result of NAT64 RFC6146. Instead, the determination of whether an address is public can be reliably made as part of the ICE gathering process, namely, if the query to the STUN RFC5389 server returns the same value as the local address.  This can be done for both IPv4 and IPv6 local addresses, provided that the application has configured both IPv4 and IPv6 STUN servers.  If this situation occurs, i.e., STUN returns the same IP address value for an address that has already been communicated as an mDNS candidate during the current ICE gathering phase, the ICE agent MUST NOT eliminate the candidate as redundant and MUST send the IP address as a server-reflexive candidate.  This allows the ICE agent to send mDNS candidates immediately (i.e., without waiting for STUN), even if the associated addresses may not be private. Once an address has been identified as public, the ICE agent MAY cache this information and omit mDNS protection for that address in future ICE gathering phases. 6.5. As noted in IPHandling, private IPv4 addresses are especially problematic because of their unbounded lifetime.  However, the RFC4941 IPv6 addresses recommended for WebRTC have inherent privacy protections, namely a short lifetime and the lack of any stateful information.  Accordingly, implementations MAY choose to not conceal RFC4941 addresses with mDNS names as a tradeoff for improved peer-to- peer connectivity. 6.6. </ins> As noted in IPHandling, privacy may be breached if a web application running in two browsing contexts can determine whether it is running on the same device.  While the approach in this document prevents the


a context that has a different origin than the top-level browsing context), or a private browsing context. <del> 6.5. </del>  Even when local IP addresses are not exposed, the number of mDNS hostname candidates can still provide a fingerprinting dimension.

a context that has a different origin than the top-level browsing context), or a private browsing context.  <ins> 6.7. </ins> Even when local IP addresses are not exposed, the number of mDNS hostname candidates can still provide a fingerprinting dimension.


included in this candidate collection.  However, disclosure of these addresses has privacy implications.  This document describes a way to share local IP addresses with other clients while preserving client <del> privacy.  This is achieved by obfuscating IP addresses with </del>  dynamically generated Multicast DNS (mDNS) names. 1.

On line 421: "that this specification is designed to hide". Could edit that as well.
My take is that we don't need to use the same term in every case, but the terms should have the same meaning. conceal and hide are fairly synonymous, but conceal and obfuscate have slightly different meanings.
Does it obfuscate, conceal, or obscure local IP addresses? My vote is for conceal.
Conceal/concealment sgtm.
As noted in , we don't need to use the same term in every case, but the terms should have the same meaning. conceal and hide are fairly synonymous, but conceal and obfuscate have slightly different meanings.

included in this candidate collection.  However, disclosure of these addresses has privacy implications.  This document describes a way to share local IP addresses with other clients while preserving client  <ins> privacy.  This is achieved by concealing IP addresses with </ins> dynamically generated Multicast DNS (mDNS) names. 1.


addition or removal of group members without informing all other members. <del> Membership of an MLS group is the managed at the level of individual </del>  clients.  In most cases, a client corresponds to a specific device used by a user.  If a user has multiple devices, the user will be represented in a group by multiple clients.  If an application wishes

Thanks both, I'll have a look today.
Looks good ! Thanks Richard!
The architecture document mentions PSKs in several places, but does not discuss the security of them. Nor does it discuss the security of External Proposals and External Commits. Notably, the third paragraph of 5.1 Membership Changes says "…the set of devices controlled by the user can only be altered by an authorized member of the group." The set of devices could be altered via an External Commit by a non-member. At the end of 5.2 Parallel Groups there is a vague mention of "using the PSK mechanism to link healing properties among parallel groups.", but no discussion of the security. Likewise Section 5.5 Recovery After State Loss talks about PSKs as the solution to a problem but the risks are not discussed. External Proposals and External Commits should be discussed in section 5.4 Access Control.
NAME I fixed the specific problems you note in

addition or removal of group members without informing all other members.  <ins> Membership of an MLS group is managed at the level of individual </ins> clients.  In most cases, a client corresponds to a specific device used by a user.  If a user has multiple devices, the user will be represented in a group by multiple clients.  If an application wishes


among parallel groups.  For example, suppose a common member M of two groups A and B has performed a key update in group A but not in group B.  The key update provides PCS with regard to M in group A.  If a <del> PSK exported from group A and injected into group B, then some of </del>  these PCS properties carry over to group B, since the PSK and secrets derived from it are only known to the new, updated version of M, not to the old, possibly compromised version of M.

among parallel groups.  For example, suppose a common member M of two groups A and B has performed a key update in group A but not in group B.  The key update provides PCS with regard to M in group A.  If a  <ins> PSK is exported from group A and injected into group B, then some of </ins> these PCS properties carry over to group B, since the PSK and secrets derived from it are only known to the new, updated version of M, not to the old, possibly compromised version of M.


its prior membership with a PSK. There are a few practical challenges to this approach.  For example, <del> the application will need to ensure that the new members have the </del>  required PSK, including any new members that have joined the group since the epoch in which the PSK was issued.

its prior membership with a PSK. There are a few practical challenges to this approach.  For example,  <ins> the application will need to ensure that all members have the </ins> required PSK, including any new members that have joined the group since the epoch in which the PSK was issued.


agreement properties of MLS will confirm that all members of the group agree on the content of these extensions. <del> 5.8. Application messages carried by MLS are opaque to the protocol; they can contain arbitrary data.  Each application which uses MLS needs to define the format of its "application_data" and any mechanism necessary to negotiate the format of that content over the lifetime of an MLS group.  In many applications this means managing format migrations for groups with multiple members who may each be offline at unpredictable times. *RECOMMENDATION:* Use the default content mechanism defined in I- D.mahy-mls-content-neg, unless the specific application defines another mechanism which more appropriately addresses the same requirements for that application of MLS. The MLS framing for application messages also provides a field where clients can send information that is authenticated but not encrypted. Such information can be used by servers that handle the message, but group members are assured that it has not been tampered with. </del>  <del> 5.9. </del>  The protocol aims to be compatible with federated environments. While this document does not specify all necessary mechanisms

Reverts mlswg/mls-architecture This has not been merged for a reason, namely I don’t want the dependency on an unpublished draft.

agreement properties of MLS will confirm that all members of the group agree on the content of these extensions.  <ins> Application messages carried by MLS are opaque; they can contain arbitrary data.  The MLS framing for application messages also provides a field where clients can send information that is authenticated but not encrypted.  Such information can be used by servers that handle the message, but group members are assured that it has not been tampered with. </ins>  <ins> 5.8. </ins> The protocol aims to be compatible with federated environments. While this document does not specify all necessary mechanisms


authentication mechanisms, ciphersuites, and infrastructure functionalities. <del> 5.10. </del>  It is important that multiple versions of MLS be able to coexist in the future.  Thus, MLS offers a version negotiation mechanism; this

authentication mechanisms, ciphersuites, and infrastructure functionalities.  <ins> 5.9. </ins> It is important that multiple versions of MLS be able to coexist in the future.  Thus, MLS offers a version negotiation mechanism; this