Draft: draft-ietf-quic-transport

Commentary: Add remaining changes from , specifically : Handshake finished -confirmed Move text around to clarify existing requirements around local addresses and CIDs Add note nearby when describing use of SPA that preferred address can be used with CIDs other than that specified in the TP ( this is already described later in the document ) ( supersedes it ) . 
 We 've moved a bunch of stuff to semicolons ( I did like parenthesis a bit too ) , so I kept these consistent since we 're touching those lines here already , and I will send a separate PR that just changes some of the others that are n't related to any of the changes in this PR . 
 Thanks for the excellent comments and suggestions ! Applied all the changes , should cover everything currently outstanding . 
 you asked that this be blocked by requesting changes . That means that you volunteered to re - review too :) Can you take another look to verify that the recent fixes address your concerns ? 
 At the moment , states : I think these paragraphs have two issues : It begins with " once handshake is finished , " but I am not sure if we define when a handshake finishes . I think we should change this to " once handshake is confirmed , " as that is the point where we allow connection migration . It states that the connection ID to be used on the new path would be the one using TP.preferredaddress . I think that is incorrect , as the server might have requested retirement of the CID provided by that transport parameter by the time the client initiates ( or finishes ) path validation . It should either be an address provided by that transport parameter , or an unused CID provided by the server ( i.e. through NCID frames ) . In fact , when the server sends an NCID frame with   To set to a value greater than 1 , the client should not be using the CID provided by the transport parameter . Note that this problem is orthogonal to , because these actions in relation to preferred address happens at some point after the handshake is confirmed . 
 This text precedes a clear definition of handshake confirmed , so I strongly agree with your first suggested clarification . I can imagine cases when the CID should be based on the path , so I 'm less clear on the correct behavior for the second point . By definition , if the CID provided in the transport param has been retired it should not be used to initiate path validation . But I 'm unclear if the preferred behavior is do n't migrate if you have n't already initiated migration or to use one of the newer CIDs . 
 Thank you for your comments . First of all , let me state that we do not need to forbid such a design . However , in a design that expects CIDs to be specific to the server address being used , a server can not issue a new CID until the migration to the preferred address completes . This is because if a server sends a NCID frame from the original server address before the client completes migration to the preferred address , the server can not tell if the client would use that issued CID on the original path ( this happen when the client fails to migrate to the preferred address ) , or if it uses that CID on the migrated path . Therefore , this issue does not have any effect on such a design . The question at stake is the client behavior we want to recommend , when the server sends a new CID ( or retires CIDs ) before migration to the preferred address completes . My view is that TP.preferredaddress is a mechanism of specifying an alternative IP address , that " happens " to also carry a new CID , so that the client can always have an unused CID in hand when it initiates migration to the preferred address . It is actually simple to implement in such way . What you would do is this : When receiving TP.preferredaddress , store preferredaddress . CID exactly the same way as you would do when receiving an NCID frame , and separately store preferredaddress . IPaddress . When handshake is confirmed , if preferredaddress . IPaddress is stored , initiate a migration to that address , using a CID from a bucket that holds the unused CIDs . As stated above , such a design would work perfectly fine with servers issuing CIDs specific to server addresses , because a client would have only one unused CID to pick from when talking with such a server . The design is also simpler than having special case code that associates preferredaddress . IPaddress and preferredaddress . CID , and handles retirement cleanly . 
 It 's a little trickier for servers . Let 's say , hypothetically , that the server knows it 's using a different CID pool on the alternative address ; it picks one for the public address in the handshake , then gives one from the preferred address 's CID pool in the TP . It does n't send NCID frames right away . That 's fine . But let 's say the client does n't migrate successfully . At some point , the server wants to start issuing the client new CIDs for one or the other of the paths , but QUICv1 does n't have a way to identify path - bound CIDs . So the server has to give up on the preferred address if it ca n't handle CIDs coming to either interface . There is n't a defined cut - off for when the server should give up expecting the connection attempt , so the best way to do this is to put RPT=2 in the NCID frames . It seems cleaner initially to special - case the CID from the Preferred Address , and say that you have to use that specific CID to do the migration . But even with that code , the server has to do the same thing : wait to see whether the client migrates or not before issuing new CIDs . I think the piece we 're missing is that when a client declares a migration unsuccessful , it MUST / SHOULD retire the CID it used to attempt the migration . That gives the server a clear signal , succeed or fail ; it can then proceed to issue CIDs for the surviving server address . 
 Good suggestion on retiring the CID immediately if the migration was unsuccessful . That does provide a clearer signal than the ambiguity we have today . 
 That 's a keen observation . I personally favor the idea of using the RETIRECONNECTIONID frame to indicate if the client has finished migration to the preferred address or if it would continue using the original address . However , such change would require every client to recognize TP.preferredaddress , in sense that even a client lacking support intentional migration would be required to signal the retirement of the CID associated to TP.preferredaddress . I think we have considered until now that a client that does not implement migration ( or migration to preferred address ) to simply ignore this transport parameter . We need to be clear about that . 
 I think this is only particularly relevant to SPA , since that 's the only time that a server is expecting a migration . Definitely worth being clear about what to do if you also disable migration , but implementations that disable migration still need 99 % of the rest of the machinery for other purposes , requiring them to immediately send retire for the TP.preferredaddress seems okay , if slightly less convoluted than having some " ignore this if that " statement around the whole thing . 
 As requested , I 'm forwarding regarding : This implies a semantic to the retirement of connection IDs that is not already defined . It says that in addition to releasing the resource , the server can say definitively that those other network paths wo n't be used . But this is misleading because retiring CID 1 does not prevent CID 4 from being used on that path . Nothing says that the connection IDs sent in NEWCONNECTION_ID have to be used on one or other path . Better to keep the requirement where it is : do n't migrate back if you use a preferred address . Yes , that means that servers ca n't be sure of behaviour of clients here , but they can use the destination address to confirm acceptance of the preferred address or not . That should suffice . 
 Retirement of either of these connection IDs notifies the server of the address the client has chosen . I think that the point being missed here is that under a given condition the server can determine the path being used for CID4 . If the CID4 is issued prior to the client choosing the path , it is true the server would not be able to determine the path on which CID4 will be used . But if the server withholds NCID frames until the client chooses the path and notifies its choice by retiring one of the first two CIDs , then the server can tell for sure . Because either of the first or the second CID would be retired first , and that tells the server the path the client has chosen . As we agree , we already state that a client can not come back to the original address , once it migrates to the preferred address . The benefit of requiring such retirement is that the server can issue CIDs specific to the server address , as pointed out by Assuming that such server deployment would be within our design scope , I think requiring such retirement is not a bad idea . 
 If the migration is unsuccessful , the client must never try the preferred address again ( MUST continue sending all future packets .... ) . So as says , the server can issue address specific ( not path - specific ) CIDs once it knows whether the client 's migration succeeded or failed . But is correct that this is implicitly sending a signal about failed migration . If the server sees a CID retired , apparently never used , it might be able to infer that the CID was used for a failed migration , but this case is unique in that the server needs to take some action for a failed migration and uses this signal to do it . 
 So far , we have n't tied the server 's knowledge of the client 's address to anything about a CID , and a lot of the attacks against migration involve an actor on the network changing the path & address from which the server thinks the packets are coming , even if the client does not actually change anything . I have n't thought this all the way through yet , but it seems as though trying to have the server issue " address - specific " CIDs leads us into some potentially tricky territory . 
 made me realize the nature of the hazard here . It seems fairly natural for an server to bind connection IDs to the current socket address . That is part of why we have new connection IDs attached to the preferred address and the forced retirement . After all , if the server uses a different target address , the hash at a load balancer could change and cause packets to be badly routed . Not including the target address in the hash would work , but it would force connection IDs to be bigger . But this all assumes that you never expect the server to migrate . If the server ever wanted to migrate , then the client is stuck with a bunch of unusable connection IDs for its own migrations . We decided that only clients can initiate migration in this version , which might mean that we do n't need to worry about this case . We decided not to allow server migration primarily to avoid having to deal with the complex problems that ICE handles . But it was only the lack of mechanisms , not a structural constraint . Now it seems like we have a structural constraint that would prevent server migration . At a minimum , it seems like we should probably acknowledge this constraint somehow . 
 The summary of our discussion over dinner last night is that there are various mechanisms a server could employ , but they all depend on one key point : Both endpoints are under joint control , because they 're cooperating to handle the connection . Therefore , it 's possible to generate a CID that each endpoint will be able to work with . ( There are various approaches to generating such a CID , which are implementation - specific ; one or more approaches might be described in the QUIC - LB draft . ) That means we do n't need to separate CIDs by endpoint ; if the migration is successful , the server could choose to issue CIDs that are n't valid on the handshake endpoint , which is now out of the picture . 
 Seems like a great task for V2 : define a policy for handling CID . Or we could try do that in V1 and ship in 2021 . 
 Discussed in ZRH . Proposed resolution is to close with no action . New Editorial issue to be opened to explain the intended use of and the CID it contains . 
 An important point to capture here is that the server is responsible for ensuring that the connection IDs are not bound to one or other address at this stage ( if migration is successful , later ones might be ) . Thus , the connection ID in the transport parameter is no different to any other connection ID ; it only exists here because using the new address is unusable without more connection IDs being available . 
 Please do note that this issue points out other editorial concerns ( see the original problem statement ) . I 'd prefer seeing them being addressed to ( and we have a WIP text in ) . 
 My hope was that the changes in would help with the editorial parts of the . However , that seems to be stalled . I am going to mark this as proposal ready and will open an editorial issue to track the remaining work on clarifying the text . To provide abundant clarity : the proposed resolution to the design issue is to make no substantive changes to the protocol . 
 To echo : I think was going to be replaced with something a bit more condensed , which means that the result here will be " no design changes to be made , editorial text clarified via and " . 
 Thank you so much for doing this work . I think the changes are spot - on . I see some improvements suggested by but otherwise looks perfect . I suggested some clearer language , but this looks fine . For the semicolon ones which are n't in text you 're actually changing , it might be better to leave them and do a separate editorial PR that cleans these up . I 'm sure the ones that hit the updated reference are n't the only ones . Thanks for the change .
Paragraph (version B):
As discussed in migration-linkability, endpoints limit the use of a
connection ID to packets sent from a single local address to a single
destination address.  Endpoints SHOULD retire connection IDs when
they are no longer actively using either the local or destination
address for which the connection ID was used.
Paragraph (version A):
Receiving acknowledgments for data sent on the new path serves as
proof of the peer's reachability from the new address.  Note that
since acknowledgments may be received on any path, return
reachability on the new path is not established.  To establish return
reachability on the new path, an endpoint MAY concurrently initiate
path validation migrate-validate on the new path.
Paragraph (version B):
An endpoint MUST NOT reuse a connection ID when sending from more
than one local address, for example when initiating connection
migration as described in initiating-migration or when probing a new
network path as described in probing.
Paragraph (version B):
Similarly, an endpoint MUST NOT reuse a connection ID when sending to
more than one destination address.  Due to network changes outside
the control of its peer, an endpoint might receive packets from a new
source address with the same destination connection ID, in which case
it MAY continue to use the current connection ID with the new remote
address while still sending from the same local address.
Paragraph (version B):
These requirements regarding connection ID reuse apply only to the
sending of packets, as unintentional changes in path without a change
in connection ID are possible.  For example, after a period of
network inactivity, NAT rebinding might cause packets to be sent on a
new path when the client resumes sending.  An endpoint responds to
such an event as described in migration-response.
Paragraph (version A):
The PMTU is the maximum size of the entire IP packet including the IP
header, UDP header, and UDP payload.  The UDP payload includes the
QUIC packet header, protected payload, and any authentication fields.
The PMTU can depend upon the current path characteristics.
Therefore, the current largest UDP payload an implementation will
send is referred to as the QUIC maximum packet size.
Paragraph (version B):
Datagrams containing Initial packets MAY exceed 1200 bytes if the
client believes that the network path and peer both support the size
that it chooses.
Paragraph (version B):
One way to construct a probe for the path MTU is to coalesce (see
packet-coalesce) a Handshake packet (packet-handshake) with a short
header packet in a single UDP datagram.  If the UDP datagram reaches
the endpoint, the Handshake packet will be ignored, but the short
header packet will be acknowledged.  If the UDP datagram causes an
ICMP message to be sent, the first part of the datagram will be
quoted in that message.  If the source connection ID is within the
quoted portion of the UDP datagram, that could be used for routing.
Paragraph (version B):
A server acknowledges the use of a Retry packet for a connection
using the original_connection_id transport parameter; see transport-
parameter-definitions.  If the server sends a Retry packet, it MUST
include the Destination Connection ID field from the client's first
Initial packet in the transport parameter.
Paragraph (version B):
The value of the Destination Connection ID field from the first
Initial packet sent by the client.  This transport parameter is
only sent by a server.  This is the same value sent in the
"Original Destination Connection ID" field of a Retry packet; see
packet-retry.  A server MUST include the original_connection_id
transport parameter if it sent a Retry packet.
Paragraph (version B):
A variable-length integer indicating which connection IDs should
be retired; see retire-cid.
Paragraph (version B):
The Retire Prior To field counts connection IDs established during
connection setup and the preferred_address transport parameter; see
retire-cid.  The Retire Prior To field MUST be less than or equal to
the Sequence Number field.  Receiving a value greater than the
Sequence Number MUST be treated as a connection error of type
FRAME_ENCODING_ERROR.
Paragraph (version A):
The sequence number of the connection ID being retired.  See
retiring-cids.
Paragraph (version B):
The sequence number of the connection ID being retired; see
retire-cid.