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
