jiebi/CodeConvo huggingface dataset:
Change:
In : This is not an issue. If v2 defines a new frame type that can appear in Initial-equivalent packets, then to be compatible with v1 (in both directions) that frame type could simply be optional in v2. The lack of a self-describing encoding is not an issue as the parsing of the v2 packet is done with knowledge of all the core frame types in v2. Sure, you can't introduce an extension frame here, but that's true of v1 on its own. The only way in which a version might become incompatible is if it includes new information that can't be inferred from the other version or doesn't have a valid default. I think that the intent of this was to say that if there is any need for the Initial flight to carry new information that is only consumed by a compatible version, then there is no way for QUIC version 1 to carry that new information by using new frames. Instead, it has to use a field in v1 that would be ignored by a v1 endpoint. As v1 defines no real extension points of this sort, the options in this case are limited. I think that this text can be removed. Maybe you could talk about the problem of carrying version-specific information in other versions.
This makes sense. This text was somewhat vestigial from earlier designs of this mechanism.

Discussion:
version such that commonly deployed versions are compatible with it. For example, a successor to QUIC version 1 may wish to design its transport parameters in a way that does not preclude compatibility. <del> Additionally, frames in QUIC version 1 do not use a self-describing encoding, so unrecognized frame types cannot be parsed or ignored (see the Extension Frames section of QUIC); this means that new versions that wish to be very similar to QUIC version 1 and compatible with it should avoid introducing new frames in initial packets. </del> 11.
Change:
I think that the answer is "no" (see also Betteridge's Law) in that the format is version-specific, but is pretty obtuse about this: The first sentence reads as an absolute; the second is clearly narrowly scoped. But then nothing is said about other versions. As I mentioned with error codes in , I think that the way this needs to be phrased is as a requirement on QUIC versions that support version negotiation. The requirement is that those protocols need to define a way to carry certain information. You can then define that information in the abstract when articulating that requirement; again see . The concrete form you choose for v1 then only needs to apply to v1.
The intention was for the handshake version information to be invariant, and for how it is conveyed to be version-specific. But I agree that we should state that versions need an authenticated way to exchange handshake version information.
It needs to go further than that. I think that you need to list, concretely, what information is being authenticated. And you need to explain the consequences, namely: And then in Section 4, say precisely what information needs to be authenticated in order to achieve this goal, with a concrete definition for how the information is carried in QUIC version 1 transport parameters.
That works for me.

Discussion:
5. During the handshake, endpoints will exchange Version Information, <del> which is a blob of data that is defined below.  In QUIC version 1, the Version Information is transmitted using a new transport parameter, version_information.  The contents of Version Information are shown below (using the notation from the "Notational Conventions" section of QUIC): </del> <ins> which consists of a chosen version and a list of other versions.  Any version of QUIC that supports this mechanism MUST provide a mechanism to exchange Version Information in both directions during the handshake, such that this data is authenticated. In QUIC version 1, the Version Information is transmitted using a new transport parameter, version_information.  The contents of Version Information are shown below (using the notation from the "Notational Conventions" section of QUIC): </ins> The content of each field is described below:
Change:
indicates that the address tuple used for the first flight remain stable. This is probably OK, but I think that this is unnecessary. What seems particularly risky here is anticipating the rules about connection IDs that might apply to both versions: My preference here is to drop this text entirely and leave it to the negotiated version to specify these rules. Once you have performed whatever mapping/transformation that is defined, then the first flight complies with the requirements of the negotiated version and you are subject to the rules of that version. Trying to manage the intersection of both sets of rules is complicated. Better not to chase down that rabbit hole (I've been there). FWIW, I fully expect v2 to also specify address tuple stability during the handshake. However, if it does not and a client can send a v2 first flight on multiple tuples (leaving aside the implausibility of expecting those datagrams to arrive at the same place), then that won't be naturally compatible with v1 and you won't be able to start with v2 in that way and expect to be able to negotiate v1 out of that. This is no different than your new, optional frame example.
I think we need to state something about 5-tuple stability here, because if version A requires 5-tuple stability and version B requires 5-tuple stability, neither of those documents specifies that the two halves of the handshake (the first half using A, and the second half using B) need 5-tuple stability between them.
I don't think that you need to say anything about that specifically. You might use it as an example in a sentence like:
Fair enough, that works for me.

Discussion:
will perform incompatible version negotiation instead, see incompat- vn. <del> For the duration of the compatible version negotiation process, clients MUST use the same 5-tuple (source and destination IP addresses and UDP port numbers).  During that time, clients MUST also use the same Destination Connection ID, except if the server explicitly instructs the client to use a different Destination Connection ID (for example, a QUIC version 1 server can accomplish this by sending an INITIAL packet with a Source Connection ID that differed from the client's Destination Connection ID).  This allows load balancers to ensure that packets for a given connection are routed to the same server. </del> <ins> Note that, after the first flight is converted to the negotiated version, the handshake completes in the negotiated version.  The entire handshake (including the converted first flight) needs to conform to the rules of the negotiated version.  For instance, if the negotiated version requires that the 5-tuple remain stable for the entire handshake (as QUIC version 1 does), then this applies to the entire handshake, including the first flight. </ins> 5.
Change:
The draft says: Server-Sent Other Versions: When sent by a server, the Other Versions field lists all the Fully-Deployed Versions of this server deployment, see Section 2. Note that the version in the Chosen Version field is not necessarily included in this list, because the server operator could be in the process of removing support for this version. For the same reason, this field MAY be empty. But the syntax is: What does the draft exactly mean by "this field MAY be empty"?
The "Other Versions" field contains a list of versions, whose length can be zero. That text exists to remind people that the list of Fully-Deployed Versions can be empty, and that shouldn't cause handshake failures.
The text is far from clear, because the sentence mixes references to "Other Versions" and "Chosen version". Stating "For the same reason, the Other Versions field MAY be empty" would remove the ambiguity.
Thanks for clarifying, I've written that up as .

Discussion:
fleet.  Note that the version in the Chosen Version field is not necessarily included in this list, because the server operator could be in the process of removing support for this version.  For <del> the same reason, this field MAY be empty. </del> <ins> the same reason, the Other Versions field MAY be empty. </ins> Clients and servers MAY both include versions following the pattern 0x?a?a?a?a in their Other Versions list.  Those versions are reserved
Change:
After pushback from NAME I think this covers the main point with a whole lot less text.
As discussed in URL, there are various levels of partial support for this standard, different for client and server, and there ought to be normative language around these capabilities. There are certain modes that MUST be supported along with multiple versions, and others that are just performance improvements. AFAICT, for any server that supports >1 versions, there are two possible levels of support: Send the TP and support incompatible negotiation Support compatible negotiation For a client, it's more complicated: NAME proposes: No support: do not the send nor parse the TP. If you get a VN packet, fail the QUIC connection Downgrade prevention only: send the TP with only one other version, also parse and validate the TP. If you get a VN packet, fail the QUIC connection. This protects against intermediaries that are rewriting the version field on Initial packets. In v1/v2, these attacks will be detected by the authenticated version field in subsequent handshake packets, but that is not generalizable to all versions of QUIC. Compatible only: downgrade prevention and be prepared to accept an upgrade Incompatible only: advertise only one version, so there's downgrade prevention when trying again with new version after a VN packet. Full: downgrade prevention, compatible VN and incompatible VN
LGTM

Discussion:
entire handshake (as QUIC version 1 does), then this applies to the entire handshake, including the first flight. <ins> Note also that the client can disable compatible version negotiation by only including the Chosen Version in the Other Versions field of the Version Information Transport Parameter. </ins> 5. During the handshake, endpoints will exchange Version Information,
Change:
This is NAME 's proposed text to fix this issue.
LGTM. I am going to merge this on the basis of it being David's text and my approval.
LGTM
Section 9 is pretty clear that 'compatible versions' might not have commonly usable 0-RTT packets. But Section 3 defines 'compatible' as a translatable first flight. 0-RTT is part of the first flight, so one of these definitions has to change.
That doesn't necessarily follow. You can translate a first flight in a way that 0-RTT is rejected and the 0-RTT packets are just dropped and the handshake will still succeed. I'm not sure I see an inconsistency here.
Having read sec 3 a few times now, I see the subtlety in your point. 0-RTT could fall under the third paragraph as something that can't be included to be compatible. I still don't really like the definition. I'll think on it some more, but I'd prefer something like "A is said to be 'compatible' with B if the first flight of A contains all the information minimally necessary to complete a first flight of B." So to be compatible with v1 , vx needs to contain a TLS 1.3 client hello including TPs for version negotiation and all the other required v1 TPs. For v1 to be compatible with vx, v_x must not have any additional information to complete its first fligth besides the client hello at the v1 TPs. Whether or not there's 0-RTT in the flight doesn't matter. We are drifting into the editorial, but if you like that definition I'm happy to write a PR.
I'm not sure "minimally necessary" is well-defined. How about something like:

Discussion:
from version B.  As an example, if versions A and B are absolutely equal in their wire image and behavior during the handshake but differ after the handshake, then A is compatible with B and B is <del> compatible with A. </del> <ins> compatible with A.  Note that the conversion of the first flight can be lossy: some data such as QUICv1 0-RTT packets could be ignored during conversion and retransmitted later. </ins> Version compatibility is not symmetric: it is possible for version A to be compatible with version B and for B not to be compatible with
Change:
Mix recommendations of NAME and NAME
LGTM
The document currently says: However, as we see with HTTP over TCP, clients routinely offer "h2", "http/1.1" and are content with either selection. Particularly if ALPN tokens map 1:1 to QUIC versions as specified in H3, the client's goal might be to use any of a collection of application-layer protocols. Perhaps tweak this to "...support one of the intended application layer protocols."? The first statement might or might not need to be expanded as well.
Perhaps we add a sentence after the ones you quoted along the lines of "For example, if the client's first flight advertises multiple ALPN tokens and multiple compatible versions, the server needs to ensure that the ALPN token that it selects can run over the QUIC version that it selects."

Discussion:
When a client creates a QUIC connection, its goal is to use an application layer protocol.  Therefore, when considering which versions are compatible, clients will only consider versions that <del> support the intended application layer protocol. </del> <ins> support one of the intended application layer protocols.  For example, if the client's first flight advertises multiple Application Layer Protocol Negotiation (ALPN) RFC7301 tokens and multiple compatible versions, the server needs to ensure that the ALPN token that it selects can run over the QUIC version that it selects. </ins> 4.
Change:
Should an endpoint be required to reject a transport parameter that contains 0?
Sure.
CC with ?
That's what I currently have in my implementation :)
Off topic but what if version 0 is included in Supported Version of a VN packet?
That would make the VN packet malformed. I'd suggest either dropping such packets or ignoring the zero.
OK. I modified my client to drop such packets as same as the case of the original version included.
I considered treating it as an error, but as it is an unauthenticated packet, it's better to drop it. I've done the same for ours.

Discussion:
if it is too short or if its length is not divisible by four), then the endpoint MUST close the connection; if the connection was using QUIC version 1, that connection closure MUST use a transport error of <del> type TRANSPORT_PARAMETER_ERROR. </del> <ins> type TRANSPORT_PARAMETER_ERROR.  If an endpoint receives a Chosen Version equal to zero, or any Other Version equal to zero, it MUST treat it as a parsing failure. </ins> Every QUIC version that supports version negotiation MUST define a method for closing the connection with a version negotiation error.
Change:
s/and therefore/, thereby/
s/rightly/tightly s/across version/across multiple versions
s/Alternatively, t/T/

Discussion:
negotiation (both compatible and incompatible) interacts with retry during a handshake that requires both.  For example, that could be accomplished by having the server send a Retry packet in the original <del> version first and therefore validating the client's IP address before </del> <ins> version first thereby validating the client's IP address before </ins> attempting compatible version negotiation.  If both versions support authenticating Retry packets, the compatibility defition needs to define how to authenticate the Retry in the negotiated version

QUIC version 1 uses TLS 1.3, which supports session resumption by sending session tickets in one connection that can be used in a later connection; see TLS.  New versions that also use TLS 1.3 SHOULD <del> mandate that their session tickets are rightly scoped to one version of QUIC; i.e., require that clients not use them across version and that servers validate this client requirement. </del> <ins> mandate that their session tickets are tightly scoped to one version of QUIC; i.e., require that clients not use them across multiple version and that servers validate this client requirement. </ins> 6.3.

0-RTT, that document MUST address the scenario where there are 0-RTT packets in the client's first flight.  For example, this could be accomplished by defining which transformations are applied to 0-RTT <del> packets.  Alternatively, that document could specify that compatible version negotiation causes 0-RTT data to be rejected by the server. </del> <ins> packets.  That document could specify that compatible version negotiation causes 0-RTT data to be rejected by the server. </ins> 7.
Change:
NAME was unhappy about the freedom we offered. This doesn't remove the header field separation, but it removes most of it.
Thank you, Martin! This looks good to me.

Discussion:
The Application Server then encrypts the payload.  Header fields are populated with URL-safe base-64 encoded RFC4648 values: <del> the "keyid" from the User Agent is added to both the Encryption- Key and Encryption header fields; </del> the salt is added to the "salt" parameter of the Encryption header field; and

the "rs" parameter can be omitted for messages that fit within this limit. <ins> An application server MUST NOT use other content encodings for push messages.  In particular, content encodings that compress could result in leaking of push message contents.  The Content-Encoding header field therefore has exactly one value, which is "aesgcm128". An application server MUST include exactly one entry in each of the Encryption and Encryption-Key header fields.  This allows the "keyid" parameter to be omitted from both header fields. An application server MUST NOT include a "key" parameter in the Encryption header field. </ins> 4. A User Agent decrypts messages are decrypted as described in I-
Change:
/cc NAME Not sure about "parameter of that same header" phrasing. Not a fan of duplicating the text about the content coding header either. Suggestions?
Yep, these are both correct. Thanks.

Discussion:
Server with other details of the push subscription. When sending a message, an Application Server generates an ECDH key <del> pair and a random salt.  The ECDH public key is encoded into the "dh" parameter of the Crypto-Key header field; the salt is encoded into message payload.  The ECDH key pair can be discarded after encrypting the message. </del> <ins> pair and a random salt.  The ECDH public key is encoded into the "keyid" parameter of the encrypted content coding header, the salt in the "salt" parameter of that same header (see Section 2.1 of I- D.ietf-httpbis-encryption-encoding).  The ECDH key pair can be discarded after encrypting the message. </ins> The content of the push message is encrypted or decrypted using a content encryption key and nonce that is derived using all of these

An Application combines its ECDH private key with the public key provided by the User Agent using the process described in ECDH; on receipt of the push message, a User Agent combines its private key <del> with the public key provided by the Application Server in the "dh" </del> <ins> with the public key provided by the Application Server in the "keyid" </ins> parameter in the same way.  These operations produce the same value for the ECDH shared secret.

the shared secret derived using ECDH the concatenation of the ASCII-encoded string "WebPush: info", a <del> zero octet, the X9.62 encoding of the User Agent ECDH public key, and X9.62 encoding of the Application Server ECDH public key; that is </del> <ins> zero octet, and the User Agent ECDH public key and the Application Server ECDH public key, both in the uncompressed point form defined in X9.62; that is </ins> 32 octets (i.e., the output is the length of the underlying SHA-256 HMAC function output)
Change:
This is the best that I can do for this one..
I think this is as good as it gets.

Discussion:
the "keyid" parameter of the encrypted content coding header.  The uncompressed point form defined in X9.62 (that is, a 65 octet sequence that starts with a 0x04 octet) forms the entirety of the <del> "keyid". </del> <ins> "keyid".  Note that this means that the "keyid" parameter will not be valid UTF-8 as recommended in RFC8188. </ins> A push service is not required to support more than 4096 octets of payload body (see Section 7.2 of RFC8030).  Absent header (86
Change:
defines: This removes a number of edge-cases and simplifies implementations. However, defines: Which is a violation of the former. Semantically it makes most sense for these to be distinct values since they're intended for different audiences. I'll propose a PR limiting webpush-encryption to one Crypto-Key entry having a value instead.
Because life is complicated, there are some libraries that are using ";" and creating a single parameter set containing both ECE and VAPID parameters, e.g. Because of "quirks" in both the mozilla and FCM handlers, this works. It may be beneficial if legacy push servers continue to support this behavior while libraries and applications that depend on them transition to any new division format.

Discussion:
header field therefore has exactly one value, which is "aesgcm128". Multiple "aesgcm128" values are not permitted. <del> An application server MUST include exactly one entry in each of the Encryption and Crypto-Key header fields.  This allows the "keyid" parameter to be omitted from both header fields. </del> <ins> An application server MUST include exactly one entry in the Encryption field, and at most one entry having a "dh" parameter in the Crypto-Key field.  This allows the "keyid" parameter to be omitted from both header fields. </ins> An application server MUST NOT include an "aesgcm128" parameter in the Encryption header field.
Change:
I ensured that the "proxy" text in UA and AS were similar. I removed the cross-references to and added text in Section 7.5, which is specific to PS policies if it doesn't want to support multiple subscription sets. I did not call out potential UA scenarios in detail other than "monitoring on behalf" of other receivers or senders. WebPush provides a mechanism to enable proxies - but it may be better to have separate drafts that describe specific policies that use this mechanism to support scenarios such as moving between UA(s).
NAME and NAME - please review and comment.
LGTM, but I'll wait until others have commented before merging.
This works for me.

Discussion:
A user agent MAY omit the subscription set if it is unable to receive push messages in an aggregated way for the lifetime of the subscription.  This might be necessary if the user agent is <del> monitoring subscriptions for other clients (see sets-streams). </del> <ins> monitoring subscriptions on behalf of other push message receivers. </ins> The push service SHOULD return the same subscription set in its response, although it MAY return a new subscription set if it is

unable to receive receipts in an aggregated way for the lifetime of the receipt subscription.  This might be necessary if the application server is monitoring receipt subscriptions on the behalf of other <del> push message senders (see sets-streams). </del> <ins> push message senders. </ins> A push service MUST return a 400 (Bad Request) status code for requests which contain an invalid receipt subscription.  If a push

push service.  This could force the user agent to serialize subscription requests to the push service. <del> A user agent that monitors subscriptions for other clients might require multiple subscription sets.  Each subscription set can then be managed independently, which might include being moved between user agents. </del> 8. This protocol MUST use RFC2818.  This includes any communications