Change:
Two changes here: better explanation of why, and a validation requirement on clients.
From section 17.2.5: URL "This value MUST not be equal to the Destination Connection ID field of the packet sent by the client." This was originally added when multiple Retrys were supported. I don't think it's still necessary, but if it is, I'd like to add some rationale, because it's not obvious to me why this restriction is necessary. Past slides from Martin: URL
If I understand correctly, it's still necessary to prevent a MITM from performing a Retry (and then removing the token from the second Initial).
Fair point. Is that an 'attack' that we're concerned about? That sounds like NAME ideal DDoS device, actually.
Generally, I believe the goal is to prevent all unauthorized tampering with the handshake. If it happens, it should be detected and the handshake fails. I agree with this philosophy even though it does make the Retry scenario a bit trickier to offload. Also, even if that was allowed, designing a DDoS device around it would be tricky still. You'd have to handle the case where the peer only pads their packet up to 1200 bytes including the token, so if you removed it, the backend server wouldn't accept it.
Good point, it seems like we can fix this with an editorial PR to clarify the risk of not changing CID on Retry.
NAME the retry token is part of the initial encryption associated data, so if you remove it you'll need to recompute the crypto anyway. NAME can you elaborate on what the consequences of this attack are? It sounds like the attacker can close the connection by sending a bad retry. How is that different from having the attacker send a bad retry that changes the CID and contains a bogus retry token?
Q: Should the retry token be part of the TLS transcript? That might prevent a whole class of issues?
NAME The transport parameter ensures that part of the retry token is in the TLS transcript. If the retry token is protected by authenticated encryption (which it should) then transitively we already have tamper protection for the retry token. The issue here is that if the retry token is tampered with, then the connection is closed. But I don't see how changing the server connection ID during retry changes that though (as long as not changing the CID still requires sending the transport parameter).
NAME I think one worry was that if a middle box had the ability to change the CID using Retry, then they could more easily attack packet protection. NAME could probably add more here.
NAME NAME I think you are referring to (which is a general statement), with one of the possible attacks being URL
NAME I'm not sure I understand the attack, if the middlebox has access to the server's retry token key then it can do bad things, but I don't think that's worth protecting against.
NAME Yeah I think that the issues being described in the provided links has been fixed by introducing the ODCID TP (and therefore requiring the retry token key to be shared).
Thanks NAME . Given that, does anyone see a reason to require changing the CID with retry?
Consider the case where: Client sends Initial packet 0, no token, DCID A Client times out the Initial packet and sends Initial packet 1, no token, DCID A Client receives a Retry with ODCID = SCID = A (which is what you're proposing to permit) Client sends Initial packet 2, with token from Retry, DCID A Client receives a Retry with ODCID = SCID = A. Is this Retry a response to packet 1 from a stateless server with a high RTT, or a prohibited second Retry in response to packet 2? If packet 2 carries a different DCID, the client can tell by inspecting the ODCID field in the Retry packet. If packet 2 uses the same DCID as packets 0-1, it can't tell. Requiring a change allows the client to determine that the server isn't misbehaving in this case.
Thanks NAME , that makes sense. I'm not 100% sure detecting this class of bad behavior is worth the added requirement on the protocol though.
We had other reasons why this was critical, but we've changed other requirements in the spec that eliminated them. (For example, when the client was permitted to change the ClientHello following a Retry, you had to know which Initial the server wound up responding to or the handshake would fail.)
NAME can this be closed with no action?
NAME If we decide to not change the current requirement to change the CID, this issue should track adding editorial text explaining why we require changing it.
I'm happy for this to be marked as editorial and then we can explain why we require changing it.
Another reason, I think: By requiring it to change, the ODCID becomes something that the server can include in the TPs to ensure than an on-path attacker didn't inject a Retry before the Initial reached the server. It proves that the sender of the Retry was, if not the server itself, affiliated with it. Otherwise, the ODCID is potentially still in the client's Initial for the server to echo back without coordination.
By not allowing it to change you have a stronger assurance in that the server has to have a key. In other words, it strengthens the cooperation requirement. Having just implemented Retry (yeah, it is like that...) I don't see any advantage either side of this from an implementation perspective. Either way, the server either holds state or puts the odcid in the token. The client implementation is very slightly easier and more efficient if the key doesn't change.
NAME does that mean you're advocating for this to be a design issue again?
I won't do that if others don't think that, but it seems that at least NAME thinks it's worth doing.
In issue I was advocating for keeping the initial key the same (even across a Retry that changes the CID), but I don't have a preference for whether the CID MUST vs MAY vs MUST NOT change in a Retry.
OK, I think that I'm getting my wires crossed. I think that changing CID is valuable because it then forces the server to demonstrate continuity. It's keeping the keys constant (per ) that has the added value.
Thanks for the PR!

Discussion:
the token. A server can also use a Retry packet to defer the state and <del> processing costs of connection establishment.  By giving the client a different connection ID to use, a server can cause the connection to be routed to a server instance with more resources available for new connections. </del> <ins> processing costs of connection establishment.  Requiring the server to provide a different connection ID, along with the original_connection_id transport parameter defined in transport- parameter-definitions, forces the server to demonstrate that it, or an entity it cooperates with, received the original Initial packet from the client.  Providing a different connection ID also grants a server some control over how subsequent packets are routed.  This can be used to direct connections to a different server instance. </ins> A flow showing the use of a Retry packet is shown in fig-retry.

The server includes a connection ID of its choice in the Source Connection ID field.  This value MUST not be equal to the Destination <del> Connection ID field of the packet sent by the client.  The client MUST use this connection ID in the Destination Connection ID of subsequent packets that it sends. </del> <ins> Connection ID field of the packet sent by the client.  A client MUST discard a Retry packet that contains a Source Connection ID field that is identical to the Destination Connection ID field of its Initial packet.  The client MUST use this connection ID in the Destination Connection ID field of subsequent packets that it sends. </ins> A server MAY send Retry packets in response to Initial and 0-RTT packets.  A server can either discard or buffer 0-RTT packets that it