Draft: draft-ietf-quic-transport

Commentary: This touches a lot of places in the document , but I think that the changes are all manageable in scope . The major change here is a move to a uniform 3x limit on sending packets toward unvalidated addresses . Specifically , this applies when the packets are sent in response to another packet . In practice , this means that only servers are affected by this . The consequence of this change is that PATHCHALLENGE wo n't always be padded , as previously agreed . That also means that PATHRESPONSE might not be as well ( if the client migrates , it can send PATH_CHALLENGE in that packet ; though we require that to be padded , we specifically do n't require enforcement , so ... ) . Address validation using this packet works , but this does n't also provide MTU validation . To fix that , I have recommended that a second validation be performed when the address is valid , or there are enough bytes available that the anti - amplification limit is not a barrier . The nice part about this is that unifies the response . We no longer have weird carve - outs for rate limiting or minimum congestion window ( both of which I removed as part of this ) . 
 I was intentionally avoiding " packets " here as the amplification inputs is the size of the UDP payload , and the rules here also use that . Would " bytes " or " bytes of UDP payload " be better ? 
 " bytes of UDP payload " would be the most accurate , but " bytes " also works for me . 
 So those are both performance optimizations that come at the cost of potentially sending more data toward an unverified address . We exempt the client from address validation when it migrates , but that does n't mean we need to recommend that it send a whole bunch . I 'd rather not include these as recommendations . 
 How so ? The server 's address is verified , and that 's where the client would be sending this . 
 That is not the case for a preferred address . It 's possible - if unlikely - that the change in source address means a change in destination also . 
 I would be happy to exempt SPA from these recommendations , as I did n't realize we were even including them as " migration " . 
 Even there , I think that it is a fine performance optimization , but not something I would want to recommend . 
 I too think that these recommendations are unnecessary . Firstly , IMO it is unbalanced to recommend to sending three full - sized datagrams in these cases , when clients are expected to send only one full - sized datagram when creating a new connection . Secondly , when the client migrates to an unvalidated path , we already require them to send a full - sized datagram containing PATH_CHALLENGE . Thirdly , it is not a good idea for clients idle for a long time then elicit NAT rebinding . Rather , endpoints should be exchanging packets periodically , so that the NAT entry persists . Otherwise , the path from the server to the client gets lost . Therefore , I think that there 's no reason to specify optimizations regarding how a client should recover from NAT rebinding . 
 Personally , I side with more on the topic of recommending these behaviors as ways to improve migration scenarios . They do n't have to be framed as explicit recommendations , but could just be mentioned as ways to improve things . To your points , I agree it 's unbalanced , but for both larger server certificate scenarios and 0 - RTT scenarios it might actually make sense to recommend similar client behavior for the handshake . I 'm not sure I understand the point here . Are you saying that because we require 1 full packet , we should n't recommend 3 ? As far as I understand , if the server 's infrastructure can survive NAT rebindings , there is no such recommendation to avoid them . Why waste the keep alives if you do n't need to receive any packet from the server ? Therefore , when the client does end up sending after idle ( which might result in rebinding ) why not account for the possibility of NAT rebinding and send a bit more ? Again , we do n't need to recommend these behaviors . They can just be mentioned as possible solutions to bottlenecks that may arise from migration . 
 Regarding the first two points , I think we should rather not start designing the protocol by discussing how much data clients should send when establishing a connection . Regarding the last point , I think your point is that the optimization might matter when the server knows that it is not going to send any data until it receives something from the client , because otherwise the server will trying to keep the connection open . To paraphrase , the optimization depends on the application protocol , and how that application protocol is used . Another point to remember is that this optimization is unnecessary when NAT rebinding only changes the port number , and if the server does not revalidate the path when only the port number changes . IIUC , these points together lead to the conclusion that the optimization covers a niche that might or might not be possible depending on application behavior . 
 as far I understand ( please correct me if I 'm wrong ) amplification protection still applied to migration as a result of port - only NAT rebinding . We 're just saying that in this case , the server ca n't pad it 's PATHCHALLENGES , so PMTU validation does n't happen along with address validation . The only other exception we make for port - only NAT rebinding is not requiring congestion control reset , though , as already mentioned the idleness that goes along with this scenario should _ trigger that reset anyways . 
 Ah thanks . That 's true ( though I do think that the server does not have to be restricted to 3x when the client unintentionally migrates to a different port , assuming that the server does path validation ) . Anyways , I think my other point still holds , that the optimization is a niche that relies on the properties of an application protocol , and therefore that there is no strong necessity to explain . 
 This is not clear to me from the PR . I 'm personally fine with making an exception for this , but it should be called out in the PR , otherwise I will assume no such exception . 
 While I think that a server does not have to be restricted under certain circumstances , trying to describe the conditions is going to be tricky . Moreover , we have had the restriction for quite some time ; this PR is merely changing the amount of that restriction from 2 MTU per RTT to 3x of the bytes received . Therefore , I think that a new issue is needed if we are going to discuss when a server does not have to be restricted . That said , I would prefer not to ( re)open that discussion ; I think we have discussed it in the past . 
 Can we move the discussion here to the issue , please ? 
 One point that seems to have been lost is the addition of an error code earlier . I think adding an error code for NOVIABLEPATH is a good idea . 
 you might need to rebase your branch to resolve conflicts . 
 I 've implemented the new requirements to pad path challenges in  and I immediately startled hitting asserts in my code during automated testing because the server ended up trying to pad beyond the 3x amplification limit for the new path . What am I supposed to do here ? Pad only up to the 3x limit ? Wait until I have received enough on the path to be able to send a fully padded packet ? Do n't pad , but then track some state to additionally do PMTUD sometime later , after I 've validated the source address ? I might have missed it , but I think this scenario needs explicit text in the spec . 
 Can you walk through the scenario ? The server observes a NAT rebinding or migration and decides that the new client address is not validated . It sends PATHCHALLENGE and pads , but the packets it has received thus far are too small and therefore it immediately exceeds the 3x limit ? This seems like it might be worth fixing . Like you , I do n't have an easy answer . If the client probes the path , there is no issue . However , a small non - probing packet can happen and we need an answer for the server in that case . Curiously , you could send PATHCHALLENGE in a small packet too , but not regard any response as path validation . The client should send PATH_RESPONSE padded and open up the server sending quota , allowing the server to properly probe . 
 The simplest scenario is NAT rebinding , and the first packet received on the path is small . Per - spec , we 're still supposed to send a path challenge , and per my understanding , we 're always supposed to pad those . One option , at least for this scenario would be to make an exception , with the assumption that rebinding should n't change the MTU . But I do n't care for assumptions that could really bite you if you get it wrong . Additionally , it does n't fix the bigger problem if it was n't NAT rebinding . 
 To repeat what has said before , every time we change something , we introduce some issue . If a connection is immediately migrating prior to probing the new path with PATH_CHALLENGE , I believe it either means it 's unintentional or the new path is the only one available . In either case , if the MTU is too small , you 're sunk , so making an exception to padding for cases of immediate migration seems ok to me . The only cost is it may take a bit longer to realize the new path has a smaller MTU ? 
 I might be dumb , but do we require amplification limit to be applied to path challenges ? I am not sure if there 's such a requirement . I do not think we have to have that . Unlike a DDoS attack using Initial packets , an off - path attacker can not mount a DDoS attack using spoofed packets to elicit path challenge ; only an MOTS attacker can do that . I would also point out that because the server has per - connection state , it will rate - limit ( or bail out from ) the number of path challenges it sends . 
 If I understand the spec correctly , server enforces amplification protection before it receives first client Handshake packet . So the intended scenario is that server sends PATHCHALLENGE in its 0.5 RTT flight . But do we need to send them ? Because receiving client Handshake validates client address , server does not need to send PATHCHALLENGE during handshake . 
 I went back and looked at the specs , you 're right that we do n't seems to require amplification protection in the spec explicitly for migration , but is that really correct ? I figured it was an amplification attack vector just like the handshake ( though a bit less impactful since you have to handshake first ) . Could n't you connect to a server that has a larger initial window and then send a request for a large response , spoofing the target IP address ? Rinse and repeat ? If we really do n't need to have amplification protection for migration , then I 'm fine to close this issue ( and go remove some code ) . 
  , is right , I ca n't find any restriction on use of paths after migration . Our limits for anti - amplification are specifically : handshake , closing , and stateless reset . No other mention exists . That does n't mean that  is wrong to have this code though . Without limits , an attacker could connect to a server then spoof a bunch of small packets to cause an amplification attack toward a chosen target . We can turn that into a low - grade amplification attack if we allow probes to be exempt from that limit . It 's low - grade then for several reasons . It is stateful at the server and the connection establishment is expensive . A single connection can be used to attack multiple targets , but a server wo n't send many packets to each . In my half - written migration code , this results in just three packets , which is n't that useful . After digging in more here , I think that we can make two changes , one the direct response to this issue , but the first is in response to the unstated issue that we do n't have anti - amplification protection for migration . the 3x rule for any unvalidated path . path probes to ignore the 3x rule . The alternative is to leave this alone and focus on clarification . We have a requirement that the server reduce its congestion window , so the concrete amount of amplification that can be gained without the 3x rule being in place is not that much relative to the cost of setting up the attack . I 'm ambivalent on this . I can see the appeal of the principled fix , but getting it right could be tricky . 
 I think leaving this alone and focus on clarification SGTM . Amplification limits are tricky , as evidenced by the repeated tweaks we 've needed to enforce the 3x limit during the handshake , so adding one at this stage sounds risky . Given there is some ' protection ' by requiring the handshake to complete prior to migration , I think this protection is sufficient as long as one ca n't repeatedly abuse migration by immediately migrating over and over . I 'm not sure if the existing text provides enough protection or not from that situation or not ? 
 I think that there is an existing MUST regarding this problem . It states that until a peer 's address is deemed valid , an endpoint MUST limit the rate at which it sends data to this address . The endpoint MUST NOT send more than a minimum congestion window 's worth of data per estimated round - trip time ( kMinimumWindow ) ( ) . So to answer to current limit is not INITCWND , but 2 MTU . I think that this limit might be a bit on the loose side , but I wonder if there is a need to change . PS . If we are to change the existing rule , I like what has written above . 
 Thanks for finding that kMinimumWindow thing that makes me much happier . Relative to the cost of mounting the attack , I do n't expect an attacker to find that attractive . 
 Ok , so we 're saying that instead of the 3x limit , we 're going to use 2 MTU per Initial RTT ( path challenges are n't retransmitted on loss , right ? ) ? I 'm just trying to reason about how I should update my logic . It used to be : Now , it should be something like this ? And , just so my understanding is clear , if I receive a minimum size packet ( 10ish byte UDP payload ? ) from an unvalidated path on average 1/2 x INIT_RTT , then I will be amplifying that traffic by ~100x , right ? And a man - on - the - side attacker could just take every small packet destined to my server that it sees , and race a copy , with changed source address to some target address , and I 'd start doing this amplification for all those connections ' packets ? 
 For one unvalidated path , an endpoint would send no more than 2 MTU worth of data per every Initial RTT ( 333ms ) . Therefore , while the amplification factor will be large , the amount of traffic being sent is going to be small . For all the unvalidated paths from which an endpoint might receive data , the upper bound would be 2 MTU multiplied by the number of paths that an endpoint can validate concurrently . From what I understand , each path validation attempt is abandoned by a timeout , that is greater than 2 seconds ( ) . 
 Ok . I did some excel math to get a more accurate number , and it seems at least for IPv4 , the amplification ratio is closer to 25x . To make use of this though , as you indicated  , the attacker would be limited by the 2 MTU , per unvalidated path . Assuming a server tracks only 4 paths  , per connection , and an attacker opens 1000 connections to the server and uses them as an amplification vector , the attacker can send packets at less than 10Mbps to get almost 250 Mbps send to the target . Do this with a couple different servers ( which ever you find to track the most parallel paths ) and I 'd say you have a pretty good attack vehicle . And as I mentioned above , a MoTS can copy / modify / race valid connection traffic to achieve similar results . Obviously getting a connection to the handshake confirmed state before it can be used as an amplification vector is a hurdle , but I would n't say it a very large one . The attacker can open connection to many different servers to mask it 's attack origin somewhat . IMO this still seem like a very valid threat we at the very least should mention in the spec , if not actually fix . 
 I think that I 'd like to see the working for that , because I have a larger number , depending on how many probes are involved ( at 3 probes per path , the number is 160 - ish for a server that uses one byte connection IDs , or 42 for a more reasonable 8 byte CID ) , at last for those few paths that a server might choose to validate . That is , if you take the handshake cost out , which is fair if you consider them amortized , but a server will only probe so many paths . If you take the handshake into account and leave aside the possibility that you can amortize the handshake costs across attacks on different servers , then you get a lower value . 
 My math : Assuming outgoing packets are 1 to 1 with incoming , that gives us a limit of 6 packets per second , per path Estimated the incoming UDP payload size to be 20 bytes The outgoing UDP payload size will be 1200 bytes The amplification ratio is , which is . For incoming size of 28 bytes ( 8 byte CID ) the number comes down to . 
 OK , that helps . I did n't factor in packet headers in my calculations , but I also allow for multiple probes in response to a single non - probing packet . What I 'm concerned about then is considering the cost of the handshake . To complete the handshake , you need to send one 1200 byte packet and one packet of about 78 bytes . For an attack on a single host , this changes the dynamic considerably : you send to get , assuming that you send three probes on new paths . That 's lower than our 3x target even if the connection ID is zero length ( 2.66 ) . Even if you amortize that setup cost across multiple targets , the amplification factor is n't as bad as I first thought . If a server probes up to 10 paths ( which seems high ) , then you get which for a CID of 8 bytes and 10 paths is 19.8 . That 's much worse , but not so bad as it is spread over multiple paths . We might limit the number of concurrent path validations , but this is not really going to change anything if they are just strung out . Only the total amount matters if the attacker is even slightly patient . I think that there might be some clarifications we can add : more clearly to the requirement to limit the sending rate on unvalidated paths after migration . that this rate limit applies to each path and that it might be necessary to limit the number of paths that are concurrently validated in this way , either per connection or across all connections ( perhaps per destination if you are able ) . that multiple path validations in sequence can still be used to use a single connection to attack multiple targets and that it might be necessary to limit the number of total failed path validations . On this last point , the total exposure is fixed in total to the number of probes in each failed validation attempt ( e.g. , 3 ) times the number of failed validations that the endpoint permits ( e.g. , 10 ) . Using 3 and 10 gives the ~20x figure above , which is pretty bad , but not so far out of proportion that it could n't be managed . Keep in mind that the attacker needs to do all the crypto of a handshake in order to access that , plus all the protocol logic and timers over two round trips . All that to get that 20x factor . 
 Thank you for the calculations . Something around ~20x is what I have expected too . I tend to agree that having some cautionary text is sufficient . I 'd also point out that we have a sentence that states : In response to an apparent migration , endpoints MUST validate the previously active path using a PATHCHALLENGE frame . ( ) . Therefore , in addition to sending bytes to the victim , servers used for the reflection attack will be sending about 1/2 of that to the initiator of the attack . I 'm not sure how critical that is to the attacker , though . 
 This is a response to the the discussion in on the potential performance cost of applying this limit on quiescence . This roundtrip is n't the only perf issue on NAT rebinding : a server could reset the congestion controller the server infrastructure could send a GOAWAY since incoming packets are having to be redirected between servers , forcing a new connection for subsequent requests . Despite the fact that we want to have continuity across NAT rebinding , we did not design for it to be seamless in terms of performance . I do n't think we should start now . Let 's remember that NAT rebinding is the uncommon case , and typically occurs after quiescence of 30 or 60 seconds . A client app that wants to improve performance because this quiescence is a common pattern for it can always use one of many methods , including sending PINGs . I 'd strongly argue against making any recommendations . This is a question where I believe more experience is necessary to learn best practices . 
 I would also point out that we suggest that . This is n't three datagrams , but it 's now a fully padded datagram , which will allow for three packets . That 's pretty good relative to a full handshake , if an implementation chooses to do that . 
 I agree with the sentiment that NAT rebinding is an edge case and it likely to have all sorts of performance related issues , and we do n't really need to try to optimize for them . I personally think mentioning the known problems an possible solutions would be nice though . The only real problem I left is that is seems there is some confusion ( as seen from my discussion with  on the PR ) about amplification protection and its relation to port - only NAT rebinding . Is it an exception to the rule or not ? I did n't see any specific text on this one way or the other in the latest PR last I look , and I think it might be worth while to have some . 
 My reading of this text is that for a port - only change , you 're not mandated to , but a cautious implementation could certainly choose to apply the limit to that case as well . 
 One point that seems to have been lost is the addition of an error code -- see discussion . I think adding an error code for  is a good idea . 
 Let 's do that as a separate PR , which I will write up now , so that I do n't forget ... 
 I am seeing interop failures . Picoquic avoids sending full size datagrams in response to short natted packets ; it just send short challenges to both client addresses , and will perform PMTUD later . Some implementations see " unpadded challenges " as some kind of protocol violation and just ignore them , leading to connection failures . This is a difficult situation , because implementations end up having to choose between sending long challenge packets in response to NAT and risking participating in reflection  , or sending short challenge packets and risking connection failures . I think this is a case in which the behavior of clients and servers vary . When clients send PATH CHALLENGE , they are either deliberately attempting to probe a new path , or maybe verifying a NAT response from the server . In both cases , padding is appropriate . For servers , padding is appropriate in response to a padded client message , but it is mostly inappropriate in response to a short natted packet . 
 So at least my implementation requires padded PATHCHALLENGES , because Section 8.2.1 says : to at least the smallest allowed maximum datagram size of 1200 bytes . Is there an inconsistency in the spec here ? 
 The PR adds " , unless the anti - amplification limit for the path does not permit sending a datagram of this size . " 
 Given that you ca n't validate the " unless " criteria for the peer , it seems like the client is n't able to enforce this MUST . 
 What  says . " MUST ... unless " is not standard per RFC 2119 and 8174 , and that leaves implementers with fuzzy guidance , leading to interop failures . The proper text would be something like : 
 I agree with here , client MUST + server SHOULD sounds like the easiest way to resolve this issue . 
 I 'm not sure if I follow . IIUC , we do have MUSTs that are not enforceable by the peer . To give an example , a server can not close a connection when it receives a half - sized datagram containing an Initial packet . Is the argument that we have to change the existing MUST pad rule to SHOULD ? IMO " MUST unless " is better than " SHOULD unless " , because it is clear that the sender is required to behave as specified whenever the exception is not being met . SHOULD sounds like there are other cases when a sender can send a smaller sized datagrams . 
 FTR , this is now resolved , see discussion : The editorial fix is in this commit : 
 Reopening as requested by chairs . 
 Closing this now that the IESG review of draft 33 has concluded . 
 Based on the argument in this email : I would propose the following text . I 'm not sure where it should go : 1 ) " After a long idle period , clients SHOULD send at least one , and ideally at least three , full size datagrams in its first transmission in case a NAT rebinding forces the server to validate the path and MTU . " 2 ) " When migrating to a new address on a path that has not already been validated by both endpoints , a client SHOULD send at least one , and ideally at least three , full size datagrams to allow fast MTU validation and use of the entire congestion window . " If clients follow this advice , it eliminates all of the performance downsides of the amplification limit . A few minor nits , but this does a really good job walking a very fine line of not - much - change but actually making things a bit more consistent . Thanks
Mailing list commentary: I want to carefully think through the various scenarios here , two " normal " ones and two attack ones . But the summary is that the proposal to always use the amp limit is good , if we add a coupe of more recommendations for clients ( in bold below ) 1 ) Normal NAT rebinding . The connection is idle for a long period . A good server will have reset its congestion controller due to the long idle period . The client then sends a packet ( if the server does first , it 'll probably disappear ) . Whether or not that packet is small , the server is going to be limited by the amplification limit rather than congestion control . One alternative is to kill the connection after an idle period and restart with , but that 's only superior because the client has to send a bunch of bytes . The recommendation here , I think , is that clients SHOULD send one or more full - size datagrams when restarting after a long idle period , and possibly reset its PMTU assumptions . [ I ca n't remember what says about idle periods ] If the client does this , the server will be able to validate address and MTU in one RTT . Otherwise , it 's going to have to take two . But the recommendation is sufficient to mitigate the impact of the 3x limit in NAT rebinding cases . 2 ) Spoofed NAT rebinding . An attacker rewrites source addresses on someone else 's packets , or opens a valid connection and then switches the source address to the victim . The amplification limit will prevent anything bad from happening here , then PATHCHALLENGE will fail and we 're done . 3 ) . The client suddenly changes the CIDs and source IP . ( a ) If the path is pre - validated , there is no issue . PATHCHALLENGE and PATHRESPONSE SHOULD have been padded to handle MTU and address validation simultaneously . ( b ) If the path is not - prevalidated , the client SHOULD pad PATHCHALLENGE . This will be more restrictive than init - cwnd , unless the client sends 3 datagrams or so , padded pings if necessary . 4 ) Spoofed Migration : the attacker opens a connection , then sends packets with new CIDs and the victim 's IP . It is impossible for this to be pre - validated . Because the attacker has to send 1 byte for every 3 the victim gets , this is safe . I 'll propose some text in review .
Paragraph (version B):
This document defines the core of the QUIC transport protocol.  QUIC
provides applications with flow-controlled streams for structured
communication, low-latency connection establishment, and network path
migration.  QUIC includes security measures that ensure
confidentiality, integrity, and availability in a range of deployment
circumstances.  Accompanying documents describe the integration of
TLS for key negotiation, loss detection, and an exemplary congestion
control algorithm.
Paragraph (version B):
QUIC is a secure general-purpose transport protocol.  This document
defines version 1 of QUIC, which conforms to the version-independent
properties of QUIC defined in QUIC-INVARIANTS.
Paragraph (version B):
QUIC is a connection-oriented protocol that creates a stateful
interaction between a client and server.
Paragraph (version B):
QUIC provides the necessary feedback to implement reliable delivery
and congestion control.  An algorithm for detecting and recovering
from loss of data is described in QUIC-RECOVERY.  QUIC depends on
congestion control to avoid network congestion.  An exemplary
congestion control algorithm is also described in QUIC-RECOVERY.
Paragraph (version B):
QUIC connections are not strictly bound to a single network path.
Connection migration uses connection identifiers to allow connections
to transfer to a new network path.  Only clients are able to migrate
in this version of QUIC.  This design also allows connections to
continue after changes in network topology or address mappings, such
as might be caused by NAT rebinding.
Paragraph (version B):
A complete processable unit of QUIC that can be encapsulated in a
UDP datagram.  One or more QUIC packets can be encapsulated in a
single UDP datagram.
Paragraph (version B):
A unit of structured protocol information.  There are multiple
frame types, each of which carries different information.  Frames
are contained in QUIC packets.
Paragraph (version B):
This document uses the terms "QUIC packets", "UDP datagrams", and "IP
packets" to refer to the units of the respective protocols.  That is,
one or more QUIC packets can be encapsulated in a UDP datagram, which
is in turn encapsulated in an IP packet.
Paragraph (version B):
When a single-bit field is referenced in prose, the position of that
field can be clarified by using the value of the byte that carries
the field with the field's value set.  For example, the value 0x80
could be used to refer to the single-bit field in the most
significant bit of the byte, such as One-bit Field in fig-ex-format.
Paragraph (version B):
An endpoint that selects a zero-length connection ID during the
handshake cannot issue a new connection ID.  A zero-length
Destination Connection ID field is used in all packets sent toward
such an endpoint over any network path.
Paragraph (version A):
The primary defense against amplification attack is verifying that an
endpoint is able to receive packets at the transport address that it
claims.  Address validation is performed both during connection
establishment (see validate-handshake) and during connection
migration (see migrate-validate).
Paragraph (version A):
Connection establishment implicitly provides address validation for
both endpoints.  In particular, receipt of a packet protected with
Handshake keys confirms that the client received the Initial packet
from the server.  Once the server has successfully processed a
Handshake packet from the client, it can consider the client address
to have been validated.
Paragraph (version B):
The primary defense against amplification attacks is verifying that a
peer is able to receive packets at the transport address that it
claims.  Therefore, after receiving packets from an address that is
not yet validated, an endpoint MUST limit the amount of data it sends
to the unvalidated address to three times the amount of data received
from that address.  This limit on the size of responses is known as
the anti-amplification limit.
Paragraph (version B):
Address validation is performed both during connection establishment
(see validate-handshake) and during connection migration (see
migrate-validate).
Paragraph (version B):
Connection establishment implicitly provides address validation for
both endpoints.  In particular, receipt of a packet protected with
Handshake keys confirms that the peer successfully processed an
Initial packet.  Once an endpoint has successfully processed a
Handshake packet from the peer, it can consider the peer address to
have been validated.
Paragraph (version B):
For the client, the value of the Destination Connection ID field in
its first Initial packet allows it to validate the server address as
a part of successfully processing any packet.  Initial packets from
the server are protected with keys that are derived from this value
(see Section 5.2 of QUIC-TLS).  Alternatively, the value is echoed by
the server in Version Negotiation packets (version-negotiation) or
included in the Integrity Tag in Retry packets (Section 5.8 of QUIC-
TLS).
Paragraph (version A):
Tokens sent in NEW_TOKEN frames MUST include information that allows
the server to verify that the client IP address has not changed from
when the token was issued.  Servers can use tokens from NEW_TOKEN in
deciding not to send a Retry packet, even if the client address has
changed.  If the client IP address has changed, the server MUST
adhere to the anti-amplification limits found in validate-handshake.
Note that in the presence of NAT, this requirement might be
insufficient to protect other hosts that share the NAT from
amplification attack.
Paragraph (version B):
Tokens sent in NEW_TOKEN frames MUST include information that allows
the server to verify that the client IP address has not changed from
when the token was issued.  Servers can use tokens from NEW_TOKEN in
deciding not to send a Retry packet, even if the client address has
changed.  If the client IP address has changed, the server MUST
adhere to the anti-amplification limit; see address-validation.  Note
that in the presence of NAT, this requirement might be insufficient
to protect other hosts that share the NAT from amplification attack.
Paragraph (version A):
An endpoint MUST expand datagrams that contain a PATH_CHALLENGE frame
to at least the smallest allowed maximum datagram size of 1200 bytes.
Sending UDP datagrams of this size ensures that the network path from
the endpoint to the peer can be used for QUIC; see datagram-size.
Paragraph (version B):
An endpoint MUST expand datagrams that contain a PATH_CHALLENGE frame
to at least the smallest allowed maximum datagram size of 1200 bytes,
unless the anti-amplification limit for the path does not permit
sending a datagram of this size.  Sending UDP datagrams of this size
ensures that the network path from the endpoint to the peer can be
used for QUIC; see datagram-size.
Paragraph (version B):
When an endpoint is unable to expand the datagram size to 1200 bytes
due to the anti-amplification limit, the path MTU will not be
validated.  To ensure that the path MTU is large enough, the endpoint
MUST perform a second path validation by sending a PATH_CHALLENGE
frame in a datagram of at least 1200 bytes.  This additional
validation can be performed after a PATH_RESPONSE is successfully
received or when enough bytes have been received on the path that
sending the larger datagram will not result in exceeding the anti-
amplification limit.
Paragraph (version B):
Unlike other cases where datagrams are expanded, endpoints MUST NOT
discard datagrams that appear to be too small when they contain
PATH_CHALLENGE or PATH_RESPONSE.
Paragraph (version A):
An endpoint MUST expand datagrams that contain a PATH_RESPONSE frame
to at least the smallest allowed maximum datagram size of 1200 bytes.
This verifies that the path is able to carry datagrams of this size
in both directions.
Paragraph (version B):
An endpoint MUST expand datagrams that contain a PATH_RESPONSE frame
to at least the smallest allowed maximum datagram size of 1200 bytes.
This verifies that the path is able to carry datagrams of this size
in both directions.  However, an endpoint MUST NOT expand the
datagram containing the PATH_RESPONSE if the resulting data exceeds
the anti-amplification limit.  This is expected to only occur if the
received PATH_CHALLENGE was not sent in an expanded datagram.
Paragraph (version B):
Endpoints SHOULD abandon path validation based on a timer.  When
setting this timer, implementations are cautioned that the new path
could have a longer round-trip time than the original.  A value of
three times the larger of the current Probe Timeout (PTO) or the PTO
for the new path (that is, using kInitialRtt as defined in QUIC-
RECOVERY) is RECOMMENDED.
Paragraph (version A):
When an endpoint abandons path validation, it determines that the
path is unusable.  This does not necessarily imply a failure of the
connection - endpoints can continue sending packets over other paths
as appropriate.  If no paths are available, an endpoint can wait for
a new path to become available or close the connection.
Paragraph (version B):
When an endpoint abandons path validation, it determines that the
path is unusable.  This does not necessarily imply a failure of the
connection - endpoints can continue sending packets over other paths
as appropriate.  If no paths are available, an endpoint can wait for
a new path to become available or close the connection.  An endpoint
that has no valid network path to its peer MAY signal this using the
NO_VIABLE_PATH connection error, noting that this is only possible if
the network path exists but does not support the required MTU
(datagram-size).
Paragraph (version A):
As described in migration-response, an endpoint is required to
validate a peer's new address to confirm the peer's possession of the
new address.  Until a peer's address is deemed valid, an endpoint
MUST limit the rate at which it sends data to this address.  The
endpoint MUST NOT send more than a minimum congestion window's worth
of data per estimated round-trip time (kMinimumWindow, as defined in
QUIC-RECOVERY).  In the absence of this limit, an endpoint risks
being used for a denial of service attack against an unsuspecting
victim.  Note that since the endpoint will not have any round-trip
time measurements to this address, the estimate SHOULD be the default
initial value; see QUIC-RECOVERY.
Paragraph (version B):
As described in migration-response, an endpoint is required to
validate a peer's new address to confirm the peer's possession of the
new address.  Until a peer's address is deemed valid, an endpoint
limits the amount of data it sends to that address; see address-
validation.  In the absence of this limit, an endpoint risks being
used for a denial of service attack against an unsuspecting victim.
Paragraph (version A):
Servers SHOULD initiate path validation to the client's new address
upon receiving a probe packet from a different address.  Servers MUST
NOT send more than a minimum congestion window's worth of non-probing
packets to the new address before path validation is complete.
Paragraph (version B):
Servers SHOULD initiate path validation to the client's new address
upon receiving a probe packet from a different address; see address-
validation.
Paragraph (version B):
To support this process, an endpoint issues a stateless reset token,
which is a 16-byte value that is hard to guess.  If the peer
subsequently receives a stateless reset, which is a UDP datagram that
ends in that stateless reset token, the peer will immediately end the
connection.
Paragraph (version B):
A stateless reset token is specific to a connection ID.  An endpoint
issues a stateless reset token by including the value in the
Stateless Reset Token field of a NEW_CONNECTION_ID frame.  Servers
can also issue a stateless_reset_token transport parameter during the
handshake that applies to the connection ID that it selected during
the handshake.  These exchanges are protected by encryption, so only
client and server know their value.  Note that clients cannot use the
stateless_reset_token transport parameter because their transport
parameters do not have confidentiality protection.
Paragraph (version B):
Tokens are invalidated when their associated connection ID is retired
via a RETIRE_CONNECTION_ID frame (frame-retire-connection-id).
Paragraph (version B):
Initial packets use an AEAD, the keys for which are derived using a
value that is visible on the wire.  Initial packets therefore do not
have effective confidentiality protection.  Initial protection exists
to ensure that the sender of the packet is on the network path.  Any
entity that receives an Initial packet from a client can recover the
keys that will allow them to both read the contents of the packet and
generate Initial packets that will be successfully authenticated at
either endpoint.  The AEAD also protects Initial packets against
accidental modification.
Paragraph (version B):
A receiver MUST discard a newly unprotected packet unless it is
certain that it has not processed another packet with the same packet
number from the same packet number space.  Duplicate suppression MUST
happen after removing packet protection for the reasons described in
Section 9.5 of QUIC-TLS.
Paragraph (version B):
frame-types lists and summarizes information about each frame type
that is defined in this specification.  A description of this summary
is included after the table.
Paragraph (version B):
The format and semantics of each frame type are explained in more
detail in frame-formats.  The remainder of this section provides a
summary of important and general information.
Paragraph (version B):
The Frame Type in ACK, STREAM, MAX_STREAMS, STREAMS_BLOCKED, and
CONNECTION_CLOSE frames is used to carry other frame-specific flags.
For all other frames, the Frame Type field simply identifies the
frame.
Paragraph (version B):
All frames are idempotent in this version of QUIC.  That is, a valid
frame does not cause undesirable side effects or errors when received
more than once.
Paragraph (version B):
The maximum datagram size is defined as the largest size of UDP
payload that can be sent across a network path using a single UDP
datagram.  QUIC MUST NOT be used if the network path cannot support a
maximum datagram size of at least 1200 bytes.
Paragraph (version B):
QUIC sometimes requires datagrams to be no smaller than a certain
size; see validate-handshake as an example.  However, the size of a
datagram is not authenticated.  That is, if an endpoint receives a
datagram of a certain size, it cannot know that the sender sent the
datagram at the same size.  Therefore, an endpoint MUST NOT close a
connection when it receives a datagram that does not meet size
constraints; the endpoint MAY however discard such datagrams.
Paragraph (version A):
For example, the eight byte sequence c2 19 7c 5e ff 14 e8 8c (in
hexadecimal) decodes to the decimal value 151288809941952652; the
four byte sequence 9d 7f 3e 7d decodes to 494878333; the two byte
sequence 7b bd decodes to 15293; and the single byte 25 decodes to 37
(as does the two byte sequence 40 25).
Paragraph (version B):
Examples and a sample decoding algorithm are shown in sample-varint.
Paragraph (version A):
As a result, the size of the packet number encoding is at least one
bit more than the base-2 logarithm of the number of contiguous
unacknowledged packet numbers, including the new packet.
Paragraph (version A):
For example, if an endpoint has received an acknowledgment for packet
0xabe8bc, sending a packet with a number of 0xac5c02 requires a
packet number encoding with 16 bits or more; whereas the 24-bit
packet number encoding is needed to send a packet with a number of
0xace8fe.
Paragraph (version B):
As a result, the size of the packet number encoding is at least one
bit more than the base-2 logarithm of the number of contiguous
unacknowledged packet numbers, including the new packet.  Pseudocode
and examples for packet number encoding can be found in sample-
packet-number-encoding.
Paragraph (version A):
Once header protection is removed, the packet number is decoded by
finding the packet number value that is closest to the next expected
packet.  The next expected packet is the highest received packet
number plus one.  For example, if the highest successfully
authenticated packet had a packet number of 0xa82f30ea, then a packet
containing a 16-bit value of 0x9b32 will be decoded as 0xa82f9b32.
Example pseudo-code for packet number decoding can be found in
sample-packet-number-decoding.
Paragraph (version B):
Once header protection is removed, the packet number is decoded by
finding the packet number value that is closest to the next expected
packet.  The next expected packet is the highest received packet
number plus one.  Pseudocode and an example for packet number
decoding can be found in sample-packet-number-decoding.
Paragraph (version B):
Two bits (those with a mask of 0x0c) of byte 0 are reserved across
multiple packet types.  These bits are protected using header
protection; see Section 5.4 of QUIC-TLS.  The value included prior
to protection MUST be set to 0.  An endpoint MUST treat receipt of
a packet that has a non-zero value for these bits after removing
both packet and header protection as a connection error of type
PROTOCOL_VIOLATION.  Discarding such a packet after only removing
header protection can expose the endpoint to attacks; see
Section 9.5 of QUIC-TLS.
Paragraph (version B):
The next two bits (those with a mask of 0x18) of byte 0 are
reserved.  These bits are protected using header protection; see
Section 5.4 of QUIC-TLS.  The value included prior to protection
MUST be set to 0.  An endpoint MUST treat receipt of a packet that
has a non-zero value for these bits, after removing both packet
and header protection, as a connection error of type
PROTOCOL_VIOLATION.  Discarding such a packet after only removing
header protection can expose the endpoint to attacks; see
Section 9.5 of QUIC-TLS.
Paragraph (version B):
The Transport Parameter Length field contains the length of the
Transport Parameter Value field in bytes.
Paragraph (version B):
The goal of QUIC is to provide a secure transport connection.
security-properties provides an overview of those properties;
subsequent sections discuss constraints and caveats regarding these
properties, including descriptions of known attacks and
countermeasures.
Paragraph (version B):
Prior to address validation, endpoints are limited in what they are
able to send.  Endpoints cannot send data toward an unvalidated
address in excess of three times the data received from that address.
Paragraph (version B):
The anti-amplification limit only applies when an endpoint
responds to packets received from an unvalidated address.  The
anti-amplification limit does not apply to clients when
establishing a new connection or when initiating connection
migration.
Paragraph (version B):
The length of QUIC packets can reveal information about the length of
the content of those packets.  The PADDING frame is provided so that
endpoints have some ability to obscure the length of packet content;
see frame-padding.
Paragraph (version B):
Note however that defeating traffic analysis is challenging and the
subject of active research.  Length is not the only way that
information might leak.  Endpoints might also reveal sensitive
information through other side channels, such as the timing of
packets.