New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduces PATH_CHALLENGE and PATH_RESPONSE frames #1086
Changes from 1 commit
d14922c
9cc0cab
b96bd5d
5c3c0d6
4c470d8
5ce6149
fd34af6
d7a4c77
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1567,16 +1567,15 @@ endpoint validates a remote address by sending a PATH_CHALLENGE frame containing | |
a payload that is hard to guess. This frame MUST be sent in a packet that is | ||
sent to the new address. Once a PATH_RESPONSE frame containing the same payload | ||
is received, the address is considered to be valid. The PATH_RESPONSE frame can | ||
use any path on its return. A PATH_CHALLENGE frame containing 12 randomly | ||
generated {{?RFC4086}} octets is sufficient to ensure that it is easier to | ||
receive the packet than it is to guess the value correctly. | ||
use any path on its return. | ||
|
||
An endpoint MAY send multiple PATH_CHALLENGE frames to handle packet loss or to | ||
make additional measurements on a new network path. | ||
|
||
An endpoint MUST use fresh random data in every PATH_CHALLENGE frame so that it | ||
can associate the peer's response with the causative PATH_CHALLENGE, | ||
additionally helping the endpoint make more accurate path measurements. | ||
can associate the peer's response with the causative PATH_CHALLENGE. Using | ||
fresh values allows the endpoint to measure the path's roundtrip time more | ||
accurately. | ||
|
||
If the PATH_CHALLENGE frame is determined to be lost, a new PATH_CHALLENGE frame | ||
SHOULD be generated. This PATH_CHALLENGE frame MUST include new data that is | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rather than SHOULD here, I think that you need to talk about sending multiple to deal with the potential of loss, but limiting the total time or number of challenges and eventually giving up. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This text is the same as previous, with PING+Data. I intend to change this in the PR that addresses other migration concerns, but not here. |
||
|
@@ -2160,7 +2159,7 @@ Endpoints can use PING frames (type=0x07) to verify that their peers are still | |
alive or to check reachability to the peer. The PING frame contains no | ||
additional fields. | ||
|
||
The receiver of a PING frame simply need to acknowledge the packet containing | ||
The receiver of a PING frame simply needs to acknowledge the packet containing | ||
this frame. | ||
|
||
The PING frame can be used to keep a connection alive when an application or | ||
|
@@ -2337,61 +2336,9 @@ Application Error Code: | |
{{app-error-codes}}). | ||
|
||
|
||
## PATH_CHALLENGE Frame {#frame-path-challenge} | ||
|
||
Endpoints can use PATH_CHALLENGE frames (type=0x0e) to check reachability to the | ||
peer, to verify a new path's PMTU, and for address validation during connection | ||
establishment and connection migration. | ||
|
||
PATH_CHALLENGE frames contain a variable-length payload. | ||
|
||
~~~ | ||
0 1 2 3 | ||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| Length(8) | Data (*) ... | ||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
~~~ | ||
|
||
Length: | ||
|
||
: This 8-bit value describes the length of the Data field. | ||
|
||
Data: | ||
|
||
: This variable-length field contains arbitrary data. | ||
|
||
|
||
The sender of this frame MUST include at least one octet of data in the Data | ||
field. | ||
|
||
The recipient of this frame MUST generate a PATH_RESPONSE frame | ||
({{frame-path-response}}) containing the same Data. An endpoint that receives a | ||
PATH_CHALLENGE frame containing an empty payload MUST generate a connection | ||
error of type FRAME_ERROR, indicating the PATH_CHALLENGE frame (that is, 0x0e). | ||
|
||
A PATH_CHALLENGE frame MUST NOT elicit acknowledgements; the corresponding | ||
PATH_RESPONSE serves to indicate receipt of the PATH_CHALLENGE. | ||
|
||
|
||
## PATH_RESPONSE Frame {#frame-path-response} | ||
|
||
The PATH_RESPONSE frame (type=0x0f) is sent in response to a PATH_CHALLENGE | ||
frame. Its format is identical to the PATH_CHALLENGE frame | ||
({{frame-path-challenge}}). | ||
|
||
An endpoint that receives a PATH_RESPONSE frame containing an empty payload MUST | ||
generate a connection error of type FRAME_ERROR, indicating the PATH_RESPONSE | ||
frame (that is, 0x0e). If the content of a PATH_RESPONSE frame does not match | ||
the content of a PATH_CHALLENGE frame previously sent by the endpoint, the | ||
endpoint MAY generate a connection error of type UNSOLICITED_PATH_RESPONSE. | ||
|
||
A PATH_RESPONSE frame MUST NOT elicit an acknowledgement. | ||
|
||
|
||
## ACK Frame {#frame-ack} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor: This is now type There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not minor -- you can create chaos doing this. Ask me how I know. 😉 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yup, this would not be happy. fixed. |
||
|
||
Receivers send ACK frames (type=0xe) to inform senders which packets they have | ||
Receivers send ACK frames (type=0x0d) to inform senders which packets they have | ||
received and processed. A sent packet that has never been acknowledged is | ||
missing. The ACK frame contains any number of ACK blocks. ACK blocks are | ||
ranges of acknowledged packets. | ||
|
@@ -2617,6 +2564,52 @@ by a client in protected packets, because it is certain that the server is able | |
to decipher the packet. | ||
|
||
|
||
## PATH_CHALLENGE Frame {#frame-path-challenge} | ||
|
||
Endpoints can use PATH_CHALLENGE frames (type=0x0e) to check reachability to the | ||
peer and for address validation during connection establishment and connection | ||
migration. | ||
|
||
PATH_CHALLENGE frames contain an 8-byte payload. | ||
|
||
~~~ | ||
0 1 2 3 | ||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| | | ||
+ Data (8) + | ||
| | | ||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
|
||
~~~ | ||
|
||
Data: | ||
|
||
: This 8-byte field contains arbitrary data. | ||
|
||
A PATH_CHALLENGE frame containing at least 8 randomly generated {{?RFC4086}} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that we're making this too hard. Can we just say hard to guess? How they are generated can be left to the challenger. (If TCP is our benchmark, then 32 bits of entropy is probably enough.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SGTM. I kept futzing around with saying the right thing, and it's probably adequate to say "hard to guess". Done. |
||
octets is sufficient to ensure that it is easier to receive the packet than it | ||
is to guess the value correctly. | ||
|
||
The recipient of this frame MUST generate a PATH_RESPONSE frame | ||
({{frame-path-response}}) containing the same Data. An endpoint that receives a | ||
PATH_CHALLENGE frame containing an empty payload MUST generate a connection | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's no length, so I don't believe you can have an empty PATH_CHALLENGE frame There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. Removed the text, since it seems redundant now. |
||
error of type FRAME_ERROR, indicating the PATH_CHALLENGE frame (that is, 0x0e). | ||
|
||
|
||
## PATH_RESPONSE Frame {#frame-path-response} | ||
|
||
The PATH_RESPONSE frame (type=0x0f) is sent in response to a PATH_CHALLENGE | ||
frame. Its format is identical to the PATH_CHALLENGE frame | ||
({{frame-path-challenge}}). | ||
|
||
An endpoint that receives a PATH_RESPONSE frame containing an empty payload MUST | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment: It can no longer be empty There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
generate a connection error of type FRAME_ERROR, indicating the PATH_RESPONSE | ||
frame (that is, 0x0f). If the content of a PATH_RESPONSE frame does not match | ||
the content of a PATH_CHALLENGE frame previously sent by the endpoint, the | ||
endpoint MAY generate a connection error of type UNSOLICITED_PATH_RESPONSE. | ||
|
||
|
||
## STREAM Frames {#frame-stream} | ||
|
||
STREAM frames implicitly create a stream and carry stream data. The STREAM | ||
|
@@ -2716,10 +2709,19 @@ implementation decision, and an implementation should be careful to delay | |
conservatively, since any delay is likely to increase application-visible | ||
latency. | ||
|
||
Regular QUIC packets are "containers" of frames; a packet is never retransmitted | ||
whole. How an endpoint handles the loss of the frame depends on the type of the | ||
frame. Some frames are simply retransmitted, some have their contents moved to | ||
new frames, and others are never retransmitted. | ||
Regular QUIC packets are "containers" of frames. When an endpoint receives an | ||
ACK frame for one or more transmitted packets, all frames in the acknowledged | ||
packets are considered to have been delivered to the peer, with one exception. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about "received and processed by" instead of "delivered to", since processing is as important as receipt There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
A PATH_CHALLENGE frame (see {{path-challenge}}) is used to validate a peer's | ||
ownership of its address. An ACK frame received for a PATH_CHALLENGE frame is | ||
not adequate to indicate that the PATH_CHALLENGE was in fact received. A | ||
PATH_CHALLENGE is considered acknowledged only when the corresponding | ||
PATH_RESPONSE (see {{path-response}}) is received for it. | ||
|
||
A packet is never retransmitted whole. How an endpoint handles the loss of a | ||
frame depends on the type of the frame. Some frames are simply retransmitted, | ||
some have their contents moved to new frames, and others are never | ||
retransmitted. | ||
|
||
When a packet is detected as lost, the sender re-sends any frames as necessary: | ||
|
||
|
@@ -2749,7 +2751,7 @@ When a packet is detected as lost, the sender re-sends any frames as necessary: | |
retransmitted. | ||
|
||
* PATH_CHALLENGE frames MUST NOT be retransmitted, but a new PATH_CHALLENGE | ||
frame MAY be sent with new random data. PATH_RESPONSE frames MUST NOT be | ||
frame MAY be sent with new data. PATH_RESPONSE frames MUST NOT be | ||
retransmitted. | ||
|
||
* All other frames MUST be retransmitted. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about "The new address is not validated until a PATH_RESPONSE frame containing the same payload is received, even if the packet containing the PATH_RESPONSE frame is acknowledged." (and then remove the text below I think is a bit confusing)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added. Which text is weird? The text about measuring time taken? It's caused me enough trouble so I'll remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't find my comment, but I thought it was weird to take an RTT sample of one path in one direction and a different path in another, which is what happens if PATH_RESPONSE comes back on a different path from the one PATH_CHALLENGE is sent on.