In order to archive the Slack responses to changing SHOULD to MUST @anrossi thought his code supported both server behaviors, but still thought the change was a good idea.
@huitema says changing the text would simplify his code, and the current text might create corner cases that wedge the connection @tatsuhiro agreed with @Christian Huitema <[email protected]> I'm firmly convinced that this is a case where changing the spec to match the implementations is appropriate. There will be a PR shortly making the change. On Thu, Oct 13, 2022 at 6:29 PM David Schinazi <[email protected]> wrote: > I also support changing the SHOULD to a MUST. I would phrase it something > along the lines of: > * The server MUST send all CRYPTO frames in the negotiated version. > * The client learns the negotiated version by observing the first long > header Version field that differs from the original version. If the client > receives a CRYPTO frame from the server in the original version, that > indicates that the negotiated version is equal to the original version. > > Credit for finding this issue goes to Anthony Rossi, thanks Anthony! > > Since we're on the topic of tweaking normative text, Anthony also pointed > out some gaps in the QUIC VN draft: > https://github.com/quicwg/version-negotiation/issues/129 > Those should be addressed by the following PR: > https://github.com/quicwg/version-negotiation/pull/131 > I'd love some extra review to make sure we get this right. > > Thanks everyone, > David > > On Thu, Oct 13, 2022 at 3:59 PM Martin Thomson <[email protected]> wrote: > >> The current text (as you have quoted) is essentially exactly what I >> implemented. That was pretty natural, but I followed the "SHOULD" you >> reference and I realize that maybe my client code wouldn't work if a server >> didn't. >> >> To put some flavour on that, the server is generally in a position to >> generate a v2 Initial when it receives the client's Initial. The only case >> that is interesting is where the server receives an incomplete TLS >> ClientHello (in the PQ test, for instance), where it might need to send an >> acknowledgment in a v1 Initial. However, from the server side, the >> cryptographic handshake message is always put into a packet *after* >> deciding which version to use. >> >> >From the client's perspective, they really need to keep all sets of keys >> around or be prepared to generate keys for any compatible version (I think >> I generate them on demand). For negotiation, my implementation latches >> onto the negotiated version based on the version of Initial packets it >> receives. If a server ignored the SHOULD and sent its handshake messages >> in Initial packets from the original version, I'm not sure that my code >> would successfully switch over to the negotiated version. >> >> The client needs a strong signal about which version to generate >> Handshake keys for, and the version of Initial packets seems to be the only >> signal we have prior to generating Handshake keys. So without the MUST, >> I'm not sure that this even works without the client also generating >> multiple Handshake keys, something I didn't even think to do. >> >> For that reason, I am very much supportive of your "MUST" change, >> provided that it is adequately conditioned. That is, the server MUST send >> cryptographic handshake messages in an Initial of the negotiated version, >> though it MAY send acknowledgments or other messages in an Initial of the >> original version. >> >> Thanks for catching that Martin. >> >> On Fri, Oct 14, 2022, at 09:42, Martin Duke wrote: >> > Hello QUIC Enthusiasts, >> > >> > We are dealing with late changes to the v2 draft after Last Call, and >> > I'd like the opinion of people who have implemented v2 and VN. >> > >> > The draft currently says: >> > >> >> The server SHOULD start sending its Initial packets using the >> negotiated version as soon as it decides to change. Before the server is >> able to process transport parameters from the client, it might need to >> respond to Initial packets from the client. For these packets the server >> uses the original version. >> > >> >> Once the client has processed a packet using the negotiated version, >> it SHOULD send subsequent Initial packets using that version. The server >> MUST NOT discard its original version Initial receive keys until it >> successfully processes a packet with the negotiated version. >> >> Both endpoints MUST send Handshake or 1-RTT packets using the >> negotiated version. An endpoint MUST drop packets using any other version. >> > >> > The VN draft says that v2 should make it clear how the client and >> > server learn the negotiated version, so I have to edit this somehow. >> > The shortest path is to just add some explanatory text that >> > extrapolates from what's already here. >> > >> > But I sense that the first SHOULD complicates the code a bit: if the >> > server elects to send the server hello with the original version, the >> > client can't verify the final version until it gets a Handshake. It >> > could say that the Server Hello MUST be sent with the negotiated >> > version, but it's pretty late to make that kind of change. >> > >> > So -- thoughts? Does it make things easier? Do the existing >> > implementations assume this anyway? >> > >> > Martin >> >>
