Hop-by-Hop (HBH): Communications between an endpoint and a Media Distribution Device or between Media Distribution Devices. <del> Endpoint: An RTP flow terminating entity that has possession of E2E media encryption keys and terminates E2E encryption.  This may </del>  include embedded user conferencing equipment or browsers on computers, media gateways, MCUs, media recording device and more that are in the trusted domain for a given deployment. which includes, but not limited to, having no access to RTP media unencrypted and having limits on what RTP header field it can alter. <del> Key Distributor: An entity that is a logical function which passes keying material and related information to endpoints and Media Distributor(s) that is appropriate for each.  The Key Distributor might be co-resident with another entity trusted with E2E keying material. </del>  Conference: Two or more participants communicating via trusted endpoints to exchange RTP flows through one or more Media Distributor.  Third Party: Any entity that is not an Endpoint, Media Distributor, Key Distributor or Call Processing entity as described in this document. Distributor MUST NOT alone be interpreted as being authorized to have access to the E2E media encryption keys, as the Media Distributor does not have the ability to determine whether an endpoint is <del> authorized. </del>  A Media Distributor MUST perform its role in properly forwarding media packets while taking measures to mitigate the adverse effects of denial of service attacks (refer to attacks), etc, to a level <del> equal to or better than traditional conferencing (i.e. pre-PERC) </del>  deployments. A Media Distributor or associated conferencing infrastructure may Endpoints will take measures to mitigate the adverse effects of denial of service attacks (refer to attacks) from other entities, including from other endpoints, to a level equal to or better than <del> traditional conference (i.e., pre-PERC) deployments. </del>  3.2.2. User Agent would send an INVITE message containing SDP for the media session along with the endpoint's certificate fingerprint, which can be signed using the procedures described in RFC4474 for the benefit <del> of forwarding the message to other entities.  Other entities can now verify the fingerprints match the certificates found in the DTLS-SRTP connections to find the identity of the far end of the DTLS-SRTP connection and check that is the authorized entity. </del>  Ultimately, if using session signaling, an endpoint's certificate fingerprint would need to be securely mapped to a user and conveyed 5.3. <del> The Key Distributor is responsible for knowing what endpoints are allowed in a given conference.  Thus, the Key Distributor and the </del>  Media Distributor will need to know endpoint-to-conference mappings, which is enabled by exchanging a conference-specific unique identifier as defined in I-D.jones-perc-dtls-tunnel.  How this unique

Other than revisiting section 3.1.1 and 5.3 after changes to other drafts are complete, these changes either directly, or in-spirit, address all of the feedback/comments.
Just a couple of comments inline.

Hop-by-Hop (HBH): Communications between an endpoint and a Media Distribution Device or between Media Distribution Devices.  <ins> Trusted Endpoint: An RTP flow terminating entity that has possession of E2E media encryption keys and terminates E2E encryption.  This may </ins> include embedded user conferencing equipment or browsers on computers, media gateways, MCUs, media recording device and more that are in the trusted domain for a given deployment. which includes, but not limited to, having no access to RTP media unencrypted and having limits on what RTP header field it can alter.  <ins> Key Distributor: An entity that is a logical function which distributes keying material and related information to trusted endpoints and Media Distributor(s), only that which is appropriate for each.  The Key Distributor might be co-resident with another entity trusted with E2E keying material. </ins> Conference: Two or more participants communicating via trusted endpoints to exchange RTP flows through one or more Media Distributor. <ins> Call Processing: All tusted endpoints in the conference connect to it by a call processing dialog, such as with the Focus defined in the Framework for Conferencing with SIP RFC4353. </ins> Third Party: Any entity that is not an Endpoint, Media Distributor, Key Distributor or Call Processing entity as described in this document. Distributor MUST NOT alone be interpreted as being authorized to have access to the E2E media encryption keys, as the Media Distributor does not have the ability to determine whether an endpoint is  <ins> authorized.  Trusted endpoint authorization is described in the (add ref to new signaling draft here). </ins> A Media Distributor MUST perform its role in properly forwarding media packets while taking measures to mitigate the adverse effects of denial of service attacks (refer to attacks), etc, to a level  <ins> equal to or better than traditional conferencing (i.e. non-PERC) </ins> deployments. A Media Distributor or associated conferencing infrastructure may Endpoints will take measures to mitigate the adverse effects of denial of service attacks (refer to attacks) from other entities, including from other endpoints, to a level equal to or better than  <ins> traditional conference (i.e., non-PERC) deployments. </ins> 3.2.2. User Agent would send an INVITE message containing SDP for the media session along with the endpoint's certificate fingerprint, which can be signed using the procedures described in RFC4474 for the benefit  <ins> of forwarding the message to other entities by the Focus RFC4353. Other entities can now verify the fingerprints match the certificates found in the DTLS-SRTP connections to find the identity of the far end of the DTLS-SRTP connection and check that is the authorized entity. </ins> Ultimately, if using session signaling, an endpoint's certificate fingerprint would need to be securely mapped to a user and conveyed 5.3.  <ins> The Key Distributor needs to know what endpoints are to being added to in a given conference resource.  Thus, the Key Distributor and the </ins> Media Distributor will need to know endpoint-to-conference mappings, which is enabled by exchanging a conference-specific unique identifier as defined in I-D.jones-perc-dtls-tunnel.  How this unique


5.3. <del> The Key Distributor needs to know what endpoints are to being added to in a given conference resource.  Thus, the Key Distributor and the Media Distributor will need to know endpoint-to-conference mappings, which is enabled by exchanging a conference-specific unique identifier as defined in I-D.jones-perc-dtls-tunnel.  How this unique identifier is assigned is outside the scope of this document. </del>  6.

Fixed typos/deleted extra words in the Conf Id section.
LGTMlooks good.

5.3.  <ins> The Key Distributor needs to know what endpoints are being added to a given conference.  Thus, the Key Distributor and the Media Distributor will need to know endpoint-to-conference mappings, which is enabled by exchanging a conference-specific unique identifier as defined in I-D.jones-perc-dtls-tunnel.  How this unique identifier is assigned is outside the scope of this document. </ins> 6.


5.1. <del> IANA is requested to create a new registry for "EKT Messages Types". The initial values in this registry are: </del>  Note to RFC Editor: Please replace RFCAAAA with the RFC number for this specification. 5.2. <del> IANA is requested to create a new registry for "EKT Ciphers".  The </del>  initial values in this registry are: Note to RFC Editor: Please replace RFCAAAA with the RFC number for

Ignoring my concern and bias over extensibility with EKT :), this looks fine.
Should the registries be part of the SDP or RTP parameters group? I.e., collected together with the other SDP parameters?

5.1.  <ins> IANA is requested to create a new table for "EKT Messages Types" in the "Real-Time Transport Protocol (RTP) Parameters" registry.  The initial values in this registry are: </ins> Note to RFC Editor: Please replace RFCAAAA with the RFC number for this specification. 5.2.  <ins> IANA is requested to create a new table for "EKT Ciphers" in the "Real-Time Transport Protocol (RTP) Parameters" registry.  The </ins> initial values in this registry are: Note to RFC Editor: Please replace RFCAAAA with the RFC number for


The last byte is used to indicate the type of the EKTField.  This MUST be 2 in the FullEKTField format and 0 in ShortEKTField <del> format.  Values less than 64 are mandatory to understand and the whole EKTField SHOULD be discarded if it contains message type value that is less than 64 and is not implemented. </del>  2.2.

If anyone has ideas on how to write this is a more clear way, love any suggestions ...
s2.1, MessageType Maybe it’s late but I’m having trouble parsing this sentence: Values less than 64 are mandatory to understand and the whole EKTField SHOULD be discarded if it contains message type value that is less than 64 and is not implemented. Can “and is not implemented” be dropped?

The last byte is used to indicate the type of the EKTField.  This MUST be 2 in the FullEKTField format and 0 in ShortEKTField  <ins> format.  Values less than 64 are mandatory to understand while other values are optional to understand.  A receiver SHOULD discard the whole EKTField if it contains any message type value that is less than 64 and that is not understood.  Message type values that are 64 or greater but not implemented or understood can simply be ignored. </ins> 2.2.


Each distinct EKT parameter set that is used MUST be associated with a distinct SPI value to avoid ambiguity. <del> All EKT message other that ShortEKTField must have a length as </del>  second from the last element.  This is the length in octets of either the FullEKTField/ExtensionEKTField including this length field and the following message type.

s2.1, EKTMsgLength Should this be “MUST”: All EKT message other that ShortEKTField must have ...

Each distinct EKT parameter set that is used MUST be associated with a distinct SPI value to avoid ambiguity.  <ins> All EKT message other that ShortEKTField MUST have a length as </ins> second from the last element.  This is the length in octets of either the FullEKTField/ExtensionEKTField including this length field and the following message type.


When an SRTP or SRTCP packet contains a ShortEKTField, the ShortEKTField is removed from the packet then normal SRTP or SRTCP processing occurs.  If the packet contains a FullEKTField, then <del> processing continues as described below. </del>  The Security Parameter Index (SPI) field is used to find which EKT parameter set to be used when processing the packet.  If there is

Does this way of phrasing it look better ?
2) s2.2.2, : I gotta ask why the MessageType byte isn’t first? Wouldn’t putting the MessageType first allow you avoid buffering everything before proceeding? It seems like you’re counting on nobody sending a string of zeros as the first byte of the EKT field to mess with implementations.

When an SRTP or SRTCP packet contains a ShortEKTField, the ShortEKTField is removed from the packet then normal SRTP or SRTCP processing occurs.  If the packet contains a FullEKTField, then  <ins> processing continues as described below.  The reason for using the last byte of the packet to indicate the type is that the length of the SRTP or SRTCP part is not known until the decryption has occurred.  At this point in the processing, there is no easy way to know where the EKT field would start.  However, the whole UDP packet has been received so instead of the starting at the front of the packet, the parsing works backwards off the end of the packet and thus the type is put at the very end of the packet. </ins> The Security Parameter Index (SPI) field is used to find which EKT parameter set to be used when processing the packet.  If there is


Distributor MUST NOT alone be interpreted as being authorized to have access to the E2E media encryption keys, as the Media Distributor does not have the ability to determine whether an endpoint is <del> authorized.  Trusted endpoint authorization is described in the (add ref to new signaling draft here). </del>  A Media Distributor MUST perform its role in properly forwarding media packets while taking measures to mitigate the adverse effects between an endpoint and the Key Distributor.  To establish this association, an endpoint will send DTLS-SRTP messages to the Media Distributor which will then forward them to the Key Distributor as <del> defined in I-D.jones-perc-dtls-tunnel.  The Key Encryption Key (KEK) (i.e., EKTKey) is also conveyed by the Key Distributor over the DTLS association to endpoints via procedures defined in PERC EKT [I- </del>  D.ietf-perc-srtp-ekt-diet]. Media Distributors use DTLS-SRTP RFC5764 directly with a peer Media 4.5.1. <del> The procedures defined in DTLS Tunnel for PERC I-D.jones-perc-dtls- tunnel establish one or more TLS tunnels between the Media </del>  Distributor and Key Distributor, making it is possible for the Media Distributor to facilitate the establishment of a secure DTLS association between each endpoint and the Key Distributor as shown given conference.  Thus, the Key Distributor and the Media Distributor will need to know endpoint-to-conference mappings, which is enabled by exchanging a conference-specific unique identifier as <del> defined in I-D.jones-perc-dtls-tunnel.  How this unique identifier is assigned is outside the scope of this document. </del>  6.

Changed reference to Tunnel and added an (interim) reference to Roach's PERC signaling draft
Added the actual reference to ietf-roach-perc-webrtc in the body.
LGTM

Distributor MUST NOT alone be interpreted as being authorized to have access to the E2E media encryption keys, as the Media Distributor does not have the ability to determine whether an endpoint is  <ins> authorized.  Trusted endpoint authorization is described in WebRTC Signaling for PERC I-D.ietf-roach-perc-webrtc. </ins> A Media Distributor MUST perform its role in properly forwarding media packets while taking measures to mitigate the adverse effects between an endpoint and the Key Distributor.  To establish this association, an endpoint will send DTLS-SRTP messages to the Media Distributor which will then forward them to the Key Distributor as  <ins> defined in I-D.draft-ietf-perc-dtls-tunnel.  The Key Encryption Key (KEK) (i.e., EKTKey) is also conveyed by the Key Distributor over the DTLS association to endpoints via procedures defined in PERC EKT [I- </ins> D.ietf-perc-srtp-ekt-diet]. Media Distributors use DTLS-SRTP RFC5764 directly with a peer Media 4.5.1.  <ins> The procedures defined in DTLS Tunnel for PERC I-D.draft-ietf-perc- dtls-tunnel establish one or more TLS tunnels between the Media </ins> Distributor and Key Distributor, making it is possible for the Media Distributor to facilitate the establishment of a secure DTLS association between each endpoint and the Key Distributor as shown given conference.  Thus, the Key Distributor and the Media Distributor will need to know endpoint-to-conference mappings, which is enabled by exchanging a conference-specific unique identifier as  <ins> defined in I-D.draft-ietf-perc-dtls-tunnel.  How this unique identifier is assigned is outside the scope of this document. </ins> 6.


The following shows the syntax of the EKTField expressed in ABNF RFC5234.  The EKTField is added to the end of an SRTP or SRTCP <del> packet.  The EKTCiphertext is computed by encrypting the EKTPlaintext using the EKTKey.  Future extensions to the EKTField MUST conform to the syntax of ExtensionEKTField. </del>  These fields and data elements are defined as follows:

s2.1, EKTPlaintext Probably over thinking this, but is the concatentation like so: +--------------+--------+--------+ +-------------+---------+--------+ I’d be afraid somebody would think it’s the other way around without being more specific. Maybe it’s as easy as: putting something like "SRTP MK denotes concatenation” s omewhere in the paragraph.

The following shows the syntax of the EKTField expressed in ABNF RFC5234.  The EKTField is added to the end of an SRTP or SRTCP  <ins> packet.  The EKTPlaintext is the concatenation of SRTPMasterKeyLength, SRTPMasterKey, SSRC, and ROC in that order.  The EKTCiphertext is computed by encrypting the EKTPlaintext using the EKTKey.  Future extensions to the EKTField MUST conform to the syntax of ExtensionEKTField. </ins> These fields and data elements are defined as follows:


EKT MUST NOT be used in conjunction with SRTP's MKI (Master Key Identifier) or with SRTP's <From, To> RFC3711, as those SRTP features <del> duplicate some of the functions of EKT. </del>  2.1.

Section 2 (para 2) EKT MUST NOT be used in conjunction with SRTP's MKI (Master Key Identifier) or with SRTP's [RFC3711], as those SRTP features duplicate some of the functions of EKT. Same issue has be raised by Spt >>>What happens if an implementation does use SRTP's MKI or with SRTP's ? Is an error thrown?
I do expect they'd check, because they have to know how to parse the packet and where to insert the EKT field. With EKT, the key to use is conveyed via the RTP packet. Only after the EKT field is parsed would it make sense to look to find an MKI value. In any case, if MKI is used it's just redundant. One thing I didn't see in reviewing the current specs is where the EKT field should be inserted. It should be inserted on the inner encryption step of double. The outer encryption is consumed by intermediaries and they don't understand EKT. We probably need to put that back into the framework document. The packet format was removed during one revision.
opened new bug for where EKT goes

EKT MUST NOT be used in conjunction with SRTP's MKI (Master Key Identifier) or with SRTP's <From, To> RFC3711, as those SRTP features  <ins> duplicate some of the functions of EKT.  Senders MUST not include MKI when using EKT.  Receivers SHOULD simply ignore any MKI field received if EKT is in use. </ins> 2.1.


Each distinct EKT parameter set that is used MUST be associated with a distinct SPI value to avoid ambiguity. <del> All EKT message other that ShortEKTField MUST have a length as second from the last element.  This is the length in octets of either the FullEKTField/ExtensionEKTField including this length field and the following message type. </del>  The last byte is used to indicate the type of the EKTField.  This MUST be 2 in the FullEKTField format and 0 in ShortEKTField values over odd ones until the even code points are consumed to avoid conflicts with pre standard versions of EKT that have been deployed.  5.2. IANA is requested to create a new table for "EKT Ciphers" in the

EKTMsgLength All EKT message other that ShortEKTField must have a length as second from the last element. This is the length in octets of either the FullEKTField/ExtensionEKTField including this length field and the following message type.

Each distinct EKT parameter set that is used MUST be associated with a distinct SPI value to avoid ambiguity.  <ins> All EKT message other that ShortEKTField have a length as second from the last element.  This is the length in octets of either the FullEKTField/ExtensionEKTField including this length field and the following message type. </ins> The last byte is used to indicate the type of the EKTField.  This MUST be 2 in the FullEKTField format and 0 in ShortEKTField values over odd ones until the even code points are consumed to avoid conflicts with pre standard versions of EKT that have been deployed. <ins> All new EKT messages MUST be defined to have a length as second from the last element. </ins> 5.2. IANA is requested to create a new table for "EKT Ciphers" in the


2.2.2. <del> When receiving a packet on a RTP stream where EKT was negotiated, the following steps are applied for each received packet. </del>  The final byte is checked to determine which EKT format is in use. When an SRTP or SRTCP packet contains a ShortEKTField, the

Inbound Processing When receiving a packet on a RTP stream where EKT was negotiated, the following steps are applied for each received packet.
I don't think you can ever receive non EKT packets on a flow with EKT negotiated. That is to say know from the SDP when you get a SRTP packet if it is EKT or not
Use of EKT must be negotiated in signalling on a per session basis. In the case of PERC, all multiplexed flows must use EKT. For WebRTC, that should also be true, unless a determination can be made based on the payload type. That actually raises a question. How are PERC endpoints supposed to construct the SDP for PERC that indicates use of DTLS? Is that going to be in Adam's draft? PERC endpoints are always required to initiate the DTLS association.
Framework and Signaling draft should sum up the usage of this.
More reason to delay framework until we know we've covered everything.
Framework is not getting published anytime soon . We have time :)

2.2.2.  <ins> When receiving a packet on a RTP stream, the following steps are applied for each received packet. </ins> The final byte is checked to determine which EKT format is in use. When an SRTP or SRTCP packet contains a ShortEKTField, the


2.3. EKT uses an authenticated cipher to encrypt and authenticate the <del> EKTPlaintext.  We first specify the interface to the cipher, in order to abstract the interface away from the details of that function.  We then define the cipher that is used in EKT by default.  The default cipher described in DefaultCipher MUST be implemented, but another cipher that conforms to this interface MAY be used, in which case its use MUST be coordinated by external means (e.g., key management). </del>  An EKTCipher consists of an encryption function and a decryption function.  The encryption function E(K, P) takes the following

Section 2.3 Ciphers EKT uses an authenticated cipher to encrypt and authenticate the EKTPlaintext. We first specify the interface to the cipher, in order to abstract the interface away from the details of that function. We then define the cipher that is used in EKT by default. The default cipher described in Section 2.3.1 MUST be implemented, but another cipher that conforms to this interface MAY be used, in which case its use MUST be coordinated by external means (e.g., key management).
Fixed by

2.3. EKT uses an authenticated cipher to encrypt and authenticate the  <ins> EKTPlaintext.  This specification defines the interface to the cipher, in order to abstract the interface away from the details of that function.  This specification also defines the default cipher that is used in EKT.  The default cipher described in DefaultCipher MUST be implemented, but another cipher that conforms to this interface MAY be used. </ins> An EKTCipher consists of an encryption function and a decryption function.  The encryption function E(K, P) takes the following


normal SRTP or SRTCP processing takes place including replay protection. <del> 2.2.2.1. </del>  The value of the EKTCiphertext field is identical in successive packets protected by the same EKT parameter set and the same SRTP that out of order packets can be processed as well as packets sent during the time keys are changing. <del> 2.3. </del>  EKT uses an authenticated cipher to encrypt and authenticate the EKTPlaintext.  This specification defines the interface to the These functions have the property that D(K, E(K, P)) = ( P concatenated with optional padding) for all values of K and P.  Each cipher also has a limit T on the number of times that it can be used <del> with any fixed key value.  The EKTKey MUST NOT be used more that T times. </del>  Security requirements for EKT ciphers are discussed in sec. <del> 2.3.1. </del>  The default EKT Cipher is the Advanced Encryption Standard (AES) Key Wrap with Padding RFC5649 algorithm.  It requires a plaintext length As AES-128 is the mandatory to implement transform in RFC3711, AESKW128 MUST be implemented for EKT and AESKW256 MAY be implemented. <del> 2.3.2. </del>  Other specifications may extend this document by defining other EKTCiphers as described in iana.  This section defines how those an input.  The values of the parameters L, and T MUST be defined by each EKTCipher. <del> 2.4. </del>  If a source has its EKTKey changed by the key management, it MUST also change its SRTP master key, which will cause it to send out a master key, so that traffic can be decrypted only by those who know the current EKTKey. <del> 2.5. </del>  EKT SHOULD be used over SRTP, and other specification MAY define how to use it over SRTCP.  SRTP is preferred because it shares fate with for RTCP transmission limits, and to avoid SRTCP compound packets with RTP translators and mixers. <del> 2.6. </del>  A system using EKT learns the SRTP master keys distributed with FullEKTFields sent with the SRTP, rather than with call signaling.  A helps mitigate this issue. Each EKT cipher specifies a value T that is the maximum number of <del> times a given key can be used.  An endpoint MUST NOT send more than T Full EKT Field using the same EKTKey.  In addition, the EKTKey MUST NOT be used beyond the lifetime provided by the TTL described in dtls-srtp-extensions. </del>  The confidentiality, integrity, and authentication of the EKT cipher MUST be at least as strong as the SRTP cipher and at least as strong

,
Changes look good , except for few typos .
Nothing to add beyond Suhas' comments.
Section 4 Each EKT cipher specifies a value T that is the maximum number of times a given key can be used. An endpoint MUST NOT send more than T Full EKT Field using the same EKTKey. In addition, the EKTKey MUST NOT be used beyond the lifetime provided by the TTL described in Section 3.2.
ektttl: The maximum amount of time, in seconds, that this ektkeyvalue can be used. The ektkey_value in this message MUST NOT be used for encrypting or decrypting information after the TTL expires.
These functions have the property that D(K, E(K, P)) = ( P concatenated with optional padding) for all values of K and P. Each cipher also has a limit T on the number of times that it can be used with any fixed key value. The EKTKey MUST NOT be used more that T times.

normal SRTP or SRTCP processing takes place including replay protection.  <ins> 2.3. </ins> The value of the EKTCiphertext field is identical in successive packets protected by the same EKT parameter set and the same SRTP that out of order packets can be processed as well as packets sent during the time keys are changing.  <ins> When receiving a new EKTKey, implementations need to use the ekt_ttl to create a time after which this key cannot be used and they also need to create a counter that keeps track of how many times the keys has been used to encrypt data to ensure it does not exceed the T value for that cipher.  If either of theses limits are exceeded, the key can no longer be used for encryption.  At this point implementation need to either use the call signaling to renegotiation a new session or need to terminate the existing session.  Terminating the session is a reasonable implementation choice because theses limits should not be exceeded except under an attack or error condition. 2.4. </ins> EKT uses an authenticated cipher to encrypt and authenticate the EKTPlaintext.  This specification defines the interface to the These functions have the property that D(K, E(K, P)) = ( P concatenated with optional padding) for all values of K and P.  Each cipher also has a limit T on the number of times that it can be used  <ins> with any fixed key value.  The EKTKey MUST NOT be used for encryption more that T times.  Note that if the same EKT packet is retransmitted 3 times, that only counts as 1 encryption. </ins> Security requirements for EKT ciphers are discussed in sec.  <ins> 2.4.1. </ins> The default EKT Cipher is the Advanced Encryption Standard (AES) Key Wrap with Padding RFC5649 algorithm.  It requires a plaintext length As AES-128 is the mandatory to implement transform in RFC3711, AESKW128 MUST be implemented for EKT and AESKW256 MAY be implemented.  <ins> 2.4.2. </ins> Other specifications may extend this document by defining other EKTCiphers as described in iana.  This section defines how those an input.  The values of the parameters L, and T MUST be defined by each EKTCipher.  <ins> 2.5. </ins> If a source has its EKTKey changed by the key management, it MUST also change its SRTP master key, which will cause it to send out a master key, so that traffic can be decrypted only by those who know the current EKTKey.  <ins> 2.6. </ins> EKT SHOULD be used over SRTP, and other specification MAY define how to use it over SRTCP.  SRTP is preferred because it shares fate with for RTCP transmission limits, and to avoid SRTCP compound packets with RTP translators and mixers.  <ins> 2.7. </ins> A system using EKT learns the SRTP master keys distributed with FullEKTFields sent with the SRTP, rather than with call signaling.  A helps mitigate this issue. Each EKT cipher specifies a value T that is the maximum number of  <ins> times a given key can be used.  An endpoint MUST NOT encrypt more than T different Full EKT Field using the same EKTKey.  In addition, the EKTKey MUST NOT be used beyond the lifetime provided by the TTL described in dtls-srtp-extensions. </ins> The confidentiality, integrity, and authentication of the EKT cipher MUST be at least as strong as the SRTP cipher and at least as strong


longer than needed by SRTP, then it is truncated by taking the first N bytes from the srtp_master_salt field.  The SRTP Master Key, ROC, and SRTP Master Salt from the previous step are saved in a map indexed by the SSRC found in the EKTPlaintext and can be used for any future crypto operations on

This is a very substantial change. I suspect it is correct but given text in security section but think carefully about if this breaks anything.
Section 4 The presence of the SSRC in the EKTPlaintext ensures that an attacker cannot substitute an EKTCiphertext from one SRTP stream into another SRTP stream.
I think this is right.

longer than needed by SRTP, then it is truncated by taking the first N bytes from the srtp_master_salt field. <ins> If the SSRC in the EKTPlaintext does not match the SSRC of the SRTP packet, then all the information from this EKTPlaintext MUST be discarded and the following steps in this list are not done. </ins> The SRTP Master Key, ROC, and SRTP Master Salt from the previous step are saved in a map indexed by the SSRC found in the EKTPlaintext and can be used for any future crypto operations on


and SRTCP traffic. Either the FullEKTField or ShortEKTField is appended at the tail end <del> of all SRTP packets. </del>  2.2.1.

There is slight mention of i frames but they get called "intra coded video frames"
Either the FullEKTField or ShortEKTField is appended at the tail end of all SRTP packets.
Pointing to the section looks good This is ok. I reviewed the timing section briefly, but didn't see mention of I-frame or key frame packets. That's another good time to provide the full EKT field.

and SRTCP traffic. Either the FullEKTField or ShortEKTField is appended at the tail end  <ins> of all SRTP packets.  The decision on which to send is specified in timing. </ins> 2.2.1.


An attacker who tampers with the bits in FullEKTField can prevent the intended receiver of that packet from being able to decrypt it.  This <del> is a minor denial of service vulnerability. </del>  An attacker could send packets containing a Full EKT Field, in an attempt to consume additional CPU resources of the receiving system

Does this look like a problem to you guys or am I missing the boat on something ?
Decryption might fail if it's not the right key or if the ROC is old. Yes, that can happen. However, what implementations should do is keep the old and new key and try both. I'm not sure if this is spelled out, but that would be ideal since it's possible to get out-of-order packets and the old key might be needed for the next packet received. No. A sender's transmit key is independent of another sender's transmit key. There's nothing to suggest a relationship to a conference key, except that the conference key is used to encrypt the EKT field. But, one should definitely not re-use an old conference key to transmit packets and conference keys should be discarded fairly soon, because a change in conference key is rather significant (e.g., a user left the conference and media should no longer use any old keys). Yes, by putting yet another auth tag on the packet, but I would not suggest it since the packet is getting large. An alternative is to compute the EKT tag and authenticate that using the E2E cipher. For AES GCM, treat the EKT Field as "additional authenticated data" (AAD). As an implementation challenge, though, I believe that most ciphers assume that all AAD to be included in the AES GCM processing must be in contiguous memory and libsrtp (and I suspect any other such library) does not allocate memory for per-packet processing for good reason (lots of mallocs of varying lengths that must be securely erased), which would be necessary since the other AAD is in the RTP header. But, it wouldn't be too bad if we changed the libsrtp API to allow the application to provide a buffer that the library can use to copy the data from the header and then concatenate the EKT field. The size of that buffer can be prescribed in terms of the size of the RTP header + max length of the EKT field (which is a known size). It is also possible to use a different "alternative initialization vector" (AIV) in the AES Key Wrap logic. By default, the AIV is 0xA65959A6. We could provide alternative values based on the current packet (e.g., effectiveaiv = (ROC XOR seqnum XOR defaultaiv) and put the ROC in the clear (since it's not secret). This would immediately tell the receiving endpoint that the EKT field is bad before we start E2E packet processing. (It would not be useful in detecting HBH manipulation.) However, I don't think we need to do these things. When a packet is received by a receiving endpoint, it will extract the EKT key if the EKT field properly decrypts. It should not immediately assume that's a valid key, though, because that could been produced by another endpoint and thrown in there by the hacker. The endpoint should first attempt to use the key during the E2E decipher phase. If it works, then add it to the front of the key list and set it as the active key. If the key fails to decrypt during E2E processing, then the EKT field was bad and the key should be discarded. So, in the worst case a bogus EKT field results in attempting to decrypt the packet and failing. It's no different than if the hacker manipulated the packet payload anywhere else. Granted, manipulating other places will cause a failure on HBH decryption, but failing on E2E decryption is not significantly worse. Just one more decryption cycle. DoS is achieved either way. (I mention "key list" as I think receivers should keep two old key around for a short time just in case there are out-of-order packets. I don't think timing the retention is important. They older keys could be kept indefinitely or perhaps purged after processing some number n packets, such as associating the key with the extended sequence number with which the key was last used. Purge could happen when a key search is performed. But, keeping three indefinitely is simpler logic.)
Yah, that makes sense. I'll try and update some text explaining this but not change how anything works.
OK - be great of folks could take another skim of this one
Concern: >>>Based on the DoS security consideration, it appears as if you’re okay with the EKT field not be protected by SRTP. (he asks without having dug into SRTP in a while) There’s really no way to get at integrity protection of the EKT field?
So the AESKeyWrap has it's own integrity protection. And the SSRC inside that has to match SRTP to make sure that it applies to the correct one.
Yeah. AES Key Wrap is self-authenticated by design.

An attacker who tampers with the bits in FullEKTField can prevent the intended receiver of that packet from being able to decrypt it.  This  <ins> is a minor denial of service vulnerability.  Similarly the attacker could take an old FullEKTField from the same session and attach it to the packet.  The FullEKTField would correctly decode and pass integrity but the key extracted from the FullEKTField , when used to decrypt the SRTP payload, would be wrong and the SRTP integrity check would fail.  Note that the FullEKTField only changes the decryption key and does not change the encryption key.  None of these are considered significant attacks as any attacker that can modify the packets in transit and cause the integrity check to fail. </ins> An attacker could send packets containing a Full EKT Field, in an attempt to consume additional CPU resources of the receiving system


[!@RFC5246].  This section provides an example of what the bits on the wire would look like for the <del> message that advertises support for both SRTP_AEAD_AES_128_GCM and SRTP_AEAD_AES_256_GCM RFC7714. </del>  Thus, the encoding on the wire presented here in network bytes order would be this stream of octets:

This is a rebased version of from last October.
You want the MDD to be told "use DOUBLEAEADAES128GCMAEADAES128GCM", when it will actually only do have of it?
Another question: can we change the words "if IANA assigned" to something concrete? That is, we just make this assumption. Then, insert a note to RFC Editor to adjust these values as necessary before publication?
On MDD told to do double ... The TLS has to negotiate double or the endpoints will not do double. The endpoints can only do what is negotiated inside of TLS. Keep in mind our desing goal here is to minimize the code changes outside libsrtp to the endpoints and not worry too much about the amount of code on MDD and KDD. On IANA - yah fine with changing this to an RFC editor note to change values to whatever IANA assigned. I think we are at the point where we could have the chairs ask IANA for an early assignment to help pre standard implementations write code.

[!@RFC5246].  This section provides an example of what the bits on the wire would look like for the  <ins> message that advertises support for both DOUBLE_AEAD_AES_128_GCM_AEAD_AES_128_GCM and DOUBLE_AEAD_AES_256_GCM_AEAD_AES_256_GCM I-D.ietf-perc-double. RFC Editor Note: Please replace the values 0009 and 000A in the following two examples with whatever code points IANA assigned for DOUBLE_AEAD_AES_128_GCM_AEAD_AES_128_GCM and DOUBLE_AEAD_AES_256_GCM_AEAD_AES_256_GCM. </ins> Thus, the encoding on the wire presented here in network bytes order would be this stream of octets:


cryptographic context and then encrypts using the outer cryptographic context.  The processes is as follows:  5.2. The Media Distributor does not have a notion of outer or inner

You can't think of this as SRTP tunneled inside of SRTP. It's not. It is SRTP done once with a crypto transform called "double" and with a single key. Double has the weird property that if you know half the key, it ends up only decrypting half the the data for you. The endpoints know the full key, the MDD only half the key, and the both the endpoints and the MMD have to do double.
Make sure specs are clear on this
wondering where size ends up
Which size?
That aligns with what you said you preferred. It's certainly easier to explain in words here. But, it will be more challenging for MDDs to explain. Since we are using the same cipher and the ciphertext will have a constant size, we can do in-place authenticated encryption and not destroy the EKT field in the process. So performance will not be affected on the middle box. But, we need to explain this somewhere for the media distributor. Maybe the right place to explain that is when we also show an example of the packet format. I can see that expanding to be processing rules for endpoints and the media distributor.

cryptographic context and then encrypts using the outer cryptographic context.  The processes is as follows: <ins> When using EKT I-D.ietf-perc-srtp-ekt-diet, the EKT Field comes after the SRTP packet exactly like using EKT with any other SRTP transform. </ins> 5.2. The Media Distributor does not have a notion of outer or inner


"unexpected_version"  Note: sometimes packets are dropped before they can be associated with a particular connection (e.g., in case of "unsupported_version").  This situation is discussed in handling-

There are two conditions an Initial packet has to fulfill: It's DCID must be >= 8 bytes long. The size of the datagram must be >= 1200. None of the other triggers for the event seem appropriate for this.

"unexpected_version" <ins> "invalid_initial" </ins> Note: sometimes packets are dropped before they can be associated with a particular connection (e.g., in case of "unsupported_version").  This situation is discussed in handling-


<del> HTTP/3 and QPACK event definitions for qlog </del>  draft-ietf-quic-qlog-h3-events-latest Abstract

Fixes part of . The changes are tedious but also not too onerous. The main issue you have is that there's lots of comments here and there that break length limits. So I've just picked a line length that will appease xml2rfc. The changes you have in mind might have obviated the errors anyway. But if not, these changes will set a strong foundation to know how to shut xml2rfc up.
According to the official IETF draft guidelines, line length should not be longer than 72 ASCII characters (URL, and URL). For some reason, I had previously understood this to be 82 characters, and so the current texts are 10 characters too wide... Since this will be somewhat of a tedious process (which can be done largely automatically but with manual checks) which will impact allmost all parts of the documents, I propose we do this in a single burst somewhere down the line. cc NAME
Chatted a bit with rmarx offline. The errors that xml2rfc moans about are about artwork, not body text etc. Over the 3 PRs I created, there might look like a lot of churn but it is all constrained to the artwork pieces. In my opinion, it's better to fix these now (or nullify the json validation errors) so that we don't start ignoring things that exist or get newly introduced.
This should be fixed as of main-schema-02 and h3/quic-events-01. For future reference: hard limit of 72 is only needed inside "figures" (including code blocks!). Running text paragraphs/lists/etc. can be done by the tooling itself.

<ins> HTTP/3 and QPACK qlog event definitions </ins> draft-ietf-quic-qlog-h3-events-latest Abstract


This document describes the values of the qlog name ("category" + "event") and "data" fields and their semantics for the QUIC protocol. <del> This document is based on draft-34 of the QUIC I-Ds QUIC-RECOVERY QUIC-TLS.  HTTP/3 and QPACK events are defined in a separate document QLOG-H3. </del>  Feedback and discussion are welcome at https://github.com/quicwg/qlog [1].  Readers are advised to refer to the "editor's draft" at that

quic: fix artwork line length quic: stick commas between refs to unfool xml2rfc Fixes part of URL The changes are tedious but also not too onerous. The main issue you have is that there's lots of comments here and there that break length limits. So I've just picked a line length that will appease xml2rfc. The changes you have in mind might have obviated the errors anyway. But if not, these changes will set a strong foundation to know how to shut xml2rfc up.
According to the official IETF draft guidelines, line length should not be longer than 72 ASCII characters (URL, and URL). For some reason, I had previously understood this to be 82 characters, and so the current texts are 10 characters too wide... Since this will be somewhat of a tedious process (which can be done largely automatically but with manual checks) which will impact allmost all parts of the documents, I propose we do this in a single burst somewhere down the line. cc NAME
Chatted a bit with rmarx offline. The errors that xml2rfc moans about are about artwork, not body text etc. Over the 3 PRs I created, there might look like a lot of churn but it is all constrained to the artwork pieces. In my opinion, it's better to fix these now (or nullify the json validation errors) so that we don't start ignoring things that exist or get newly introduced.
This should be fixed as of main-schema-02 and h3/quic-events-01. For future reference: hard limit of 72 is only needed inside "figures" (including code blocks!). Running text paragraphs/lists/etc. can be done by the tooling itself.

This document describes the values of the qlog name ("category" + "event") and "data" fields and their semantics for the QUIC protocol.  <ins> This document is based on draft-34 of the QUIC I-Ds QUIC-TRANSPORT, QUIC-RECOVERY, and QUIC-TLS.  HTTP/3 and QPACK events are defined in a separate document QLOG-H3. </ins> Feedback and discussion are welcome at https://github.com/quicwg/qlog [1].  Readers are advised to refer to the "editor's draft" at that


While DPLPMTUD is optional, there's an about it in QUIC transport. Minimal support for this in qlog would define an event for every increase of the MTU: I don't think we need a separate event for the sending of an MTU probe packet, but we should probably standardize a for this. Suggestion: . Open question: Do we want a separate failure event? Failure would be either the loss of an MTU probe packet, or (for implementations that pay attention to ICMP packets) the receipt of an ICMP Packet Too Big (PTB) message.
I agree it would be useful to have this information in qlog. In terms of design, as always there are several options: 1) have separate events for this (, , , etc.) 2) integrate them into existing events( triggers on and , new field in ) 3) a combination of these approaches (which is what you suggest IIUC) This is imo a good example of where we need clear design guidelines on how to add new information/events to qlog.
Revisiting this after a long time: is problematic, as this would essentially be a copy of the normal event (it is allowed, although not recommended, to just send normal application data as a probe packet). The trigger seems to be the best solution here needs to be a separate event, there's just no way we can reasonably collapse this into an acknowledgment event is what I'm still undecided about. This logically belongs to the regular event, we'd just need a way to attach "oh and by the way, this was a MTU probe packet". In fact, it would be really useful to have it on that event, since the congestion control implications are very different for lost MTU packets (i.e., you wouldn't decrease your cwnd).
I have to disagree with myself here. The sending of the packet might have been triggered by something else, it's just that the stack decided to send a probe packet. I suggest: Add a optional on the and events. Add a event.
Supporting DPLPMTUTD events seems important to cover in the base specs.

Definition: <ins> 3.5. Importance: Extra This event indicates that the estimated Path MTU was updated.  This happens as part of the Path MTU discovery process. </ins> 4. TBD


inclusion, log aggregation, event grouping and log file size reduction techniques.  Feedback and discussion are welcome at https://github.com/quicwg/qlog [1].  Readers are advised to refer to the "editor's draft" at that URL for an up-to-date version of this document. have a string key that maps to any value.  Used to indicate a generic JSON object.  1.1.2. <del> While the qlog schemas are format-agnostic, and can be serialized in many ways (e.g., JSON, CBOR, protobuf, ...), this document only describes how to employ JSON, its subset I-JSON, and its streamable derivative JSON-Text-Sequences as textual serialization options.  As such, examples are provided in JSON.  Other documents may describe how to utilize other concrete serialization options, though tips and requirements for these are also listed in this document (concrete- formats). </del>  2.

There's too much text here that doesn't aid the reader. Delete it to be clear that we're using JSON as the notational convention for examples. If this text was valuable, it should be somewhere else.
I still feel we should have a "forward reference" here, indicating that we also discuss I-JSON and Streaming JSON considerations in this document, rather than making it seem we only do "pure JSON" due to the examples. Put differently, something like this should still be mentioned in this location imo:
But the fact it can be serialized to I-JSON has nothing to do with notational conventions used in this document, because we don't use any I-JSON.
NAME I just pushed a commit with a proposal to split up the original text to keep only a minimal amount in "Notational Conventions" but keep the core message alive in the introduction (which seemed the most logical location for now). I added the "unless otherwise indicated", as there are some examples of JSON-SEQ near the end of the document that obviously don't use RFC8259 notation directly. Please review and if approved, merge :)

inclusion, log aggregation, event grouping and log file size reduction techniques. <ins> The qlog schema can be serialized in many ways (e.g., JSON, CBOR, protobuf, etc).  This document describes only how to employ JSON, its subset I-JSON, and its streamable derivative JSON-Text-Sequences. </ins> Feedback and discussion are welcome at https://github.com/quicwg/qlog [1].  Readers are advised to refer to the "editor's draft" at that URL for an up-to-date version of this document. have a string key that maps to any value.  Used to indicate a generic JSON object. <ins> All timestamps and time-related values (e.g., offsets) in qlog are logged as "float64" in the millisecond resolution. Other qlog documents can define their own CDDL-compatible (struct) types (e.g., separately for each Packet type that a protocol supports). </ins> 1.1.2.  <ins> Serialization examples in this document use JSON (JSON) unless otherwise indicated. </ins> 2.


For now, infer from other connectivity events and path_challenge/ path_response frames  3.2. 3.2.1. Definition: <del> 3.5. Importance: Extra This event indicates that the estimated Path MTU was updated.  This happens as part of the Path MTU discovery process. </del> 4. TBD

Updates as that had some problems: used instead of for CDDL type in some of the definitions (not in others)... Made a separate category for the event. It's debatable imo whether it belongs in or , but it shouldn't be its own thing. In general, I feel was approved/merged too soon and this type of things should be checked for future PRs of a similar type.
Changes look good to me. First of all, sorry for messing up the type name. I'm not sure I agree that it was merge too soon though, was open for 3 months, and was approved by one of the editors. Sometimes it's better to make progress instead of not moving at all, even if some cleanup is necessary later.
NAME no problem, I mess up way worse than that :) Let me rephrase that to just "approved" too soon then, instead of "merged" too soon (which is again perfectly understandable with Lucas not used to watching for that type of issue, just wanted to indicate future approvals should).
From the discussion in , it seems better to keep this consistent with other events. Also noticed I forgot to prefix the event with Connectivity and add it to the CDDL list on the bottom...
Sorry if that's a stupid question, but why do we have an and a field here? I thought you can only set it once. Originally posted by NAME in URL
This is a fair question. This is most likely a copy-paste from one of the events (can't find evidence that this was once called StreamTypeUpdated though...) For updates this makes sense, but if the StreamType is only ever set once after becoming known, it would be better to change the definition to e.g., (note, is from ) :

For now, infer from other connectivity events and path_challenge/ path_response frames <ins> 3.1.9. Importance: Extra This event indicates that the estimated Path MTU was updated.  This happens as part of the Path MTU discovery process. </ins> 3.2. 3.2.1. Definition:  4. TBD


Additionally, this document defines the following custom types for clarity:  The main general CDDL syntax conventions in this document a reader should be aware of for easy reading comprehension are: have a string key that maps to any value.  Used to indicate a generic JSON object. <del> All timestamps and time-related values (e.g., offsets) in qlog are logged as "float64" in the millisecond resolution. Other qlog documents can define their own CDDL-compatible (struct) types (e.g., separately for each Packet type that a protocol supports). </del> 1.1.2. While the qlog schemas are format-agnostic, and can be serialized in

In the main schema document, there's a a chunk of text that says: The danger with restating things like this is that there is some subtle problem or incompatibility with the canonical CDDL source citation. I appreciate the QUIC WG might not be familiar with this syntax, so it's handy. But the long-term problems a more insidious. Consider replacing it with deep links to CDDL syntax, or sticking it behind a note that it will be removed prior to publication.
Yes, the intent is to remove this prior to publication. It's just there to make early adoption easier for now. Will look up how to properly add such a note (not sure if there's something default in the kramdown for that) and add it.

Additionally, this document defines the following custom types for clarity: <ins> All timestamps and time-related values (e.g., offsets) in qlog are logged as "float64" in the millisecond resolution. Other qlog documents can define their own CDDL-compatible (struct) types (e.g., separately for each Packet type that a protocol supports). </ins> The main general CDDL syntax conventions in this document a reader should be aware of for easy reading comprehension are: have a string key that maps to any value.  Used to indicate a generic JSON object.  1.1.2. While the qlog schemas are format-agnostic, and can be serialized in


8. <del> TBD </del>  9. 9. <del> TBD </del>  10. 9. <del> TODO : discuss privacy and security considerations (e.g., what NOT to log, what to strip out of a log before sharing, ...) TODO: strip out/don't log IPs, ports, specific CIDs, raw user data, exact times, HTTP HEADERS (or at least :path), SNI values TODO: see if there is merit in encrypting the logs and having the server choose an encryption key (e.g., sent in transport parameters) Good initial reference: Christian Huitema's blogpost [12] </del>  10. [10] https://github.com/quiclog/quictrace2qlog [11] https://qvis.edm.uhasselt.be <del> [12] https://huitema.wordpress.com/2020/07/21/scrubbing-quic-logs- for-privacy/ </del>

Adding high-level discussion of privacy and security considerations operators should take into account. This will walk a fine line between being too high-level/vague and trying to do too much in a qlog document that should be done in a more general IETF document that discusses these issues for all possible log formats, not just qlog.
This is a solid start. I think it treads the line well about what should be discussed in the scope of qlog. There might be a small discussion about whether we should mention so many QUIC things in the main schema, rather than in the qlog schema, but at the moment I'd fall on the side of leaving them here.
NAME I have now processed all of your comments, with 2 that probably deserve an extra look. The overall structure is more consistent now, and concrete QUIC/TLS/HTTP mentions are now clear as examples of data types, rather than specific data fields in qlog themselves. I think this is ready for broader review (and as we discussed yesterday, a first merge into the main doc if it can be approved by the editors here). The main missing part is a proper reference to a recent differential privacy survey/discussion which I still need to research (suggestions welcome!). I will also add a section to the event documents that references back to this soon.
NAME Thank you for the review and extensive comments. In discussion with NAME and because we really wanted to have -something- about this in the new drafts, I've merged this first version of the text, including fixes for your smaller but not larger remarks, with the intent of there being continued discussion going forward. To that end, I will create 2 new issues, one for your high-level review about general structure, and one for the "user consent" remark to further track these points for future versions. Thanks again!
This is a lot of text. I like the enumeration of the types of risk, but I fear that the extrapolation from there is both incomplete and a little long-winded. The focus on anonymization is not one that I would emphasize. I know that Christian has toyed with the concept, but that was idle speculation, not anything rigorous. In the end, this text should be very clear that qlog files present a privacy risk to those participating in the connection. They should therefore be treated accordingly. Any notion that these files might be sanitized in a way that might remove that risk should be changed to focus more on defense in depth. That is, look at access control and retention limits as primary means of protection, not anonymization. I would instead structure this roughly as follows: A brief introductory piece. An articulation of the types of privacy risk that might be presented by capture, storage, and use of qlog data. This part is fairly lengthy and could probably be a subsection. A description of the operational implications and potential actions that might be taken first from a security standpoint, then for privacy remediation. qlog files that are records of interactions with peers are data that those peers (or users) potentially have rights over (I like this point, so make it prominently, but do not refer to laws; do not refer to the GDPR especially). a. Access controls required to enable qlog or to expand the information that is captured. a. Access controls required to access stored qlog files. a. Limits to retention of qlog files. a. Finally, observe that limiting what is captured or anonymization might be possible, but that this could either be insufficient from a privacy perspective, reduce the usefulness of the data, or (highly likely) both. It's easy to focus on the point about not being able to link qlog data with people. But it's safer to treat that as an open research problem than invite implementations and deployments to indulge in amateur research on the topic.Looks good now, thanks!

8.  <ins> The security and privacy considerations discussed in QLOG-MAIN apply to this document as well. </ins> 9. 9.  <ins> The security and privacy considerations discussed in QLOG-MAIN apply to this document as well. </ins> 10. 9.  <ins> Protocols such as TLS RFC8446 and QUIC RFC9000 provide varying degrees of secure protection for the wire image RFC8546.  There is inevitably tension between security and observability, when logging can reveal aspects of the wire image, that would ordinarily be protected.  This tension equally applies to any privacy considerations that build on security properties, especially if data can be correlated across data sources. qlog operators and implementers should be mindful of the security and privacy risks inherent in handling qlog data.  This includes but is not limited to logging, storing, or using the data.  Data might be considered as non-sensitive, potentially-sensitive, or sensitive; applying the considerations in this section may produce different risks depending on the nature of the data itself, or its handling. However, in many cases the largest risk factors arise from data that can be considered as potenially-sensitive or sensitive. The following is a non-exhaustive list of such fields and types of data that can be carried in qlog data: IP addresses and transport protocol port numbers, which can be used to uniquely identify individual connections, endpoints, and potentially users. Session, Connection, or User identifiers which can be used to correlate nominally separate contexts.  For example, QUIC Connection IDs can be used to identify and track users across geographical networks RFC9000). Stored State which can be used to correlate individual connections or sessions over time.  Examples include QUIC address validation and retry tokens, TLS session tickets, and HTTP cookies. Decryption keys, passwords, and tokens which can be used with other data sources (e.g., captures of encrypted packets) to correlate qlog data to a specific connection or user or leak additional information.  Examples include TLS decryption keys and HTTP-level API access or authorization tokens. Data that can be used to correlate qlogs to other data sources (e.g., captures of encrypted packets).  Examples include high- resolution event timestamps or inter-event timings, event counts, packet and frame sizes. Full or partial encrypted raw packet and frame payloads, which can be used with other data sources (e.g., captures of encrypted packets) to correlate qlog data to a specific connection or session. Full or partial plaintext raw packet and frame payloads (e.g., HTTP Field values, HTTP response data, TLS SNI field values), which can contain directly sensitive information. The simplest and most extreme form of protection against abuse of this information is the complete deletion of a given field, which is equivalent to not logging the field(s) in question.  While deletion completely protects the data in the deleted fields from the risk of compromise, it also reduces the utility of the dataset as a whole. As such, a balance should be found between logging these fields and the potential risks inherent in their (involuntary) disclosure.  This balance depends on the use case at hand (e.g., research datasets might have different requirements to live operational troubleshooting).  Capturing the minimal amount of data required for a specific purpose can help to minimize the risks associated with data usage. qlog implementations that provide fine-grained control over the inclusion of data fields, ideally on a per-use-case or per- connection basis, improve the ability to minimize data. Any data that is determined to be necessary for a use case at hand could be logged or captured.  As per RFC6973, operators must be aware that such data will be at risk of compromise.  As such, measures should be taken to firstly reduce the risk of compromise and secondly reduce the risk of abuse of compromised data.  While a full discussion of both aspects is out of scope for this document, the following paragraphs discuss high-level considerations that can be applied to qlog data. To reduce the risk of compromise, operators can take measures such as: limiting the length of time that data is stored, encrypting data in transit and at rest, limiting access rights to the data, and auditing data usage practices. qlog deployments that provide integrated options for automated or manual data deletion and (aggressive) aggregation, improve the ability to minimize the risk of compromise. To reduce the risk of data abuse after compromise, data can be anonymized, pseudonymized, otherwise permutated/replaced, truncated, (re-)encrypted, or aggregated.  A partial discussion of applicable techniques (especially for IP address information) can be found in DNS-PRIVACY.  Operators should, however, be aware that many of these techniques have been shown to be insufficient to safeguard user privacy and/or to protect user identity, especially if a qlog data set is large or easily correlated against other data sources. Finally, qlog operators should consider the interplay between their use case needs and end user rights or preferences.  While active user participation (as indicated by RFC6973) on a per-qlog basis is difficult, as logs are often captured out-of-band to the main user interaction and intent, general user expectations should be taken into account. qlog deployments that provide mechanisms to integrate the capture, storage and removal of qlogs with more general, often pre-existing, user preference and privacy control systems, improve the ability to protect data sensitive or confidential to the end user.  In qlog, these data are typically (but not exclusively) contained in fields of the RawInfo type (see raw-info). qlog users should thus be particularly hesitant to include these fields for all but the most stringent use cases. </ins> 10. [10] https://github.com/quiclog/quictrace2qlog [11] https://qvis.edm.uhasselt.be


4.6. <del> TODO 4.7. </del> Importance: Base This event is used to track progress through QUIC's complex handshake state = handshake_confirmed <del> 4.8. </del>  e.g., path_updated For now, infer from other connectivity events and path_challenge/ path_response frames <del> 4.9. </del>  Importance: Extra

Connection retried was never properly specced. The main reason is that a retried connection is completely separate from the original connection attempt, except for the value, and as such is usually logged in a separate file / separate context from the original connection qlog data. Current qlog deployments either have other ways of correlating retried connections with the original attempts, or don't need to do this. Either way, there is no tangible need for at this time.
I don't think that's correct. You also take your Connection IDs with you to the new connection. quic-go logs it to the same file, as it is the same connection attempt. I don't see value in though.

4.6.  Importance: Base This event is used to track progress through QUIC's complex handshake state = handshake_confirmed  <ins> 4.7. </ins> e.g., path_updated For now, infer from other connectivity events and path_challenge/ path_response frames  <ins> 4.8. </ins> Importance: Extra


5.2.  5.2.1. 5.2.2. 8.11.  8.11.1. In QUIC, PADDING frames are simply identified as a single byte of

In doing the exercise to try and define a new DATAGRAM extension for qlog (at URL), it became clear that we only had a CDDL extension point for the events themselves () but NOT for the individual QUIC and HTTP/3 frames. This is needed so we can add the CDDL definitions for new frames in other documents and have them properly matched to the CDDL expectations of "main document" events like and .
LGTM modulo some editorial nits

5.2. <ins> The generic "$HTTPFrame" is defined here as a CDDL extension point (a "socket" or "plug").  It can be extended to support additional HTTP/3 frame types. The HTTP/3 frame types defined in this document are as follows: </ins> 5.2.1. 5.2.2. 8.11. <ins> The generic "$QuicFrame" is defined here as a CDDL extension point (a "socket" or "plug").  It can be extended to support additional QUIC frame types. The QUIC frame types defined in this document are as follows: </ins> 8.11.1. In QUIC, PADDING frames are simply identified as a single byte of


2.1.  2.2. A single qlog event trace is typically associated with a single QUIC

This field is not particularly useful, because it will always be 16, see URL it's a property of the TLS cipher suite in use, so it can be trivially looked up, if necessary
So this is a bit of a tough one for me, since I've gone through the pain of trying to determine the length of the TLS trailer for TLS-over-TCP from wireshark output that does NOT explicitly include the size and also makes it difficult to get the proper cipher name to heuristically determine it. That said, for QUIC V1 it's indeed all 16, so you -could- make an argument we can drop it here and add it back in with a V2.1/V3 if new ciphers start being used. I don't have a particularly big preference either way. If we do this change though, the prose could use tightening, because in the current version we have 2 sentences after another that indicate the aead_length depends on the cipher suite.
I'm leaning on the side of removing this field. The information is made redundant by the cipher suite. Things that care about the tag length can do a lookup or make their own assumptions based on other information
Discussed on call. NAME will make the requested prose change and should be good to go.
Rebased and tightened the text around the tag length.
Minus the comment above, this LGTM.

2.1. <ins> QUIC packets always include an AEAD authentication tag at the end. In general, the length of the AEAD tag depends on the TLS cipher suite, although all cipher suites used in QUIC v1 use a 16 byte tag. </ins> 2.2. A single qlog event trace is typically associated with a single QUIC


efficient than logging the observed CID with each packet in the .header field of the "packet_sent" or "packet_received" events. <del> This is viewed from the perspective of the one applying the new id. As such, if we receive a new connection id from our peer, we will see the dst_ fields are set.  If we update our own connection id (e.g., NEW_CONNECTION_ID frame), we log the src_ fields. </del>  Definition: Definition: <del> Note: We do not explicitly log the encryption_level or packet_number_space: the header.packet_type specifies this by inference (assuming correct implementation) </del>  Note: for more details on "datagram_id", see transport-datagramssent. It is only needed when keeping track of packet coalescing. This event is emitted when a packet is buffered because it cannot be processed yet.  Typically, this is because the packet cannot be <del> parsed yet, and thus we only log the full packet contents when it was parsed in a packet_received event. </del>  Definition: Importance: Extra <del> When we pass one or more UDP-level datagrams to the socket.  This is useful for determining how QUIC packet buffers are drained to the OS. </del>  Definition: Importance: Extra <del> When we receive one or more UDP-level datagrams from the socket. </del>  This is useful for determining how datagrams are passed to the user space stack from the OS. Importance: Extra <del> When we drop a UDP-level datagram.  This is typically if it does not contain a valid QUIC packet (in that case, use packet_dropped instead). </del>  Definition: This event's main goal is to prevent a large proliferation of specific purpose events (e.g., packets_acknowledged, <del> flow_control_updated, stream_data_received).  We want to give implementations the opportunity to (selectively) log this type of signal without having to log packet-level details (e.g., in packet_received).  Since for almost all cases, the effects of applying a frame to the internal state of an implementation can be inferred from that frame's contents, we aggregate these events in this single "frames_processed" event. </del>  Note: This event can be used to signal internal state change not resulting directly from the actual "parsing" of a frame (e.g., the This event indicates which data was marked for retransmit upon detecting a packet loss (see packet_lost).  Similar to our reasoning for the "frames_processed" event, in order to keep the amount of <del> different events low, we group this signal for all types of retransmittable data in a single event based on existing QUIC frame definitions. </del>  Implementations retransmitting full packets or frames directly can just log the constituent frames of the lost packet here (or do away By definition, an application error is defined by the application- level protocol running on top of QUIC (e.g., HTTP/3). <del> As such, we cannot define it here directly.  Though we provide an extension point through the use of the CDDL "socket" mechanism. </del>  Application-level qlog definitions that wish to define new ApplicationError strings MUST do so by extending the to 0x100 to produce a QUIC error code from the range reserved for CRYPTO_ERROR." <del> This approach maps badly to a pre-defined enum.  As such, we define the crypto_error string as having a dynamic component here, which should include the hex-encoded and zero-padded value of the TLS alert description. </del>  9.

Work towards resolving , for the QUIC events document.
This is great. There are 2-3 instances in the h3 document as well that could use similar re-wording. I'll post a PR for that

efficient than logging the observed CID with each packet in the .header field of the "packet_sent" or "packet_received" events.  <ins> This is viewed from the perspective of the endpoint applying the new id.  As such, when the endpoint receives a new connection id from the peer, it will see the dst_ fields are set.  When the endpoint updates its own connection id (e.g., NEW_CONNECTION_ID frame), it logs the src_ fields. </ins> Definition: Definition:  <ins> Note: The encryption_level and packet_number_space are not logged explicitly: the header.packet_type specifies this by inference (assuming correct implementation) </ins> Note: for more details on "datagram_id", see transport-datagramssent. It is only needed when keeping track of packet coalescing. This event is emitted when a packet is buffered because it cannot be processed yet.  Typically, this is because the packet cannot be  <ins> parsed yet, and thus only the full packet contents can be logged when it was parsed in a packet_received event. </ins> Definition: Importance: Extra  <ins> When one or more UDP-level datagrams are passed to the socket.  This is useful for determining how QUIC packet buffers are drained to the OS. </ins> Definition: Importance: Extra  <ins> When one or more UDP-level datagrams are received from the socket. </ins> This is useful for determining how datagrams are passed to the user space stack from the OS. Importance: Extra  <ins> When a UDP-level datagram is dropped.  This is typically done if it does not contain a valid QUIC packet (in that case, use packet_dropped instead). </ins> Definition: This event's main goal is to prevent a large proliferation of specific purpose events (e.g., packets_acknowledged,  <ins> flow_control_updated, stream_data_received).  Implementations have the opportunity to (selectively) log this type of signal without having to log packet-level details (e.g., in packet_received).  Since for almost all cases, the effects of applying a frame to the internal state of an implementation can be inferred from that frame's contents, these events are aggregated into this single "frames_processed" event. </ins> Note: This event can be used to signal internal state change not resulting directly from the actual "parsing" of a frame (e.g., the This event indicates which data was marked for retransmit upon detecting a packet loss (see packet_lost).  Similar to our reasoning for the "frames_processed" event, in order to keep the amount of  <ins> different events low, this signal is grouped into in a single event based on existing QUIC frame definitions for all types of retransmittable data. </ins> Implementations retransmitting full packets or frames directly can just log the constituent frames of the lost packet here (or do away By definition, an application error is defined by the application- level protocol running on top of QUIC (e.g., HTTP/3).  <ins> As such, it cannot be defined here directly.  Applications MAY use the provided extension point through the use of the CDDL "socket" mechanism. </ins> Application-level qlog definitions that wish to define new ApplicationError strings MUST do so by extending the to 0x100 to produce a QUIC error code from the range reserved for CRYPTO_ERROR."  <ins> This approach maps badly to a pre-defined enum.  As such, the crypto_error string is defined as having a dynamic component here, which should include the hex-encoded and zero-padded value of the TLS alert description. </ins> 9.


Importance: Base <del> This event indicates a QUIC-level packet was dropped after partial or no parsing. </del>  Definition: <del> Note: sometimes packets are dropped before they can be associated with a particular connection (e.g., in case of "unsupported_version").  This situation is discussed more in handling-unknown-connections. </del>  <del> Note: for more details on "datagram_id", see transport-datagramssent. It is only needed when keeping track of packet coalescing. </del>  5.8.

Hey NAME we think this PR is ready to be merged. If you have some time this week for a quick review, that would be splendid :)
The current text lists about 8 reasons for dropping packets. Microsoft's implementation lists 60+ individual reasons (via NAME Some of those: LogDrop("Already received server response"); LogDrop("No room for ODCID"); LogDrop("Invalid ODCID"); LogDrop("InitialToken alloc failed"); LogDrop("OrigCID alloc failed"); LogDrop("Max deferred datagram count reached"); LogDrop("Key no longer accepted"); LogDrop("SH packet during version negotiation"); LogDrop("Too short for HP"); LogDrop("Packet number too big"); LogDrop("Payload length less than encryption tag"); LogDrop("Generate new packet keys"); LogDrop("Decryption failure"); LogDrop("Invalid SH Reserved bits values"); LogDrop("Invalid LH Reserved bits values"); LogDrop("Duplicate packet number"); LogDrop("Key no longer accepted (batch)"); LogDrop("Failed to compute HP mask"); LogDrop("Different remote address"); LogDrop("Too small for Packet->Invariant"); LogDrop("LH no room for DestCID"); LogDrop("Zero length DestCID"); LogDrop("LH no room for SourceCID"); LogDrop("SH no room for DestCID"); LogDrop("DestCID don't match"); LogDrop("SourceCID don't match"); LogDrop("Greater than allowed max CID length"); LogDropWithValue("Invalid client/server packet type", Packet->LH->Type); LogDrop("Invalid LH FixedBit bits values"); LogDrop("Long header has invalid token length"); LogDropWithValue("Long header has token length larger than buffer length", TokenLengthVarInt); LogDrop("Long header has invalid payload length"); LogDropWithValue("Long header has length larger than buffer length", LengthVarInt); LogDropWithValue("Long Header doesn't have enough room for packet number", LogDrop("Invalid SH FixedBit bits values"); LogDrop("Non-initial packet not matched with a Connection"); LogDrop("Retry received after initial"); I feel that we don't need to list things in this level of detail in the qlog spec (the "trigger" field allows any text anyway). However, maybe some guidance text on this would be helpful and maybe a few more suggested triggers would be interesting.
Wonder how many reasons Microsoft has for dropping in packets in 2022. Any input NAME What are your top 20 used reasons? I think we need to be judiscious with minimizing scope in the qlog document. Unless the triggers are common and self explanatory, we'll just risk confounding people with options or tying ourselves in knots with text to explain them. Our escape valve is that this is free form text and probably not commonly used for anything special. Being frugal in the base spec is an advantage.
fwiw, this is what quic-go has: URL It seems like many of NAME reasons are just variations of a generic "header parse error", and could be logged as details to that event.
In my experience, if you're debugging an incident, you need to know the exact line of code, the exact reason why a drop happened, because you need to figure out how to fix it right then. If you only log enough to narrow the scope down to a dozen different code places, that doesn't help. I don't care if there is one field for all the info, or two, with one of them being the "detailed_info" or something, but all the details need to be captured to make it useful.
I agree deployments would want the ability to log to that level. Let's look at HTTP status codes for example. Proxies can fail requests with high level 4xx or 5xx status codes and then use the proxy-status header to include additional data URL; namely the parameter. HTTP also has problem details URL This is effectively a 3 layer model of coarseness - limited top level, broader mid level, very specific low layer. Each of these layers is also well structured, which makes interoperability easier - I.e. grepping out specific cases for alerting or investigation. To map to qlog we could have a limited set of top-level triggers, an optional error type, and a field for detailed info. The last field is likely to be text but in theory you could indicate the format of that text for interop. E.g., if I want to encode JSON in event and singal that to consumers explicitly, using a media type could help. But is suspect is probably enough for a lot of folks.
just adding a datapoint in favor for being as specific as possible about the reason a packet got dropped on the floor in MVFST we have about 40 different reasons and as NAME says they are useful to identify the specific line of code that drops the packet URL That being said encoding this information with a generic "Packet Dropped" event and an optional free-form reason/detailed_info field seems like the best course of action to me since it's not up to qlog specs to define which errors are useful and which ones are less useful.
Looking at this, I would agree keeping the list in qlog itself quite short and providing a generic field where implementations can add any type of freeform info they desire. For this, we need 2 things: Decide WHICH of these current triggers on we want to keep (or do we want to rename/exchange some maybe?). Probably best coming from someone with a large deployment (NAME NAME NAME Add a field to the event. I have it as a JSON object instead of a but I don't mind either way. I'd put the "error type" in the field as well then NAME feeling that the can act as an "error category" indicator.
Looking at our (currently 79) drop reasons in MsQuic, I think the following top-level categories would be reasonable: Internal Error (not initialized, OOM, etc.) Rejected (internal limits reached, ddos protection, unwilling to track more paths, duplicate) Unsupported (unknown/unsupported version) Invalid Packet (packet parsing/validation failed) Connection Unknown (CID doesn't match) Decryption Failure (decrypt failed or key unavailable)
I like Nicks categories. All I might add is a "General" category for anything else, where details can be added or not at operator discretion
LGTM modulo nits

Importance: Base  <ins> This event indicates a QUIC-level packet was dropped. The trigger field indicates a general reason category for dropping the packet, while the details field can contain additional implementation-specific information. </ins> Definition:  <ins> Some example situations for each of the trigger categories include: </ins>  <ins> internal_error: not initialized, out of memory rejected: limits reached, DDoS protection, unwilling to track more paths, duplicate packet unsupported: unknown or unsupported version.  See also handling- unknown-connections. invalid: packet parsing or validation error connection_unknown: packet does not relate to a known connection or Connection ID decryption_failure: decryption key was unavailable, decryption failed general: situations not clearly covered in the other categories For more details on "datagram_id", see transport-datagramssent. </ins> 5.8.


many UDP datagrams, unique identifiers are required to be able to track them individually in qlog traces.  However, neither UDP nor QUIC exchanges datagram identifiers on the wire.  Selecting <del> identifier is values is thus left to qlog implementations, that should consider how to generate unique values within the scope of their created traces. </del>  5.11.

rebase on main should fix the cddl tests
Currently, we have a mechanism for tracking QUIC packet coalescing in a single UDP datagram by means of the field. This was originally added as per . Main intended use: when a UDP payload is received containing multiple coalesced QUIC packets, those QUIC packets are given the same "datagram ID" (which is a receiver-side chosen number that's unique per received datagram, which is needed because UDP datagrams don't have a packet number or similar). As such, when 2 separate packets are logged in 2 separate events, but they have the same value for the field, it's clear they were coalesced. Similarly, 2 events with the same indicate sender-side coalescing. As the original issue indicates, this can be deduced from the events as well, but those are often too chatty to leave on. The fields on the events are for completeness / ability to track coalesced packets across the different events. I'm personally not the biggest fan of this solution (did you eventually implement this in quic-go, NAME but I don't immediately see a better approach. CC NAME as he indicated the use of wasn't clear to him, which means we either need to revisit or clarify its use.
I'll try to summarise my understanding. The is specified for the following events packetsent packetreceived packetbuffered packetdropped datagramssent (an array here, but same purpose) datagramsreceived (an array here, but same purpose) The use of the ID is given in URL and currently says: I don't mind the motivating use case. I'm not sure exactly how my implementations could use it for packet sending events because we generate the packet and qlog it before we get into UDP datagram realms. Changes might address that but I'm not sure it's worth overhead. Other implementations might find it far more natural to use though. The main part I find confusing is the part about . This is vague and quite specific at the same time. How unique does something need to be? Can I just use a counter like datagramid = 0, datagramid=1 for the packets sent on a connection? Or is the expectation that the identifier is more like a UUID, so that packets are uniquely traceable? Maybe it depends if we are capturing single connections or traces that span mutliple things, so perhaps a reword to state the requirements and expectations of the datagram_id value could help. E.g. "Since QUIC traces may contain many UDP events, unique identifiers are required for each datagram in order to avoid them being confused. Identifiers are not exchanged on the wire, they are only relevant to the logging endpoint. Selecting identifier values is left to implementations that should consider how to generate unique values within the scope of the traces they generate"
LGTM modulo nit

many UDP datagrams, unique identifiers are required to be able to track them individually in qlog traces.  However, neither UDP nor QUIC exchanges datagram identifiers on the wire.  Selecting  <ins> identifier values is thus left to qlog implementations, which should consider how to generate unique values within the scope of their created traces. </ins> 5.11.


"application" // e.g., HTTP/3's GOAWAY frame  5.1.7. e.g., path_updated

Partially Main change is adding as a PacketType. The is added as a field to packetsent and packetreceived. Any of the "unpredictable bits" can be logged as Added a trigger to to indicate if a connection goes into draining/closing because a valid statelessreset was received. Backwards compatibility break: renamed to on the NewConnectionID frame definition (for consistency). Been thinking about a way to signal an "invalid" stateless reset, but figured there is no way to distinguish it from an otherwise garbage datagram, so decided it was impossible. Not 100% sure about the "looping case" where you continually lower the packet size. Maybe that's solved by adding a generic "packetsize" trigger value to though?
LGTM!
These concepts were in flux when -01 was made and are now much more settled. Any thoughts on how to best approach this are more than welcome.
For stateless reset, I can see two options: make it a new PacketType and then simply use / make it a new event type with custom semantics At least one implementer has indicated a preference for (1), since their stack only intends to support the core events.
For stateless reset, both works for me. Most important thing is to get a way to log it at all, since this would be an interesting signal in production.

"application" // e.g., HTTP/3's GOAWAY frame <ins> "stateless_reset" // because a stateless reset was received </ins> 5.1.7. e.g., path_updated


Importance: Extra <del> This event is emitted when the single recovery loss timer is set. </del>  Data: these events need to be?  Just support QUIC-style recovery from the spec or broader? <del> Triggers: TODO </del>  5.4.5. <del> Importance: Extra This event is emitted when the single recovery loss timer fires. Data: 5.4.6. </del> Importance: Core This event is emitted when a packet is deemed lost by loss detection. "pto_expired" // draft-23 section 5.3.1, MAY <del> 5.4.7. </del>  Importance: Extra

Not 100% sure this is enough for all the latest draft-27(+) changes though, added a TODO in the draft for that purpose. Also added a packetnumberspace field to metrics_updated to be flexible for implementations that don't want to implement all types of events. It's not a great fit at that location, but it seemed the most synergistic without having a completely new event type. PTAL NAME
Currently, we log in . However, we can have multiple PTO's running across multiple PN spaces and there is no proper way to correlate them with a PN space in metricsupdated. This also impacts the event types. Possible resolutions: Add pnspace attribute to Split PTO count into a separate event (potentially merge with loss_timer?) TODO: reason more about how these metrics are tied to PN spaces in general (are there others than PTO that are duplicated) cc NAME
Most other metrics in the event are independent of the PN space, so that would be weird. I'd prefer to do that. Not sure if it makes sense to merge is with the loss timer events, since we also need to be able to log a reset of the PTO count to 0 (which doesn't require setting of a timer).

Importance: Extra  <ins> This event is emitted when a recovery loss timer changes state.  The three main event types are: set: the timer is set with a delta timeout for when it will trigger next expired: when the timer effectively expires after the delta timeout cancelled: when a timer is cancelled (e.g., all outstanding packets are acknowledged, start idle period) Note: to indicate an active timer's timeout update, a new "set" event is used. </ins> Data: these events need to be?  Just support QUIC-style recovery from the spec or broader?  <ins> TODO: read up on the loss detection logic in draft-27+ and see if this suffices </ins> 5.4.5.  Importance: Core This event is emitted when a packet is deemed lost by loss detection. "pto_expired" // draft-23 section 5.3.1, MAY  <ins> 5.4.6. </ins> Importance: Extra


"unsupported_version"  Note: sometimes packets are dropped before they can be associated with a particular connection (e.g., in case of "unsupported_version").  This situation is discussed in handling-

Per discussion on slack, and can be merged into , given that we have a field for the disambiguation.
NAME Done. Updated the PR.

"unsupported_version" <ins> "unexpected_packet" "unexpected_source_connection_id" "unexpected_version" </ins> Note: sometimes packets are dropped before they can be associated with a particular connection (e.g., in case of "unsupported_version").  This situation is discussed in handling-


packets. A client MAY also clear the QUIC Bit in Initial packets that are sent <del> to establish a new connection.  A client can only clear the QUIC Bit if the packet includes a token provided by the server in a NEW_TOKEN frame on a connection where the server also included the grease_quic_bit transport parameter.  To allow for changes in server configuration, clients SHOULD set the QUIC Bit if the token was provided more than 7 days prior. </del>  3.2.

At the moment, the paragraph says "Initial packets that are sent to establish a new connection." That is unclear. It is possible to interpret this text as "all Initial packets that the client sends," because all the Initial packets are used to establish a new connection. As the paragraph right above discusses what endpoints should do once they receive transport parameters, we can be clear that this paragraph discusses what should be done until then.
Thanks Kazuho, this is definitely clearer. WDYT of the tweak?

packets. A client MAY also clear the QUIC Bit in Initial packets that are sent  <ins> prior to receiving transport parameters from the server.  A client can only clear the QUIC Bit if such packets include a token provided by the server in a NEW_TOKEN frame on a connection where the server also included the grease_quic_bit transport parameter.  To allow for changes in server configuration, clients SHOULD set the QUIC Bit if the token was provided more than 7 days prior. </ins> 3.2.


negotiated the extension in a previous connection and clear the QUIC Bit based on that information.  3.2. The purpose of this extension is to allow for the use of the QUIC Bit

It seems like the answer to was already in the draft. It just wasn't precise enough to be useful. I also found the wording of the next section awkward, so I'm bundling my changes.
The editorial improvements seem good but I still don't see an answer about the question of stateless reset. For instance, you mention NEW_TOKEN but not .
Oh, I misread. Good thing I didn't mark this as closing . I'll add that.
Would it be correct to say that packets will never be affected by this extension?
Good question. An Initial with a token from (NEW_TOKEN from) a previous connection can clear the bit if the server originally included the transport parameter. If the server puts this information in the token, processes that token, and decides to send a Retry anyway, it might know that the client previously supported the extension. The question is whether we want to allow that. Allowing that means that the client is now constrained (as the server is) to not offer a token if it changes its attitude toward the extension in the interim. Disallowing it means that Retry doesn't get the benefit of greasing. The other way this might happen is if the Retry is sent after processing the contents of the Initial packet. That's much less likely given the way Retry works, but it is at least theoretically possible. I'm leaning toward forbidding the server from exercising the extension unless it reads the client's opinion from the message it receives. We don't add a bunch of constraints on how clients offer tokens or tickets elsewhere in the stack and it would be bad form to start.
Gah, I misread that as Retry. I keep doing that. As for stateless reset, it seems unlikely that a server would be able to generate a truly stateless reset with the QUIC Bit cleared. Except... A server could condition its use of the QUIC Bit extension on support from the client. That is, it only declares support for the extension if the client does the same. In that case, packets it receives with the QUIC Bit cleared would indicate that the client also supports the extension. In that case, the server would be able to clear the QUIC Bit on its own stateless reset packets. Aside from that, it seems like it would be hard to be confident that the cleared bit would be acceptable to a client.
Right, we might expect that a QUIC server that has a good relationship with e.g. a Load Balancer might be able to share some information about itself and behaviours. But that sounds too hard for the minimal gain it would provide here, so I'm pessimistic anyone would bother just for QUIC bit grease. The new text cuts a good balance on speaking to the consideration and allow people to do what they like.
LGTM thanks

negotiated the extension in a previous connection and clear the QUIC Bit based on that information. <ins> An endpoint cannot clear the QUIC Bit without knowing whether the peer supports the extension.  As stateless reset packets (Section 10.3 of QUIC) are only used after a loss of connection state, endpoints are unlikely to be able to clear the QUIC Bit on stateless reset packets. </ins> 3.2. The purpose of this extension is to allow for the use of the QUIC Bit


sent in addition to the grease_quic_bit transport parameter.  Though the value of the QUIC Bit in packets received by a peer might be set according to rules defined by the extension, they might also be <del> randomized according to the definition of the grease_quic_bit extension.  Receiving the transport parameter for the extension could be used to confirm that a peer supports the semantic defined in the extension.  To avoid acting on a randomized signal, the extension can require that endpoints set the QUIC Bit according to the rules of the extension, but defer acting on the information conveyed until the transport parameter for the extension is received. </del>  Extensions that define semantics for the QUIC Bit can be negotiated without using the grease_quic_bit transport parameter.

This was unclear as it wasn't clear which extension was operative in the sentence.
changes lgtm

sent in addition to the grease_quic_bit transport parameter.  Though the value of the QUIC Bit in packets received by a peer might be set according to rules defined by the extension, they might also be  <ins> randomized as specified in this document.  Receiving the transport parameter for the extension could be used to confirm that a peer supports the semantic defined in the extension.  To avoid acting on a randomized signal, the extension can require that endpoints set the QUIC Bit according to the rules of the extension, but defer acting on the information conveyed until the transport parameter for the extension is received. </ins> Extensions that define semantics for the QUIC Bit can be negotiated without using the grease_quic_bit transport parameter.


The second-to-most significant bit of the first byte in every QUIC packet is defined as having a fixed value in QUIC version 1 QUIC. <del> The purpose of having a fixed value is to allow intermediaries and endpoints to efficiently distinguish between QUIC and other protocols; see DEMUX for a description of a scheme that QUIC can integrate with as a result.  As this bit effectively identifies a packet as QUIC, it is sometimes referred to as the "QUIC Bit". </del>  Where endpoints and the intermediaries that support them do not depend on the QUIC Bit having a fixed value, sending the same value

This is also fewer words :)
URL there is no definition of what an intermediary stands for here to understand the statement. I think rather defining the "intermediary" we can rephrase to inform the original intention of the fixed bit in QUIC packet i.e. coexistence with protocols in RFC7983. The statement here also gives an impression that any node in the network should be able to efficiently distinguish QUIC packets where in our OPS draft we are saying this is not reliable with a notion of "don't use it". so rephrasing should also help from this point of view. I would propose something like this - The purpose of having a fixed value is to allow coexistance with other protocols in ] . As this bit can be used to identify a packet as QUIC, it is sometimes referred to as the "QUIC Bit".

The second-to-most significant bit of the first byte in every QUIC packet is defined as having a fixed value in QUIC version 1 QUIC.  <ins> The purpose of having a fixed value is to allow QUIC to be efficiently distinguished from other protocols; see DEMUX for a description of a system that might use this property.  As this bit can identify a packet as QUIC, it is sometimes referred to as the "QUIC Bit". </ins> Where endpoints and the intermediaries that support them do not depend on the QUIC Bit having a fixed value, sending the same value