Draft: draft-ietf-quic-transport

Commentary: State requirement that clients must wait until the server considers the handshake finished before starting migration . 
 If people want to talk about this this week , then this needs an issue . 
 that would be issue 
 I like the latest text referencing handshake confirmed 
 I was waiting for ... 
 I know :-) 
 In migration interop tests , the Picoquic client was starting to simulate NAT rebinding just after obtaining the 1 - RTT read and write key . That turns out to be very messy , because at that point there is no proof that the server has received the client finished message , let alone acknowledged it . As far as tests are concerned , there is an easy fix : only start the migration tests after the client has received from the server an ACK of one of its 1 - RTT packet . That 's the moment when the client knows for sure that the handshake is successful . The migration before handshake complete is messy because the client will try to re - transmit handshake messages that have not been acknowledged , and has some kind of dilemma . Should these re - transmissions aims at the original  used during the handshake , or at one of the new CID selected during the migration ? What if the continuity of the new path has not been yet verified ? What if the continuity test was lost ? Do we have an actual need to support migration before the handshake is fully completed ? In practice , the handshake packets create a NAT mapping , and it is rather unlikely that this mapping will just disappear before the few RTT required to complete the handshake . In fact , it is possible , maybe likely , that packets received from an alternative address during the handshake comes from attackers , not from the actual client . I think the implementations would be simpler and more robust if the spec stated that clients should not initiate " voluntary " migration before the handshake is fully complete . This means 1 - RTT ACK received , or ACK of last handshake packet from the client , whichever comes first . Similarly , servers should not try to migrate connections before receiving at least one 1 - RTT packet from the client through the same addresses and ports as the Initial messages . 
 Since we decided to use timers to drop drop Handshake keys , a peer can never be sure when the other side actually finished the handshake , unless it proactively sends 1 - RTT packets . This leads to problems in the case where you just pre - connect a QUIC connection , but neither peer has any data to send . 
 In theory the key event is " server receives the client Finished message " , which the server sees directly , and the client notices when the Finished message is acknowledged . So there is always that , even if the connection is idle . Plus , migration supports requires sending NEW CONNECTION ID frames to the peer , which I suppose do count as " proactively sent 1 - RTT packets " . 
 I think stating that endpoints should not initiate migration before the handshake is fully complete would make a lot of sense . In addition to reducing the potential for complexity around those interactions and the handshake , it seems like the need for migration at that point in the timeline can mostly be satisfied by a new connection on an alternate path . If we do n't have a lot of activity happening yet on the connection ( although interesting thought about the NEWCONNECTIONID frames ) , it seems like you do n't really lose a whole lot by opening a new connection instead of migrating a pre - connected connection that has n't otherwise been used . That makes me less concerned about when the threshold should be . 
 The ACK for that could be lost . The client will then start the handshake timer and keep retransmitting the Finished , until it receives an ACK ( assuming that the server keeps the keys around for long enough , which it currently does n't , see ) . 
 I get the issue in . But regardless , there is an issue with engaging in migration when the handshake is not complete ... 
 I thought we decided that we should n't support migration before completing the handshake . It 's probably not written down , so we should state that explicitly . The value is tiny and the complexity is substantial . 
 Is n't this already made explicit in Section 9 ? 
 I think there are two separate issues : 1 ) There is some fuzziness about what " handshake is finished " actually means . The messiness that we observed in the tests was due to repeating the CFIN handshake packet while engaged in migration . Thinks get much better if the client waits until CFIN is acknowledged . 2 ) The problem is with server response to NAT Rebinding . Even if the client does not initiate migration , a NAT could decide to change its translation . My take is that both sides should ignore such NAT rebinding before the handshake is finished . That is , have exactly one address pair for the connection and stick to it until handshake done , do n't even think of changing midway . The justification for ( 2 ) is that changing addresses mid - handshake in response to NAT rebinding opens an interesting attack surface , with man - on - the - side sending copies of good packets with spoofed IP addresses . Given that actual rebinding just after a mapping is created is pretty rare , chances are that most " rebinding during handshake " will be of the " man on the side " variety . It is more robust to just ignore them . 
 Thanks for finding the text . Ah , the CFIN , the gift that keeps on giving . I agree with on 2 . We previously discussed whether changing the 5 - tuple during the handshake was allowed , and decided it opened up a huge number of attacks we were n't sure we could fix , so we should require it be fixed until handshake completion . 
 I agree with we could add text to that section to clarify what handshake finished means and what servers should do if they detect a NAT rebinding during the handshake . 
 There is also the client cert auth post handshake thing ( which I do n't understand , but I would assume it also depends on a clear definition of when the handshake is complete . 
 Based on there being existing text , I think that we 'll just use this for clarifying where the boundary is . PRs sought . 
   
 Tokyo conclusion : the answer to will provide a basis for defining the transition point . has a PR and can update that when we have an answer there . 
 Updated the text to reference the output of PR as agreed during the London interim . 
 this one looks good to go . 
 Quick question : We 're forbidding active migration during the handshake here , but what about a passive NAT rebinding that may happen ? We obviously ca n't forbid that , so we must either handle it or have the connection die quickly ? 
 That 's an issue , but a different one . 
 What said . I would personally treat NAT rebinding during handshake as an error , on the assumption that it will be extremely rare and is caused by a broken NAT . We generally assume that NAT keep a UDP mapping active for at least 30 seconds -- the BEHAVE recommendation was 2 minutes . Having a mapping change in fewer than 2 RTT means the NAT is broken . 
 Closing the connection introduces yet another way an attacker can interrupt the handshake . It may be the preferable option , but it 's worth noting . 
 You do n't have to close the connection to protect against NAT rebinding . Ignoring packets from the wrong addresses during the handshake is simpler and more robust . The picoquic implementation does something like that : accept the content of the handshake packet ( not initial ) if it decrypts correctly , ignore any address change until the handshake is confirmed . 
 Good point , that SGTM . 
 Waiting on PR to close this issue . 
 Looking good !
Paragraph (version A):
Data sent in CRYPTO frames is not flow controlled in the same way as
stream data.  QUIC relies on the cryptographic protocol
implementation to avoid excessive buffering of data, see QUIC-TLS.
The implementation SHOULD provide an interface to QUIC to tell it
about its buffering limits so that there is not excessive buffering
at multiple layers.
Paragraph (version A):
Packets with long headers include Source Connection ID and
Destination Connection ID fields.  These fields are used to set the
connection IDs for new connections, see negotiating-connection-ids
for details.
Paragraph (version B):
Packets with long headers include Source Connection ID and
Destination Connection ID fields.  These fields are used to set the
connection IDs for new connections; see negotiating-connection-ids
for details.
Paragraph (version A):
Endpoints store received connection IDs for future use.  An endpoint
that receives excessive connection IDs MAY discard those it cannot
store without sending a RETIRE_CONNECTION_ID frame.  An endpoint that
issues connection IDs cannot expect its peer to store and use all
issued connection IDs.
Paragraph (version A):
An endpoint can change the connection ID it uses for a peer to
another available one at any time during the connection.  An endpoint
consumes connection IDs in response to a migrating peer, see
migration-linkability for more.
Paragraph (version B):
An endpoint can change the connection ID it uses for a peer to
another available one at any time during the connection.  An endpoint
consumes connection IDs in response to a migrating peer; see
migration-linkability for more.
Paragraph (version A):
Version negotiation ensures that client and server agree to a QUIC
version that is mutually supported.  A server sends a Version
Negotiation packet in response to each packet that might initiate a
new connection, see packet-handling for details.
Paragraph (version A):
The connection ID can change over the lifetime of a connection,
especially in response to connection migration (migration), see
issue-cid for details.
Paragraph (version B):
Implementations need to maintain a buffer of CRYPTO data received out
of order.  Because there is no flow control of CRYPTO frames, an
endpoint could potentially force its peer to buffer an unbounded
amount of data.
Paragraph (version B):
Being unable to buffer CRYPTO frames during the handshake can lead to
a connection failure.  If an endpoint's buffer is exceeded during the
handshake, it can expand its buffer temporarily to complete the
handshake.  If an endpoint does not expand its buffer, it MUST close
the connection with a CRYPTO_BUFFER_EXCEEDED error code.
Paragraph (version A):
An endpoint MAY send a stateless reset in response to a packet with a
long header.  This would not be effective if the stateless reset
token was not yet available to a peer.  In this QUIC version, packets
with a long header are only used during connection establishment.
Because the stateless reset token is not available until connection
establishment is complete or near completion, ignoring an unknown
packet with a long header might be more effective.
Paragraph (version B):
Endpoints MUST send stateless reset packets formatted as a packet
with a short header.  However, endpoints MUST treat any packet ending
in a valid stateless reset token as a stateless reset, as other QUIC
versions might allow the use of a long header.
Paragraph (version A):
The packet might not reach the peer.  If the Destination
Connection ID is critical for routing toward the peer, then this
packet could be incorrectly routed.  This might also trigger
another Stateless Reset in response, see reset-looping.  A
Stateless Reset that is not correctly routed is an ineffective
error detection and recovery mechanism.  In this case, endpoints
will need to rely on other methods - such as timers - to detect
that the connection has failed.
Paragraph (version B):
The packet might not reach the peer.  If the Destination
Connection ID is critical for routing toward the peer, then this
packet could be incorrectly routed.  This might also trigger
another Stateless Reset in response; see reset-looping.  A
Stateless Reset that is not correctly routed is an ineffective
error detection and recovery mechanism.  In this case, endpoints
will need to rely on other methods - such as timers - to detect
that the connection has failed.
Paragraph (version A):
Revealing the Stateless Reset Token allows any entity to terminate
the connection, so a value can only be used once.  This method for
choosing the Stateless Reset Token means that the combination of
connection ID and static key cannot occur for another connection.  A
denial of service attack is possible if the same connection ID is
used by instances that share a static key, or if an attacker can
cause a packet to be routed to an instance that has no state but the
same static key (see reset-oracle).  A connection ID from a
connection that is reset by revealing the Stateless Reset Token
cannot be reused for new connections at nodes that share a static
key.
Paragraph (version B):
Similarly, a request to cancel stream transmission, as encoded in
a STOP_SENDING frame, is sent until the receiving part of the
stream enters either a "Data Recvd" or "Reset Recvd" state; see
solicited-state-transitions.
Paragraph (version A):
The server MUST also limit the number of bytes it sends before
validating the address of the client, see address-validation.
Paragraph (version B):
The server MUST also limit the number of bytes it sends before
validating the address of the client; see address-validation.
Paragraph (version A):
The value in the Unused field is selected randomly by the server.
Paragraph (version A):
The ACK delay exponent is an integer value indicating an exponent
used to decode the ACK Delay field in the ACK frame (frame-ack).
If this value is absent, a default value of 3 is assumed
(indicating a multiplier of 8).  The default value is also used
for ACK frames that are sent in Initial and Handshake packets.
Values above 20 are invalid.
Paragraph (version B):
The ACK delay exponent is an integer value indicating an exponent
used to decode the ACK Delay field in the ACK frame (frame-ack).
If this value is absent, a default value of 3 is assumed
(indicating a multiplier of 8).  Values above 20 are invalid.
Paragraph (version B):
The three ECN Counts; see ack-ecn-counts.
Paragraph (version A):
An IANA registry is used to manage the assignment of frame types, see
iana-frames.
Paragraph (version B):
An IANA registry is used to manage the assignment of frame types; see
iana-frames.
Paragraph (version B):
An endpoint has received more data in CRYPTO frames than it can
buffer.