Change:
%%% Connection ID Management enum { cid_immediate(0), cid_spare(1), (255) } ConnectionIdUsage; <del> Indicates the CID which the sender wishes the peer to use. </del> <ins> Indicates the set of CIDs which the sender wishes the peer to use. </ins> <del> Indicates whether the new CID should be used immediately or is a spare.  If usage is set to "cid_immediate", then the new CID MUST be used immediately for all future records.  If it is set to "cid_spare", then either CID MAY be used. </del> <ins> Indicates whether the new CIDs should be used immediately or are spare.  If usage is set to "cid_immediate", then one of the new CID MUST be used immediately for all future records.  If it is set to "cid_spare", then either existing or new CID MAY be used. Endpoints SHOULD use receiver-provided CIDs in the order they were provided.  Endpoints MUST NOT have more than one NewConnectionId message outstanding. </ins> If the client and server have negotiated the "connection_id" extension, either side can request a new CID using the RequestConnectionId message. <del> %%% Connection ID Management struct { } RequestConnectionId; </del> <ins> %%% Connection ID Management struct { uint8 num_cids; } RequestConnectionId; The number of CIDs desired. </ins> Endpoints SHOULD respond to RequestConnectionId by sending a <del> NewConnectionId with usage "cid_spare" as soon as possible.  Note that an endpoint MAY ignore requests, which it considers excessive (though they MUST be ACKed as usual). </del> <ins> NewConnectionId with usage "cid_spare" containing num_cid CIDs soon as possible.  Endpoints MUST NOT send a RequestConnectionId message when an existing request is still unfulfilled; this implies that endpoints needs to request new CIDs well in advance.  An endpoint MAY ignore requests, which it considers excessive (though they MUST be ACKed as usual). </ins> Endpoints MUST NOT send either of these messages if they did not negotiate a connection ID.  If an implementation receives these

Discussion:
messages, but also forbid having multiple ones outstanding. NAME NAME
A client that migrates to a new point of network attachment probably wants to use a new connection ID. But that attempt will result in linkability if the server doesn't also change. How do we manage that? One approach is to use the cid_immediate instruction. But clients need to be careful to include that instruction in every packet they send lest the server miss it. QUIC takes a different approach, which is to number all connection IDs combined with a ratchet. If connection ID N is used by one endpoint, its peer has to use connection ID N or greater on that same network path.
The QUIC DT on this subject has come up with a different design: you use a new connection ID when you observe a path change endpoints need to provide their peers enough connection IDs that they shouldn't run out when an endpoint stops using a connection ID, there is a new "retire connection ID" message that is used to signal that it is no longer needed endpoints that receive this "retire connection ID" are expected to replenish the supply of connection IDs at their peer
Point (1) is sort of implicit in the text, and I agree we should add it. Points (2)-(4) are about ensuring that the other side has enough CIDs. In QUIC, this is the server's job and there's no real way for the client to say that it doesn't have enough CIDs or tell the server how many. It can just say that it is done using some set of CIDs and this tells the server to send more, but the server has no idea how many. By contrast, the DTLS design is for the client to tell the server when it wants more CIDs and the server gets to retire them. ISTM that this is a more flexible design in that the server can change CIDs whenever it wants (e.g., for rekeying of the CID encryption key). IIRC much of the motivation for the design with QUIC was not to have to interlock with the ACK, and in this respect the situation here is the same as with the KeyUpdate, which is that the QUIC design has the advantage that it doesn't need to interlock with the ACK to know when things have change. But that doesn't apply here for the same reason as with .

So I think my proposed resolution is just to add that you should change CIDs whenever you change paths and should request enough CIDs that you have a hot spare. I could imagine a way for the server to say what specific keys it wants to invalidate, but I'm not sure that's necessary. I do think we should enhance RequestConnectionId to have a count.
NAME
NAME
(Just noting my earlier thoughts here so they're saved somewhere) Overall, only concern is around the rate at which you can send additional connection IDs to the peer vs. the rate at which you retire them. My understanding is that they are all retired at once, but need to be provided independently. It seems like there could be situations, especially for a sender that needs to migrate rapidly (say away from and then back to some specific interface), where this leaves the sender without a CID to switch to. Allowing multiple CIDs in the messages as in looks like it generally resolves this. Also noting that infinite looping in response to peer changes is covered by the sequence number.
This mirrors an open topic of discussion in QUIC, and I assume that we'll want to take the lessons learned there and probably copy whatever the conclusion is. The problem is that the current design has a server remember all connection IDs that it ever minted. Over time, that might be infeasible for a server. It might be good to limit the number that are in use.
This isn't correct. In DTLS, as opposed to QUIC, new connection IDs may be marked as , in which case the peer is required to stop using any old CIDs immediately. The document could probably use some more text here, but the basic idea is that once a cid_immediate message has been ACKed, you know that any old CIDs are no longer valid.
This message appears to be lacking a codepoint. Also, is this a Handshake message? If so, does it enter the transcript (I assume not).