Skip to content
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

Full rewrite #3

Merged
merged 4 commits into from
Jun 27, 2018
Merged

Full rewrite #3

merged 4 commits into from
Jun 27, 2018

Conversation

janaiyengar
Copy link

Several iterations later, I think I've rewritten the entire thing. PTAL.

Copy link

@martinthomson martinthomson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like these changes. They tighten things up a lot. I have a few small suggestions throughout. The only thing that gives me pause is the lost ACK problem I describe in more detail. I would be OK with taking that on in a follow-up though.

to experiment with other response functions.
codepoint in the IP header as a signal of congestion. This document specifies an
endpoint's response when its peer receives packets with the Congestion
Experienced codepoint. As discussed in {!RFC8311}, endpoints are permitted to

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two braces {{!RFC8311}}.

// Start a new recovery epoch if the largest acked packet
// is larger than the end of the previous recovery epoch.
if (!InRecovery(ack.largest_acked_packet)):
NewCongestionEvent()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would usually recommend moving the InRecovery() call to NewCongestionEvent() here. Why did you de-factor this?

@@ -1112,7 +1109,8 @@ are detected lost.
largest_lost_packet = lost_packets.last()
// Start a new recovery epoch if the lost packet is larger
// than the end of the previous recovery epoch.
CongestionEvent(largest_lost_packet.packet_number)
if (!InRecovery(packet_number)):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that largest_lost_packet.packet_number is still correct.


### Continuous Verification of ECN {#ecn-continuous-verification}
QUIC endpoints SHOULD use Explicit Congestion Notification (ECN) {{!RFC3168}} to

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/SHOULD// - let's not recommend this, let's assume that it is done. Better that way I think.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with Martin here.

ECT marked packets then continuous verification is applied. This is to detect
any cases when ECN field is bleached, that is, zeroed out by a network node,
likely as the result of a routing changes since the ECN capability check.
To use ECN, QUIC endpoints must first determine whether a path and peer support

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/must//


If a packet sent with an ECT codepoint is newly acknowledged by the peer in an
ACK frame, the endpoint stops setting ECT codepoints in subsequent packets, with
the expectation that either the network or the peer no longer supports ECN.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would merge this with the previous paragraph.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to keep this separate, since this action is independent of why an ACK frame is received (instead of an ACK_ECN frame). The para above is one reason that might happen.

ACK frame, the endpoint stops setting ECT codepoints in subsequent packets, with
the expectation that either the network or the peer no longer supports ECN.

A network device may bleach the ECN codepoint in the IP header by setting it to

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"bleach"

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rephrased

ACK_ECN frame.

* The increase in ECT(0) and ECT(1) counters MUST be no greater than the number
of packets newly acknowledged that were sent with the corresponding codepoint.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little concerned that this makes things fragile (i.e., ECN will be disabled a little too aggressively), but I think that it's still correct. I think that with a good path, there is a failure mode that I think we need to address: lost ACKs. This is something in Magnus' original PR, and I think that it's worth being a little careful.

Say a marked packet gets through and gets acknowledged, but the acknowledgment is lost. And the recipient abandons the ACK. The counters will increase, but the number of newly acknowledged packets will be lower than the increase to the counters. That suggests a tweak, though it complicates things a little:

If the acknowledgments cover a range of packet numbers that extend past (or adjacent to) the largest acknowledged packet number that was previously acknowledged, then the counters must match precisely. If the acknowledgments do not extend to the largest previously acknowledged packet number, then the numbers MAY increase by the number of unacknowledged packets between the previously largest acknowledged and the newly lowest acknowledged.

That is, if an endpoint has seen an ACK_ECN for packet 10, then receives a new ACK_ECN for packet 20-30, it needs to allow for an increase in the counters for packets 11 through 19 (inclusive). It can then reset both the largest acknowledged and the values it tracks for each counter.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fully agree with Martin here. I think the sender needs to accept counter increases larger than newly acknowledged if there are gaps in the ACKs.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I deliberately left this out; my plan is to file an issue and do this separately. In most cases, we expect the receiver to repeat ack information adequately for it to not matter. That said, it does need to be covered.

An ACK_ECN frame contains all the elements of the ACK frame ({{frame-ack}}) with
the addition of three counts corresponding to the total number of packets
received with those codepoints -- ECT(0), ECT(1), and CE -- since the beginning
of the connection.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should retain the enumeration of new fields, though it could be more terse.

ECT(0) Count:
: A variable-length integer representing the number of ECT(0) marked packets received.

Also, we can't assume that the diagram is accessible, so it probably pays to say where the new field are inserted.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point on accessibility.

retransmit packets with ECN bits set and manipulate the senders congestion
avoidance state. If duplicate packets are discarded, the off-path attacker will
need to race the original packet to be successful in this attack.
An on-path attacker may manipulate the value of ECN codepoints in the IP header

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/may/could/ - may implies that this is permissible :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not? you mean... stuff happens even when the IETF does not permit it? :-P

Copy link
Owner

@gloinul gloinul left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A number of things needs edits before this can replace what is currently in the pull request.


### Continuous Verification of ECN {#ecn-continuous-verification}
QUIC endpoints SHOULD use Explicit Congestion Notification (ECN) {{!RFC3168}} to
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with Martin here.

the ECN Capable Transport (ECT) codepoints -- ECT(0) or ECT(1) -- in the IP
header {{!RFC8311}} of all outgoing packets.

If an ECT codepoint set in the IP header is not bleached or otherwise corrupted
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with Bleach being jargon, and what we might need to care about is also ECT(0) <-> ECT(1) changes by the network which isn't covered by Martin's suggestion. Maybe "... the path does not remove ECN markings or changes the applied ECT code point."

codepoints when necessary (see {{processing-and-ack}}) with an ACK_ECN frame
carrying the current state of its ECN counters (see {{frame-ack-ecn}}).

If an endpoint receives a packet without an ECT or CE codepoint, it responds per
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, my proposal using three counters so far is using ACK_ECN frame as long as there are any ECN marked packets in the range being acknowledged. This formulation can be interpreted such that ACK frames shall be used to acknowledge all packets that are unmarked. This is a possible change and would be step in the direction of the two counter proposal as well as making it clearer which packets wasn't marked allowing better sender verification if it like to check things by not marking all packets. Is this your intention here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is a change from your proposal, but it is necessary to be able to detect all failure modes correctly.

There's a change earlier in the text that basically says that an endpoint marks all packets if it wants to do ECN. The idea here is that if an ACK is received at all, the endpoint can simply turn off ECN, since that only happens if the network or the peer don't support ECN.

ACK_ECN frame.

* The increase in ECT(0) and ECT(1) counters MUST be no greater than the number
of packets newly acknowledged that were sent with the corresponding codepoint.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fully agree with Martin here. I think the sender needs to accept counter increases larger than newly acknowledged if there are gaps in the ACKs.

{{migration-cc}}.

The new path might not have the same ECN capability. Therefore, the endpoint
verifies ECN capability as described in {{ecn-connection-migration}}.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reference to a section you have removed below ecn-connection-migration

@janaiyengar
Copy link
Author

@gloinul : if this is basically good, can you merge so we can get this into the draft?

@martinthomson
Copy link

I merged this directly in the draft. There is the one issues that @janaiyengar opened, but aside from that this is good.

@gloinul gloinul merged commit b931633 into gloinul:ecn Jun 27, 2018
gloinul pushed a commit that referenced this pull request Sep 4, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants