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

Proposal for adding ECN support to QUIC. #1372

Merged
merged 43 commits into from Jun 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
961d5d9
According to text in wiki. Some MD fixes to get right formating.
gloinul May 18, 2018
b50fe18
Modified proposed text to integrate better and take care of issues ar…
gloinul May 18, 2018
57278fe
Fixed a typo on anchor creation
gloinul May 21, 2018
44a70f8
According to text in wiki. Some MD fixes to get right formating.
gloinul May 18, 2018
afd15f2
Modified proposed text to integrate better and take care of issues ar…
gloinul May 18, 2018
da68127
Fixed a typo on anchor creation
gloinul May 21, 2018
a9755ce
Merge branch 'ecn' of https://github.com/gloinul/base-drafts into ecn
gloinul May 22, 2018
3a95c40
Clarified that ACK or ACK_ECN can be used for acknowledgment in hands…
gloinul May 22, 2018
12b1054
Added ECN intro paragraph. Various editorial improvements of ECN text.
gloinul May 22, 2018
bfe80d5
Fixed bullet list, Added parenthis around section refs.
gloinul May 22, 2018
88f76dc
Fixed indentation and formating
gloinul May 22, 2018
f14134f
Spelling fixed
gloinul May 22, 2018
71c2794
Rewrote the ECN check algorithm for connection migration to be robust.
gloinul May 24, 2018
2ff5ac9
Removed trailing spaces.
gloinul May 24, 2018
19d3b53
Fixed trailing spaces in recovery.
gloinul May 24, 2018
f71e933
Rewraped text in both recovery and transport. Added a new sub-section…
gloinul May 24, 2018
fc94546
Added textual description of ECN-CE indicating congestion events.
gloinul May 28, 2018
66505a3
Editorial fixes
martinthomson May 29, 2018
d525046
Merge pull request #1 from quicwg/ecn
gloinul May 29, 2018
28ef4c1
Editing some formulations. Rewraping more text
gloinul May 29, 2018
6dd9237
Fixed trailing spaces and remaining line length issues, I hope.
gloinul May 30, 2018
0bb5bad
Reflowing now saved
gloinul May 30, 2018
0f94847
Merge branch 'master' of https://github.com/quicwg/base-drafts into ecn
gloinul Jun 4, 2018
0e7d43b
Merge branch 'master' of https://github.com/quicwg/base-drafts into ecn
gloinul Jun 7, 2018
822aded
Changed so that additional ECN-CE marks are sent in immediate ACKs to…
gloinul Jun 7, 2018
345f593
Fixed lint issues
gloinul Jun 7, 2018
e60cc8f
Adding security consideration around ECN into transport.
gloinul Jun 8, 2018
fdf9df7
Reverting some rewrapping that are not necessary to reduce clutter.
gloinul Jun 12, 2018
ec97fd8
Addressing issues raised by Ian Sweet on 180611. Editorial improvemen…
gloinul Jun 12, 2018
bf30190
Clarifying that both cases are capability checks. Correcting a number…
gloinul Jun 12, 2018
60468a7
Fixed a too too much
gloinul Jun 12, 2018
f577c8e
Addressing Martin Thomson's comments. Several editorial changes. The …
gloinul Jun 13, 2018
2d76935
Added paragraph on dealing with persistent loss of acknowledgement of…
gloinul Jun 13, 2018
4af108c
Fixing typo in new paragraph.
gloinul Jun 13, 2018
55fa3d6
Merge branch 'master' of https://github.com/quicwg/base-drafts into ecn
gloinul Jun 18, 2018
e06a2a0
Added requirement on ECN marking suppression for packet duplicates.
gloinul Jun 18, 2018
1636ebc
Clarifying that idefinite state are not requeired in duplication dete…
gloinul Jun 19, 2018
139f1ee
Martin Thomson's editorial suggestions. Restructured pseudo code sect…
gloinul Jun 19, 2018
dbfe4d8
partial editorial fixes
janaiyengar Jun 20, 2018
73bf8cb
Merge pull request #2 from janaiyengar/ecn
gloinul Jun 20, 2018
be91e8f
Moved the ECN block in the ACK prior to the ACK blocks themselves. Re…
gloinul Jun 21, 2018
f8d3d5c
Merge branch 'ecn' of https://github.com/gloinul/base-drafts into ecn
gloinul Jun 21, 2018
cf312f9
Merged ECN counters into single ACK frame section and move them befor…
gloinul Jun 25, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
107 changes: 80 additions & 27 deletions draft-ietf-quic-recovery.md
Expand Up @@ -110,8 +110,9 @@ important to the loss detection and congestion control machinery below.
* Crypto handshake data is sent on stream 0, and uses the reliability
machinery of QUIC underneath.

* ACK frames contain acknowledgment information. ACK frames contain one or more
ranges of acknowledged packets.
* ACK and ACK_ECN frames contain acknowledgment information. ACK_ECN frames
additionally contain information about ECN codepoints seen by the peer. (The
rest of this document uses ACK frames to mean either ACK or ACK_ECN frames.)

## Relevant Differences Between QUIC and TCP

Expand Down Expand Up @@ -417,6 +418,10 @@ to accelerate loss recovery. The receiver SHOULD send an immediate ACK
when it receives a new packet which is not one greater than the
largest received packet number.

Similarly, packets marked with the ECN Congestion Experienced (CE) codepoint in
the IP header SHOULD be acknowledged immediately, to reduce the peer's response
time to congestion events.

As an optimization, a receiver MAY process multiple packets before
sending any ACK frames in response. In this case they can determine
whether an immediate or delayed acknowledgement should be generated
Expand Down Expand Up @@ -623,9 +628,9 @@ Pseudocode for OnPacketSent follows:
SetLossDetectionAlarm()
~~~

### On Ack Receipt
### On Receiving an Acknowledgment

When an ack is received, it may acknowledge 0 or more packets.
When an ACK frame is received, it may acknowledge 0 or more packets.

Pseudocode for OnAckReceived and UpdateRtt follow:

Expand All @@ -642,6 +647,9 @@ Pseudocode for OnAckReceived and UpdateRtt follow:

DetectLostPackets(ack.largest_acked_packet)
SetLossDetectionAlarm()
// Process ECN-CE counter if present.
if (ACK frame contains ECN information):
OnPacketsMarked(ack.ce_counter)


UpdateRtt(latest_rtt, ack_delay):
Expand Down Expand Up @@ -675,7 +683,7 @@ newly acked packet.

If this is the first acknowledgement following RTO, check if the smallest newly
acknowledged packet is one sent by the RTO, and if so, inform congestion control
of a verified RTO, similar to F-RTO {{?RFC5682}}
of a verified RTO, similar to F-RTO {{?RFC5682}}.

Pseudocode for OnPacketAcked follows:

Expand Down Expand Up @@ -880,13 +888,22 @@ QUIC hosts MUST NOT send packets if they would increase bytes_in_flight
the packet is a probe packet sent after the TLP or RTO alarm fires, as described
in {{tlp}} and {{rto}}.

## Explicit Congestion Notification {#congestion-ecn}

If a path has been verified to support ECN, QUIC treats a Congestion Experienced
codepoint in the IP header as a signal of congestion. This document specifies a
QUIC sender's simple response to a peer receiving packets with a Congestion
Experienced codepoint. As discussed in {!RFC8311}, QUIC endpoints are permitted
to experiment with other response functions.

## Slow Start

QUIC begins every connection in slow start and exits slow start upon
loss. QUIC re-enters slow start anytime the congestion window is less
than sshthresh, which typically only occurs after an RTO.
While in slow start, QUIC increases the congestion window by the
number of acknowledged bytes when each ack is processed.
QUIC begins every connection in slow start and exits slow start upon loss or an
increase in the ECN-CE counter. QUIC re-enters slow start anytime the congestion
window is less than sshthresh, which typically only occurs after an RTO. While
in slow start, QUIC increases the congestion window by the number of
acknowledged bytes when each ack is processed.


## Congestion Avoidance

Expand All @@ -898,18 +915,19 @@ window and sets the slow start threshold to the new congestion window.

## Recovery Period

Recovery is a period of time beginning with detection of a lost packet.
Because QUIC retransmits stream data and control frames, not packets,
it defines the end of recovery as a packet sent after the start of
recovery being acknowledged. This is slightly different from TCP's
definition of recovery ending when the lost packet that started
recovery is acknowledged.
Recovery is a period of time beginning with detection of a lost packet or an
increase in the ECN-CE counter. Because QUIC retransmits stream data and control
frames, not packets, it defines the end of recovery as a packet sent after the
start of recovery being acknowledged. This is slightly different from TCP's
definition of recovery ending when the lost packet that started recovery is
acknowledged.

During recovery, the congestion window is not increased or decreased. As such,
multiple lost packets and/or increases in the ECN-CE counter only decrease the
congestion window once as long as they're lost before exiting recovery. This
causes QUIC to decrease the congestion window multiple times if retransmisions
are lost, but limits the reduction to once per round trip.

During recovery, the congestion window is not increased or decreased.
As such, multiple lost packets only decrease the congestion window once as
long as they're lost before exiting recovery. This causes QUIC to decrease
the congestion window multiple times if retransmisions are lost, but limits
the reduction to once per round trip.

## Tail Loss Probe

Expand Down Expand Up @@ -950,6 +968,7 @@ As an example of a well-known and publicly available implementation of a flow
pacer, implementers are referred to the Fair Queue packet scheduler (fq qdisc)
in Linux (3.11 onwards).


## Pseudocode

### Constants of interest
Expand Down Expand Up @@ -977,6 +996,11 @@ kLossReductionFactor (default 0.5):
Variables required to implement the congestion control mechanisms
are described in this section.

previous_ecn_ce_ctr:
: The ACK_ECN counter for ECN-CE marks previously processed. Used to
determine when one or more packet acknowledged by the ACK_ECN frame
was marked with ECN-CE.

bytes_in_flight:
: The sum of the size in bytes of all sent packets that contain at least
one retransmittable frame, and have not been acked or declared
Expand Down Expand Up @@ -1006,6 +1030,7 @@ variables as follows:
bytes_in_flight = 0
end_of_recovery = 0
ssthresh = infinite
previous_ecn_ce_ctr = 0
~~~

### On Packet Sent
Expand All @@ -1024,7 +1049,7 @@ Invoked from loss detection's OnPacketAcked and is supplied with
acked_packet from sent_packets.

~~~
InRecovery(packet_number)
InRecovery(packet_number):
return packet_number <= end_of_recovery

OnPacketAckedCC(acked_packet):
Expand All @@ -1042,6 +1067,38 @@ acked_packet from sent_packets.
kDefaultMss * acked_packet.bytes / congestion_window
~~~

### On Congestion Event Detected

Invoked functions detecting a congestion event, i.e. OnPacketsMarked and
OnPacketLost. Performs a common congestion event response by reducing the
congestion window and starting a recovery period unless already in recovery.

~~~
CongestionEvent(packet_number):
// Start a new recovery epoch if the event packet is larger
// than the end of the previous recovery epoch.
if (!InRecovery(packet_number)):
// Start a new congestion epoch
end_of_recovery = largest_sent_packet
congestion_window *= kMarkReductionFactor
congestion_window = max(congestion_window, kMinimumWindow)
~~~

### On Packets Marked

Invoked by an increment in the number of CE marked packets, as
indicated by a newly received ACK_ECN frame when compared to
previous_ecn_ce_ctr.

~~~
OnPacketsMarked(ce_counter):
if (ce_counter > previous_ecn_ce_ctr):
// update previous_ecn_ce_ctr
previous_ecn_ce_ctr = ce_counter
CongestionEvent(largest_newly_acked.packet_number)
~~~


### On Packets Lost

Invoked by loss detection from DetectLostPackets when new packets
Expand All @@ -1055,11 +1112,7 @@ 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.
if (!InRecovery(largest_lost_packet.packet_number)):
end_of_recovery = largest_sent_packet
congestion_window *= kLossReductionFactor
congestion_window = max(congestion_window, kMinimumWindow)
ssthresh = congestion_window
CongestionEvent(largest_lost_packet.packet_number)
~~~

### On Retransmission Timeout Verified
Expand Down