-
Notifications
You must be signed in to change notification settings - Fork 205
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
Add handshake retransmissions #266
Conversation
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 think the logic is fine, though there are some fairly significant editorial comments.
I don't believe this fully addresses #169, although from Tokyo I gather that some of the things I was worried about are actually application-layer actions.
draft-ietf-quic-recovery.md
Outdated
@@ -414,6 +445,15 @@ acknowledged. DetectLostPackets is called every time there is a new largest | |||
packet or if the loss detection alarm fires the previous largest acked packet is | |||
supplied. | |||
|
|||
### Handshake Packets | |||
|
|||
The receiver MUST not trust an unencryped ack for encrypted packets. The receiver |
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.
what does it mean to "trust" an ack? Perhaps " the receiver MUST ignore any acknowledgment of an encrypted packet that occurs in an ACK frame in an unencrypted packet"?
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.
@martinduke is right to ask, note that not just the acknowledgment, but the entire packet is now suspect. As we discussed elsewhere, I think that the entire packet needs to go away if it contains suspicious content.
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.
SG, will ignore the entire packet.
draft-ietf-quic-recovery.md
Outdated
initial RTT value. If no previous RTT is available, the initial RTT defaults | ||
to 200ms. Once an RTT measurement is taken, it MUST replace initial_rtt. | ||
|
||
The client hello is retransmitted via a timer, similar to a tail loss probe, but |
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.
Some issues with the client and server paragraphs:
- I think all the language about tail loss probe and delayed ack confuses it.
- I'm afraid "client hello" is handshake specific
- Separating out client and server behavior is also unnecessary, as the psuedocode is the same
- This doesn't totally reflect the pseudo code.
So how about striking these two paragraphs and replacing with the following:
"Endpoints MUST retransmit handshake packets if not acknowledged(1) within a time limit. This time limit will be the largest of the rtt value and MinTLPTimeout. For each previous handshake timeout on this connection, the timeout doubles."
"Endpoints MUST(?) also retransmit handshake packets if they receive a packet from earlier in the handshake, indicating loss of the local packet."
(1) I don't remember, must we ack the client hello, or is the server hello sufficient?
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.
An ACK for the ClientHello isn't needed, but it does contain some useful information (if you don't care about provenance, that is).
@martinduke, your use of "timeout" in that proposed text is problematic I think. It could refer to the handshake timing out, but I think that you simply intended to retransmit on a doubling interval (i.e., 200ms, 400ms, 600ms, etc...).
I wonder if some amount of randomization on that retransmission is necessary to avoid synchronizing retransmissions across a large cohort of clients that are simultaneously disconnected, or whether variations in RTT will be enough to deal with that.
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.
@martinthomson Yeah, maybe "For each previous handshake restransmission on this connection, the time limit doubles".
The way I wrote this actually implies that the timeout doubling doesn't actually reset, i.e. chlo times out twice, causing the timeout to double. Then the Finished is lost, and remains at the doubled length. I'm not sure if I meant to do that, but be aware of 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'll remove the TLP/delayed ack wording. It was there for motivation, but seems to be confusing more than helping.
- Changed client hello to initial flight
- Client vs server does matter in the case of stateless rejects, but I'll word that in as a special case where the connection 'terminates immediately' once the reject is sent.
I don't believe any of the TCP specs worry about randomization of handshake timers, so I don't think it's a large issue in practice.
draft-ietf-quic-recovery.md
Outdated
receipt of another client hello. | ||
|
||
Version negotiation packets are always stateless, and MUST be sent once per | ||
client hello, and may be sent in response to 0RTT packets. |
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.
...per handshake packet that uses an unsupported QUIC version,...
s/may/MAY
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.
Thanks done.
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.
You really need to stop using the github editor for doing this stuff. It shows.
draft-ietf-quic-recovery.md
Outdated
@@ -213,14 +213,17 @@ or negotiated in order to better suit a variety of environments. | |||
a packet lost. In fraction of an RTT. | |||
|
|||
* kMinTLPTimeout: 10ms | |||
Minimum time in the future a tail loss probe alarm may be set for. | |||
Minimum time in the future a tail loss probe alarm may be set for. |
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.
Editorial: this might look OK in markdown, but it turns into a real mess in the text version. I think that you want something like the following:
kMinTLPTimeout (default 10ms):
: Minimum time in the future [...]
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 tweaked it to say default as you said, but the extra : looked odd in markdown and text, so I didn't add it.
Is there an example formatting you were trying to achieve I should copy?
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.
The extra ':' is correct -- it's Markdown formatting for a definition list.
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.
Note that the '*' at the start of the definition title line prevents kramdown from detecting it as a definition list. You will note its absence in my example.
You also need to reformat the whole list consistent or, as you say, it looks odd.
draft-ietf-quic-recovery.md
Outdated
initial RTT value. If no previous RTT is available, the initial RTT defaults | ||
to 200ms. Once an RTT measurement is taken, it MUST replace initial_rtt. | ||
|
||
The client hello is retransmitted via a timer, similar to a tail loss probe, but |
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.
An ACK for the ClientHello isn't needed, but it does contain some useful information (if you don't care about provenance, that is).
@martinduke, your use of "timeout" in that proposed text is problematic I think. It could refer to the handshake timing out, but I think that you simply intended to retransmit on a doubling interval (i.e., 200ms, 400ms, 600ms, etc...).
I wonder if some amount of randomization on that retransmission is necessary to avoid synchronizing retransmissions across a large cohort of clients that are simultaneously disconnected, or whether variations in RTT will be enough to deal with that.
draft-ietf-quic-recovery.md
Outdated
initial RTT value. If no previous RTT is available, the initial RTT defaults | ||
to 200ms. Once an RTT measurement is taken, it MUST replace initial_rtt. | ||
|
||
The client hello is retransmitted via a timer, similar to a tail loss probe, but |
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.
Odd to be talking about TLP when you don't have text on TLP yet.
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.
Removed.
draft-ietf-quic-recovery.md
Outdated
@@ -414,6 +445,15 @@ acknowledged. DetectLostPackets is called every time there is a new largest | |||
packet or if the loss detection alarm fires the previous largest acked packet is | |||
supplied. | |||
|
|||
### Handshake Packets | |||
|
|||
The receiver MUST not trust an unencryped ack for encrypted packets. The receiver |
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.
s/unencryped/unencrypted
More generally, use "protected" rather than "encrypted' please. We have both confidentiality and integrity protection and both are relevant.
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.
So that'd be unprotected packets? Or is there a better term?
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.
That is right. "unprotected" isn't great, but I don't have anything better.
draft-ietf-quic-recovery.md
Outdated
@@ -414,6 +445,15 @@ acknowledged. DetectLostPackets is called every time there is a new largest | |||
packet or if the loss detection alarm fires the previous largest acked packet is | |||
supplied. | |||
|
|||
### Handshake Packets | |||
|
|||
The receiver MUST not trust an unencryped ack for encrypted packets. The receiver |
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.
@martinduke is right to ask, note that not just the acknowledgment, but the entire packet is now suspect. As we discussed elsewhere, I think that the entire packet needs to go away if it contains suspicious content.
draft-ietf-quic-recovery.md
Outdated
@@ -431,7 +471,7 @@ Pseudocode for DetectLostPackets follows: | |||
acked_packet.packet_number - reordering_threshold) | |||
lost_packets.insert(unacked_packet.packet_number); | |||
return lost_packets; | |||
~~~ | |||
~~~ |
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.
trailing space here
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.
Done
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.
Thanks, updated with one follow up comment on protected terminology.
draft-ietf-quic-recovery.md
Outdated
@@ -213,14 +213,17 @@ or negotiated in order to better suit a variety of environments. | |||
a packet lost. In fraction of an RTT. | |||
|
|||
* kMinTLPTimeout: 10ms | |||
Minimum time in the future a tail loss probe alarm may be set for. | |||
Minimum time in the future a tail loss probe alarm may be set for. |
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 tweaked it to say default as you said, but the extra : looked odd in markdown and text, so I didn't add it.
Is there an example formatting you were trying to achieve I should copy?
draft-ietf-quic-recovery.md
Outdated
initial RTT value. If no previous RTT is available, the initial RTT defaults | ||
to 200ms. Once an RTT measurement is taken, it MUST replace initial_rtt. | ||
|
||
The client hello is retransmitted via a timer, similar to a tail loss probe, but |
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'll remove the TLP/delayed ack wording. It was there for motivation, but seems to be confusing more than helping.
- Changed client hello to initial flight
- Client vs server does matter in the case of stateless rejects, but I'll word that in as a special case where the connection 'terminates immediately' once the reject is sent.
I don't believe any of the TCP specs worry about randomization of handshake timers, so I don't think it's a large issue in practice.
draft-ietf-quic-recovery.md
Outdated
initial RTT value. If no previous RTT is available, the initial RTT defaults | ||
to 200ms. Once an RTT measurement is taken, it MUST replace initial_rtt. | ||
|
||
The client hello is retransmitted via a timer, similar to a tail loss probe, but |
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.
Removed.
draft-ietf-quic-recovery.md
Outdated
receipt of another client hello. | ||
|
||
Version negotiation packets are always stateless, and MUST be sent once per | ||
client hello, and may be sent in response to 0RTT packets. |
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.
Thanks done.
draft-ietf-quic-recovery.md
Outdated
@@ -414,6 +445,15 @@ acknowledged. DetectLostPackets is called every time there is a new largest | |||
packet or if the loss detection alarm fires the previous largest acked packet is | |||
supplied. | |||
|
|||
### Handshake Packets | |||
|
|||
The receiver MUST not trust an unencryped ack for encrypted packets. The receiver |
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.
SG, will ignore the entire packet.
draft-ietf-quic-recovery.md
Outdated
@@ -414,6 +445,15 @@ acknowledged. DetectLostPackets is called every time there is a new largest | |||
packet or if the loss detection alarm fires the previous largest acked packet is | |||
supplied. | |||
|
|||
### Handshake Packets | |||
|
|||
The receiver MUST not trust an unencryped ack for encrypted packets. The receiver |
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.
So that'd be unprotected packets? Or is there a better term?
draft-ietf-quic-recovery.md
Outdated
@@ -431,7 +471,7 @@ Pseudocode for DetectLostPackets follows: | |||
acked_packet.packet_number - reordering_threshold) | |||
lost_packets.insert(unacked_packet.packet_number); | |||
return lost_packets; | |||
~~~ | |||
~~~ |
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.
Done
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.
Looks good to me, except for the one issue.
draft-ietf-quic-recovery.md
Outdated
it is expected client hellos will be acked immediately or a handshake packet will | ||
be sent immediately, so delayed acks do not need to be compensated for. As such, | ||
it is always retransmitted at 2x the initial_rtt or smoothed_rtt. | ||
Endpoints MUST retransmit handshake packets if not acknowledged(1) within a |
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.
The (1) was my reference to a footnote in my comment. I think "not acknowledged" has to extend to be "not acknowledged and the next handshake message didn't arrive" but I'm not sure how to word that.
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.
Thanks, I removed it and tweaked the text about exponential backoff again. Currently in the pseudocode(and the real code), all timers have their exponential backoff reset when an ack is received. The idea being, if you're getting some packets through, based the retransmission time on RTT. If you're not getting any data through, exponentially backoff because your RTT estimate may be wrong, and to avoid overloading the network.
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.
Minor update, PTAL.
draft-ietf-quic-recovery.md
Outdated
it is expected client hellos will be acked immediately or a handshake packet will | ||
be sent immediately, so delayed acks do not need to be compensated for. As such, | ||
it is always retransmitted at 2x the initial_rtt or smoothed_rtt. | ||
Endpoints MUST retransmit handshake packets if not acknowledged(1) within a |
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.
Thanks, I removed it and tweaked the text about exponential backoff again. Currently in the pseudocode(and the real code), all timers have their exponential backoff reset when an ack is received. The idea being, if you're getting some packets through, based the retransmission time on RTT. If you're not getting any data through, exponentially backoff because your RTT estimate may be wrong, and to avoid overloading the network.
So I'm still concerned that, as written, this requires to retransmit the client hello because we got a server hello instead of an ack. Unless I've missed something, and we're requiring ACKs, which would make the protocol quite a bit cleaner. |
Add some text on handshake state transitions cancelling handshake frames.
Good point, that's a bit awkward. You're right, it'd be best if we could just rely on ack frames. I added some text on crypto state transitions, but I'm not sure I like it. For now, we could just require they be properly acked, since we can include acks in crypto packets. |
As Martin said, you need to find something better than the GitHub editor, or you'll keep having funky alignment and broken builds due to whitespace. I've recently switched to Atom, which seems to be working pretty well for me and has a pretty rich collection of plugins. You might give it a shot. |
Are there any other web editors that are better? Alternately, can we just add a presubmit that strips whitespace and wraps lines? Also, how are you seeing the trailing whitespace and long lines? |
@ianswett, when you look at the diff that you produce, it shows both. Long lines are harder to detect because github doesn't have column markers, but you can see really long lines. |
@ianswett, I don't know what you are waiting for before merging this. This is only rotting sitting here like this. If it is a review from @janaiyengar, I'd suggest that you have already provided ample opportunity. |
I've corrected the errors that were in this patch by folding a bunch of lines. Ian, you are quite inconsistent with a few things in the diagrams
That shouldn't block this PR, but it's probably worth fixing separately. |
I was waiting for Jana, but yes, at this point, I'll merge and fix all the issues which have come up since then. |
Add details about handshake retransmissions for issue #169