Draft: draft-ietf-quic-transport

Commentary: As of , the client MUST use the same handshake message . 
 That 's quite complicated , and I 'm not sure if we 've chosen the right design here . I 'd like to keep this PR editorial though . I opened to discuss this . 
 In , points out that after a Retry , all 0 - RTT packets sent in the first flight are still valid , although they will probably have been dropped by the server ( unless there 's significant reordering ) . That means that a client SHOULD retransmit all 0 - RTT packets in the second flight . We now have two different scenarios : the case of a HelloRetryRequest , the client is prohibited from sending 0 - RTT , and has to cancel retransmissions for all outstanding 0 - RTT packets . the case of Retry , the 0 - RTT packets from the first flight are declared lost ( without any effect on the cwnd though ) and retransmitted . Considering that Retry adds a roundtrip anyway ( and thereby limits the usefulness of 0 - RTT ) , and that we only expect it to be used by a server that 's under attack ( which makes it likely to refuse 0 - RTT later in the handshake ) , does it really make sense to send 0 - RTT in that case ? 
 I am not sure if I agree with the observation . The transport draft states that 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 receives ( ) . Notice that the server is allowed to " buffer " 0 - RTT packets . I am not sure if I like this ambiguity ( because I think most if not all of us will be dropping 0 - RTT packets that carry the original DCID when sending a Retry ) , but IMO the draft is clear . 
 thanks for pointing that out . My point is that we should change the draft ( i.e. this is a design issue , not an editorial issue ) . The reason a server ( or a LB ) performs a Retry is that it either has reasons to suspect that the client is n't reachable at the 2 - tuple it sent the packet from , or that it is under load , and either uses the Retry to redirect traffic to a different backend server , or just to buy itself some time Under both circumstances , a server would n't want to allocate additional state for buffering 0 - RTT packets . I 'm therefore suggesting to change the draft such that : server that performs a Retry MUST discard 0 - RTT packets . client MUST NOT use 0 - RTT after a Retry was performed . Does that make sense to you ? 
 Yeah , I can envision a server that considers buffering some number of packets to be cheaper than doing a TLS handshake . For such servers , delaying the TLS handshake until client proves it 's existence but buffering the 0 - RTT packets in the meantime would make sense . That said , I 'd be fine with this , assuming that the discarded 0 - RTT packets are the ones that carry the original DCID . I would prefer not having this requirement . Once the client is known to exist , a server needs to communicate with the client . Use of 0 - RTT helps reduce the server load , because when used , average lifetime of connections becomes 1 - RTT less . That leads us to having less concurrent connections . 
 When our implementation does Retry , it 's because we 've hit a memory pressure limit and we want to protect ourselves from attack . If a client supplies us with a valid token , we will accept 0 - RTT still , but we wo n't buffer it from the previous Initial ( without a token ) . So , if the client gets a Retry and still wants to do 0 - RTT , they need to retransmit it , with the new CID , in a new packet ( with a new packet number ) . I do n't see why that design should be prevented . 
 Ok , I see that there 's value in doing 0 - RTT after a Retry , and furthermore , there seem to be good reasons ( prevention of tampering by middle boxes ) to disallow 0 - RTT after a HelloRetryRequest in TLS 1.3 , as pointed out OOB . Since we can assume that most ( all ? ) server implementation will drop 0 - RTT packets when sending a Retry , the only reasonable thing to do for a client is to treat all 0 - RTT packets as lost and retransmit them . Considering that , it would make sense to require servers to drop all Retry packets from the first flight , as suggests . 
 Thank you for suggesting a path forward . I think my weak preference goes to something slightly different . I think we are in agreement that most if not all the servers would not buffer the 0 - RTT packets carrying the original DCIDs when they send Retrys . It makes sense to acknowledge the fact in the specification and suggest clients to retransmit 0 - RTT data it has already sent . What I am not sure is if there is a reason to forbid servers from buffering such 0 - RTT packets . From client 's point of view , sending 0 - RTT data once per connection is an optimization . Retransmitting 0 - RTT data when the server sends a Retry is further optimization . If we think that way , servers that buffer 0 - RTT packets when sending a Retry has increased chance of utilizing 0 - RTT data . Compared to that , there is no reason to mandate servers to drop 0 - RTT packets . To summarize , I think all we need to clarify is that servers responding with Retries are likely to discard 0 - RTT packets that carry the original DCIDs and therefore that retransmitting 0 - RTT data makes sense . But nothing more . 
 What if client takes action on Retry , and the old 0 - RTT state lingers - would n't that make servers more vulnerable to DDoS attacks from packet sniffers ? 
 This also bears on . If the DCID does n't change , then the server wo n't be able to differentiate the first flight of 0 - RTT packets , which you 're proposing to drop , from the second flight of 0 - RTT packets which it accepts . The current text says that the server MAY buffer and process them later ; you 're saying that servers probably wo n't . I think that 's fine , but some might -- hence , I favor suggestion to retain the permission to buffer but the caution to the client that the packets were quite possibly lost / dropped . In terms of actual spec change , I think that means this text in : ... becomes a SHOULD instead of a MAY . 
 It seems like you have sorted this out . I have no problem with using " SHOULD " over " MAY " here . Note that the reason we have this distinction is logical separation of the mechanism of Retry and 0 - RTT acceptance . Retry strictly precedes the connection attempt . No point in blocking 0 - RTT if you have to Retry . HelloRetryRequest is different in that certain characteristics it might cause to reset affect whether the 0 - RTT works . Retry is required to use the same ClientHello , so there is no need to have the two interact ; you can treat a Retry almost as a loss event for the first Initial and everything works fine . 
 So , the effect of not changing the handshake message is that all previously - sent 0 - RTT data is still valid , but has potentially / probably been lost rather than queued . Clients obviously MUST NOT reuse the packet number for different data , but in their not - resetting , they also ca n't change the data that they 've already sent in those packets . They 'll need to retransmit it , because otherwise there 's a potential DoS attack by delaying / replaying a 0 - RTT packet by one RTT against a server that does Retries . This PR looks good to me as an editorial improvement . Regarding point , the transport draft explicitly states that a server sending a Retry can buffer 0 - RTT packets that carried the original DCID , and process them after receiving a response to the Retry . To put it differently , I think we are clear on the semantics and that there are ways to implement this without having security concerns . That said , I understand that has opened a design issue ( ) to discuss if that is the design we want to have . LGTM
Paragraph (version A):
A client MUST NOT reset the packet number it uses for 0-RTT packets.
The keys used to protect 0-RTT packets will not change as a result of
responding to a Retry packet unless the client also regenerates the
cryptographic handshake message.  Sending packets with the same
packet number in that case is likely to compromise the packet
protection for all 0-RTT packets because the same key and nonce could
be used to protect different content.
Paragraph (version B):
A client MUST NOT reset the packet number it uses for 0-RTT packets,
since the keys used to protect 0-RTT packets will not change as a
result of responding to a Retry packet.  Sending packets with the
same packet number in that case is likely to compromise the packet
protection for all 0-RTT packets because the same key and nonce could
be used to protect different content.
Paragraph (version A):
A client SHOULD instead generate a fresh cryptographic handshake
message and start packet numbers from 0.  This ensures that new 0-RTT
packets will not use the same keys, avoiding any risk of key and
nonce reuse; this also prevents 0-RTT packets from previous handshake
attempts from being accepted as part of the connection.