draft-ietf-quic-recovery-02.txt | draft-ietf-quic-recovery-03.txt | |||
---|---|---|---|---|
QUIC J. Iyengar, Ed. | QUIC J. Iyengar, Ed. | |||
Internet-Draft I. Swett, Ed. | Internet-Draft I. Swett, Ed. | |||
Intended status: Standards Track Google | Intended status: Standards Track Google | |||
Expires: September 14, 2017 March 13, 2017 | Expires: November 22, 2017 May 21, 2017 | |||
QUIC Loss Detection and Congestion Control | QUIC Loss Detection and Congestion Control | |||
draft-ietf-quic-recovery-02 | draft-ietf-quic-recovery-03 | |||
Abstract | Abstract | |||
QUIC is a new multiplexed and secure transport atop UDP. QUIC builds | This document describes loss detection and congestion control | |||
on decades of transport and security experience, and implements | mechanisms for QUIC. | |||
mechanisms that make it attractive as a modern general-purpose | ||||
transport. QUIC implements the spirit of known TCP loss detection | ||||
mechanisms, described in RFCs, various Internet-drafts, and also | ||||
those prevalent in the Linux TCP implementation. This document | ||||
describes QUIC loss detection and congestion control, and attributes | ||||
the TCP equivalent in RFCs, Internet-drafts, academic papers, and TCP | ||||
implementations. | ||||
Note to Readers | Note to Readers | |||
Discussion of this draft takes place on the QUIC working group | Discussion of this draft takes place on the QUIC working group | |||
mailing list (quic@ietf.org), which is archived at | mailing list (quic@ietf.org), which is archived at | |||
https://mailarchive.ietf.org/arch/search/?email_list=quic . | https://mailarchive.ietf.org/arch/search/?email_list=quic . | |||
Working Group information can be found at https://github.com/quicwg ; | Working Group information can be found at https://github.com/quicwg ; | |||
source code and issues list for this draft can be found at | source code and issues list for this draft can be found at | |||
https://github.com/quicwg/base-drafts/labels/recovery . | https://github.com/quicwg/base-drafts/labels/recovery . | |||
skipping to change at page 1, line 48 ¶ | skipping to change at page 1, line 41 ¶ | |||
Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
Drafts is at http://datatracker.ietf.org/drafts/current/. | Drafts is at http://datatracker.ietf.org/drafts/current/. | |||
Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
This Internet-Draft will expire on September 14, 2017. | This Internet-Draft will expire on November 22, 2017. | |||
Copyright Notice | Copyright Notice | |||
Copyright (c) 2017 IETF Trust and the persons identified as the | Copyright (c) 2017 IETF Trust and the persons identified as the | |||
document authors. All rights reserved. | document authors. All rights reserved. | |||
This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
Provisions Relating to IETF Documents | Provisions Relating to IETF Documents | |||
(http://trustee.ietf.org/license-info) in effect on the date of | (http://trustee.ietf.org/license-info) in effect on the date of | |||
publication of this document. Please review these documents | publication of this document. Please review these documents | |||
skipping to change at page 2, line 31 ¶ | skipping to change at page 2, line 23 ¶ | |||
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
1.1. Notational Conventions . . . . . . . . . . . . . . . . . 3 | 1.1. Notational Conventions . . . . . . . . . . . . . . . . . 3 | |||
2. Design of the QUIC Transmission Machinery . . . . . . . . . . 3 | 2. Design of the QUIC Transmission Machinery . . . . . . . . . . 3 | |||
2.1. Relevant Differences Between QUIC and TCP . . . . . . . . 4 | 2.1. Relevant Differences Between QUIC and TCP . . . . . . . . 4 | |||
2.1.1. Monotonically Increasing Packet Numbers . . . . . . . 4 | 2.1.1. Monotonically Increasing Packet Numbers . . . . . . . 4 | |||
2.1.2. No Reneging . . . . . . . . . . . . . . . . . . . . . 4 | 2.1.2. No Reneging . . . . . . . . . . . . . . . . . . . . . 4 | |||
2.1.3. More ACK Ranges . . . . . . . . . . . . . . . . . . . 5 | 2.1.3. More ACK Ranges . . . . . . . . . . . . . . . . . . . 5 | |||
2.1.4. Explicit Correction For Delayed Acks . . . . . . . . 5 | 2.1.4. Explicit Correction For Delayed Acks . . . . . . . . 5 | |||
3. Loss Detection . . . . . . . . . . . . . . . . . . . . . . . 5 | 3. Loss Detection . . . . . . . . . . . . . . . . . . . . . . . 5 | |||
3.1. Constants of interest . . . . . . . . . . . . . . . . . . 5 | 3.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . 5 | |||
3.2. Variables of interest . . . . . . . . . . . . . . . . . . 6 | 3.2. Algorithm Details . . . . . . . . . . . . . . . . . . . . 6 | |||
3.3. Initialization . . . . . . . . . . . . . . . . . . . . . 7 | 3.2.1. Constants of interest . . . . . . . . . . . . . . . . 6 | |||
3.4. On Sending a Packet . . . . . . . . . . . . . . . . . . . 7 | 3.2.2. Variables of interest . . . . . . . . . . . . . . . . 6 | |||
3.5. On Ack Receipt . . . . . . . . . . . . . . . . . . . . . 8 | 3.2.3. Initialization . . . . . . . . . . . . . . . . . . . 7 | |||
3.6. On Packet Acknowledgment . . . . . . . . . . . . . . . . 8 | 3.2.4. On Sending a Packet . . . . . . . . . . . . . . . . . 8 | |||
3.7. Setting the Loss Detection Alarm . . . . . . . . . . . . 9 | 3.2.5. On Ack Receipt . . . . . . . . . . . . . . . . . . . 8 | |||
3.7.1. Handshake Packets . . . . . . . . . . . . . . . . . . 9 | 3.2.6. On Packet Acknowledgment . . . . . . . . . . . . . . 9 | |||
3.7.2. Tail Loss Probe and Retransmission Timeout . . . . . 9 | 3.2.7. Setting the Loss Detection Alarm . . . . . . . . . . 10 | |||
3.7.3. Early Retransmit . . . . . . . . . . . . . . . . . . 9 | 3.2.8. On Alarm Firing . . . . . . . . . . . . . . . . . . . 12 | |||
3.7.4. Pseudocode . . . . . . . . . . . . . . . . . . . . . 10 | 3.2.9. Detecting Lost Packets . . . . . . . . . . . . . . . 12 | |||
3.8. On Alarm Firing . . . . . . . . . . . . . . . . . . . . . 10 | 3.3. Discussion . . . . . . . . . . . . . . . . . . . . . . . 13 | |||
3.9. Detecting Lost Packets . . . . . . . . . . . . . . . . . 11 | 4. Congestion Control . . . . . . . . . . . . . . . . . . . . . 14 | |||
3.9.1. Handshake Packets . . . . . . . . . . . . . . . . . . 11 | 4.1. Slow Start . . . . . . . . . . . . . . . . . . . . . . . 14 | |||
3.9.2. Pseudocode . . . . . . . . . . . . . . . . . . . . . 11 | 4.2. Recovery . . . . . . . . . . . . . . . . . . . . . . . . 14 | |||
4. Congestion Control . . . . . . . . . . . . . . . . . . . . . 12 | 4.3. Constants of interest . . . . . . . . . . . . . . . . . . 14 | |||
5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 12 | 4.4. Variables of interest . . . . . . . . . . . . . . . . . . 14 | |||
6. References . . . . . . . . . . . . . . . . . . . . . . . . . 12 | 4.5. Initialization . . . . . . . . . . . . . . . . . . . . . 15 | |||
6.1. Normative References . . . . . . . . . . . . . . . . . . 12 | 4.6. On Packet Acknowledgement . . . . . . . . . . . . . . . . 15 | |||
6.2. Informative References . . . . . . . . . . . . . . . . . 13 | 4.7. On Packets Lost . . . . . . . . . . . . . . . . . . . . . 15 | |||
Appendix A. Acknowledgments . . . . . . . . . . . . . . . . . . 13 | 4.8. On Retransmission Timeout Verified . . . . . . . . . . . 16 | |||
Appendix B. Change Log . . . . . . . . . . . . . . . . . . . . . 13 | 4.9. Pacing Packets . . . . . . . . . . . . . . . . . . . . . 16 | |||
B.1. Since draft-ietf-quic-recovery-01 . . . . . . . . . . . . 14 | 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 16 | |||
B.2. Since draft-ietf-quic-recovery-00: . . . . . . . . . . . 14 | 6. References . . . . . . . . . . . . . . . . . . . . . . . . . 16 | |||
B.3. Since draft-iyengar-quic-loss-recovery-01: . . . . . . . 14 | 6.1. Normative References . . . . . . . . . . . . . . . . . . 16 | |||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 14 | 6.2. Informative References . . . . . . . . . . . . . . . . . 16 | |||
Appendix A. Acknowledgments . . . . . . . . . . . . . . . . . . 17 | ||||
Appendix B. Change Log . . . . . . . . . . . . . . . . . . . . . 17 | ||||
B.1. Since draft-ietf-quic-recovery-02 . . . . . . . . . . . . 17 | ||||
B.2. Since draft-ietf-quic-recovery-01 . . . . . . . . . . . . 18 | ||||
B.3. Since draft-ietf-quic-recovery-00 . . . . . . . . . . . . 18 | ||||
B.4. Since draft-iyengar-quic-loss-recovery-01 . . . . . . . . 18 | ||||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 18 | ||||
1. Introduction | 1. Introduction | |||
QUIC is a new multiplexed and secure transport atop UDP. QUIC builds | QUIC is a new multiplexed and secure transport atop UDP. QUIC builds | |||
on decades of transport and security experience, and implements | on decades of transport and security experience, and implements | |||
mechanisms that make it attractive as a modern general-purpose | mechanisms that make it attractive as a modern general-purpose | |||
transport. The QUIC protocol is described in [QUIC-TRANSPORT]. | transport. The QUIC protocol is described in [QUIC-TRANSPORT]. | |||
QUIC implements the spirit of known TCP loss recovery mechanisms, | QUIC implements the spirit of known TCP loss recovery mechanisms, | |||
described in RFCs, various Internet-drafts, and also those prevalent | described in RFCs, various Internet-drafts, and also those prevalent | |||
in the Linux TCP implementation. This document describes QUIC | in the Linux TCP implementation. This document describes QUIC | |||
congestion control and loss recovery, and where applicable, | congestion control and loss recovery, and where applicable, | |||
attributes the TCP equivalent in RFCs, Internet-drafts, academic | attributes the TCP equivalent in RFCs, Internet-drafts, academic | |||
papers, and/or TCP implementations. | papers, and/or TCP implementations. | |||
This document first describes pre-requisite parts of the QUIC | ||||
transmission machinery, then discusses QUIC's default congestion | ||||
control and loss detection mechanisms, and finally lists the various | ||||
TCP mechanisms that QUIC loss detection implements (in spirit.) | ||||
1.1. Notational Conventions | 1.1. Notational Conventions | |||
The words "MUST", "MUST NOT", "SHOULD", and "MAY" are used in this | The words "MUST", "MUST NOT", "SHOULD", and "MAY" are used in this | |||
document. It's not shouting; when they are capitalized, they have | document. It's not shouting; when they are capitalized, they have | |||
the special meaning defined in [RFC2119]. | the special meaning defined in [RFC2119]. | |||
2. Design of the QUIC Transmission Machinery | 2. Design of the QUIC Transmission Machinery | |||
All transmissions in QUIC are sent with a packet-level header, which | All transmissions in QUIC are sent with a packet-level header, which | |||
includes a packet sequence number (referred to below as a packet | includes a packet sequence number (referred to below as a packet | |||
skipping to change at page 4, line 5 ¶ | skipping to change at page 3, line 48 ¶ | |||
loss detection mechanisms. | loss detection mechanisms. | |||
Every packet may contain several frames. We outline the frames that | Every packet may contain several frames. We outline the frames that | |||
are important to the loss detection and congestion control machinery | are important to the loss detection and congestion control machinery | |||
below. | below. | |||
o Retransmittable frames are frames requiring reliable delivery. | o Retransmittable frames are frames requiring reliable delivery. | |||
The most common are STREAM frames, which typically contain | The most common are STREAM frames, which typically contain | |||
application data. | application data. | |||
o Crypto handshake data is also sent as STREAM data, and uses the | o Crypto handshake data is sent on stream 0, and uses the | |||
reliability machinery of QUIC underneath. | reliability machinery of QUIC underneath. | |||
o ACK frames contain acknowledgment information. QUIC uses a SACK- | o ACK frames contain acknowledgment information. QUIC uses a SACK- | |||
based scheme, where acks express up to 256 ranges. The ACK frame | based scheme, where acks express up to 256 ranges. The ACK frame | |||
also includes a receive timestamp for each packet newly acked. | also includes a receive timestamp for each packet newly acked. | |||
2.1. Relevant Differences Between QUIC and TCP | 2.1. Relevant Differences Between QUIC and TCP | |||
There are some notable differences between QUIC and TCP which are | Readers familiar with TCP's loss detection and congestion control | |||
important for reasoning about the differences between the loss | will find algorithms here that parallel well-known TCP ones. | |||
recovery mechanisms employed by the two protocols. We briefly | Protocol differences between QUIC and TCP however contribute to | |||
describe these differences below. | algorithmic differences. We briefly describe these protocol | |||
differences below. | ||||
2.1.1. Monotonically Increasing Packet Numbers | 2.1.1. Monotonically Increasing Packet Numbers | |||
TCP conflates transmission sequence number at the sender with | TCP conflates transmission sequence number at the sender with | |||
delivery sequence number at the receiver, which results in | delivery sequence number at the receiver, which results in | |||
retransmissions of the same data carrying the same sequence number, | retransmissions of the same data carrying the same sequence number, | |||
and consequently to problems caused by "retransmission ambiguity". | and consequently to problems caused by "retransmission ambiguity". | |||
QUIC separates the two: QUIC uses a packet sequence number (referred | QUIC separates the two: QUIC uses a packet sequence number (referred | |||
to as the "packet number") for transmissions, and any data that is to | to as the "packet number") for transmissions, and any data that is to | |||
be delivered to the receiving application(s) is sent in one or more | be delivered to the receiving application(s) is sent in one or more | |||
skipping to change at page 5, line 23 ¶ | skipping to change at page 5, line 23 ¶ | |||
between when a packet is received and when the corresponding ACK is | between when a packet is received and when the corresponding ACK is | |||
sent. This allows the receiver of the ACK to adjust for receiver | sent. This allows the receiver of the ACK to adjust for receiver | |||
delays, specifically the delayed ack timer, when estimating the path | delays, specifically the delayed ack timer, when estimating the path | |||
RTT. This mechanism also allows a receiver to measure and report the | RTT. This mechanism also allows a receiver to measure and report the | |||
delay from when a packet was received by the OS kernel, which is | delay from when a packet was received by the OS kernel, which is | |||
useful in receivers which may incur delays such as context-switch | useful in receivers which may incur delays such as context-switch | |||
latency before a userspace QUIC receiver processes a received packet. | latency before a userspace QUIC receiver processes a received packet. | |||
3. Loss Detection | 3. Loss Detection | |||
We now describe QUIC's loss detection as functions that should be | 3.1. Overview | |||
called on packet transmission, when a packet is acked, and timer | ||||
expiration events. | ||||
3.1. Constants of interest | QUIC uses a combination of ack information and alarms to detect lost | |||
packets. An unacknowledged QUIC packet is marked as lost in one of | ||||
the following ways: | ||||
Constants used in loss recovery and congestion control are based on a | o A packet is marked as lost if at least one packet that was sent a | |||
combination of RFCs, papers, and common practice. Some may need to | threshold number of packets (kReorderingThreshold) after it has | |||
be changed or negotiated in order to better suit a variety of | been acknowledged. This indicates that the unacknowledged packet | |||
environments. | is either lost or reordered beyond the specified threshold. This | |||
mechanism combines both TCP's FastRetransmit and FACK mechanisms. | ||||
o If a packet is near the tail, where fewer than | ||||
kReorderingThreshold packets are sent after it, the sender cannot | ||||
expect to detect loss based on the previous mechanism. In this | ||||
case, a sender uses both ack information and an alarm to detect | ||||
loss. Specifically, when the last sent packet is acknowledged, | ||||
the sender waits a short period of time to allow for reordering | ||||
and then marks any unacknowledged packets as lost. This mechanism | ||||
is based on the Linux implementation of TCP Early Retransmit. | ||||
o If a packet is sent at the tail, there are no packets sent after | ||||
it, and the sender cannot use ack information to detect its loss. | ||||
The sender therefore relies on an alarm to detect such tail | ||||
losses. This mechanism is based on TCP's Tail Loss Probe. | ||||
o If all else fails, a Retransmission Timeout (RTO) alarm is always | ||||
set when any retransmittable packet is outstanding. When this | ||||
alarm fires, all unacknowledged packets are marked as lost. | ||||
o Instead of a packet threshold to tolerate reordering, a QUIC | ||||
sender may use a time threshold. This allows for senders to be | ||||
tolerant of short periods of significant reordering. In this | ||||
mechanism, a QUIC sender marks a packet as lost when a packet | ||||
larger than it is acknowledged and a threshold amount of time has | ||||
passed since the packet was sent. | ||||
o Handshake packets, which contain STREAM frames for stream 0, are | ||||
critical to QUIC transport and crypto negotiation, so a separate | ||||
alarm period is used for them. | ||||
3.2. Algorithm Details | ||||
3.2.1. Constants of interest | ||||
Constants used in loss recovery are based on a combination of RFCs, | ||||
papers, and common practice. Some may need to be changed or | ||||
negotiated in order to better suit a variety of environments. | ||||
kMaxTLPs (default 2): Maximum number of tail loss probes before an | kMaxTLPs (default 2): Maximum number of tail loss probes before an | |||
RTO fires. | RTO fires. | |||
kReorderingThreshold (default 3): Maximum reordering in packet | kReorderingThreshold (default 3): Maximum reordering in packet | |||
number space before FACK style loss detection considers a packet | number space before FACK style loss detection considers a packet | |||
lost. | lost. | |||
kTimeReorderingFraction (default 1/8): Maximum reordering in time | kTimeReorderingFraction (default 1/8): Maximum reordering in time | |||
sapce before time based loss detection considers a packet lost. | space before time based loss detection considers a packet lost. | |||
In fraction of an RTT. | In fraction of an RTT. | |||
kMinTLPTimeout (default 10ms): Minimum time in the future a tail | kMinTLPTimeout (default 10ms): Minimum time in the future a tail | |||
loss probe alarm may be set for. | loss probe alarm may be set for. | |||
kMinRTOTimeout (default 200ms): Minimum time in the future an RTO | kMinRTOTimeout (default 200ms): Minimum time in the future an RTO | |||
alarm may be set for. | alarm may be set for. | |||
kDelayedAckTimeout (default 25ms): The length of the peer's delayed | kDelayedAckTimeout (default 25ms): The length of the peer's delayed | |||
ack timer. | ack timer. | |||
kDefaultInitialRtt (default 100ms): The default RTT used before an | kDefaultInitialRtt (default 100ms): The default RTT used before an | |||
RTT sample is taken. | RTT sample is taken. | |||
3.2. Variables of interest | 3.2.2. Variables of interest | |||
We first describe the variables required to implement the loss | Variables required to implement the congestion control mechanisms are | |||
detection mechanisms described in this section. | described in this section. | |||
loss_detection_alarm: Multi-modal alarm used for loss detection. | loss_detection_alarm: Multi-modal alarm used for loss detection. | |||
handshake_count: The number of times the handshake packets have been | handshake_count: The number of times the handshake packets have been | |||
retransmitted without receiving an ack. | retransmitted without receiving an ack. | |||
tlp_count: The number of times a tail loss probe has been sent | tlp_count: The number of times a tail loss probe has been sent | |||
without receiving an ack. | without receiving an ack. | |||
rto_count: The number of times an rto has been sent without | rto_count: The number of times an rto has been sent without | |||
receiving an ack. | receiving an ack. | |||
largest_sent_before_rto: The last packet number sent prior to the | ||||
first retransmission timeout. | ||||
smoothed_rtt: The smoothed RTT of the connection, computed as | smoothed_rtt: The smoothed RTT of the connection, computed as | |||
described in [RFC6298] | described in [RFC6298] | |||
rttvar: The RTT variance, computed as described in [RFC6298] | rttvar: The RTT variance, computed as described in [RFC6298] | |||
initial_rtt: The initial RTT used before any RTT measurements have | ||||
been made. | ||||
reordering_threshold: The largest delta between the largest acked | reordering_threshold: The largest delta between the largest acked | |||
retransmittable packet and a packet containing retransmittable | retransmittable packet and a packet containing retransmittable | |||
frames before it's declared lost. | frames before it's declared lost. | |||
time_reordering_fraction: The reordering window as a fraction of | time_reordering_fraction: The reordering window as a fraction of | |||
max(smoothed_rtt, latest_rtt). | max(smoothed_rtt, latest_rtt). | |||
loss_time: The time at which the next packet will be considered lost | loss_time: The time at which the next packet will be considered lost | |||
based on early transmit or exceeding the reordering window in | based on early transmit or exceeding the reordering window in | |||
time. | time. | |||
sent_packets: An association of packet numbers to information about | sent_packets: An association of packet numbers to information about | |||
them, including a number field indicating the packet number, a | them, including a number field indicating the packet number, a | |||
time field indicating the time a packet was sent, and a bytes | time field indicating the time a packet was sent, and a bytes | |||
field indicating the packet's size. sent_packets is ordered by | field indicating the packet's size. sent_packets is ordered by | |||
packet number, and packets remain in sent_packets until | packet number, and packets remain in sent_packets until | |||
acknowledged or lost. | acknowledged or lost. | |||
3.3. Initialization | 3.2.3. Initialization | |||
At the beginning of the connection, initialize the loss detection | At the beginning of the connection, initialize the loss detection | |||
variables as follows: | variables as follows: | |||
loss_detection_alarm.reset() | loss_detection_alarm.reset() | |||
handshake_count = 0 | handshake_count = 0 | |||
tlp_count = 0 | tlp_count = 0 | |||
rto_count = 0 | rto_count = 0 | |||
if (UsingTimeLossDetection()) | if (UsingTimeLossDetection()) | |||
reordering_threshold = infinite | reordering_threshold = infinite | |||
time_reordering_fraction = kTimeReorderingFraction | time_reordering_fraction = kTimeReorderingFraction | |||
else: | else: | |||
reordering_threshold = kReorderingThreshold | reordering_threshold = kReorderingThreshold | |||
time_reordering_fraction = infinite | time_reordering_fraction = infinite | |||
loss_time = 0 | loss_time = 0 | |||
smoothed_rtt = 0 | smoothed_rtt = 0 | |||
rttvar = 0 | rttvar = 0 | |||
initial_rtt = kDefaultInitialRtt | largest_sent_before_rto = 0 | |||
3.4. On Sending a Packet | 3.2.4. On Sending a Packet | |||
After any packet is sent, be it a new transmission or a rebundled | After any packet is sent, be it a new transmission or a rebundled | |||
transmission, the following OnPacketSent function is called. The | transmission, the following OnPacketSent function is called. The | |||
parameters to OnPacketSent are as follows: | parameters to OnPacketSent are as follows: | |||
o packet_number: The packet number of the sent packet. | o packet_number: The packet number of the sent packet. | |||
o is_retransmittble: A boolean that indicates whether the packet | o is_retransmittable: A boolean that indicates whether the packet | |||
contains at least one frame requiring reliable deliver. The | contains at least one frame requiring reliable deliver. The | |||
retransmittability of various QUIC frames is described in | retransmittability of various QUIC frames is described in | |||
[QUIC-TRANSPORT]. If false, it is still acceptable for an ack to | [QUIC-TRANSPORT]. If false, it is still acceptable for an ack to | |||
be received for this packet. However, a caller MUST NOT set | be received for this packet. However, a caller MUST NOT set | |||
is_retransmittable to true if an ack is not expected. | is_retransmittable to true if an ack is not expected. | |||
o sent_bytes: The number of bytes sent in the packet. | o sent_bytes: The number of bytes sent in the packet. | |||
Pseudocode for OnPacketSent follows: | Pseudocode for OnPacketSent follows: | |||
OnPacketSent(packet_number, is_retransmittable, sent_bytes): | OnPacketSent(packet_number, is_retransmittable, sent_bytes): | |||
sent_packets[packet_number].packet_number = packet_number | sent_packets[packet_number].packet_number = packet_number | |||
sent_packets[packet_number].time = now | sent_packets[packet_number].time = now | |||
if is_retransmittable: | if is_retransmittable: | |||
sent_packets[packet_number].bytes = sent_bytes | sent_packets[packet_number].bytes = sent_bytes | |||
SetLossDetectionAlarm() | SetLossDetectionAlarm() | |||
3.5. On Ack Receipt | 3.2.5. On Ack Receipt | |||
When an ack is received, it may acknowledge 0 or more packets. | When an ack is received, it may acknowledge 0 or more packets. | |||
The sender MUST abort the connection if it receives an ACK for a | ||||
packet it never sent, see [QUIC-TRANSPORT]. | ||||
Pseudocode for OnAckReceived and UpdateRtt follow: | Pseudocode for OnAckReceived and UpdateRtt follow: | |||
OnAckReceived(ack): | OnAckReceived(ack): | |||
// If the largest acked is newly acked, update the RTT. | // If the largest acked is newly acked, update the RTT. | |||
if (sent_packets[ack.largest_acked]): | if (sent_packets[ack.largest_acked]): | |||
rtt_sample = now - sent_packets[ack.largest_acked].time | rtt_sample = now - sent_packets[ack.largest_acked].time | |||
if (rtt_sample > ack.ack_delay): | if (rtt_sample > ack.ack_delay): | |||
rtt_sample -= ack.delay | rtt_sample -= ack.delay | |||
UpdateRtt(rtt_sample) | UpdateRtt(rtt_sample) | |||
// The sender may skip packets for detecting optimistic ACKs | ||||
if (packets acked that the sender skipped): | ||||
abortConnection() | ||||
// Find all newly acked packets. | // Find all newly acked packets. | |||
for acked_packet_number in DetermineNewlyAckedPackets(): | for acked_packet in DetermineNewlyAckedPackets(): | |||
OnPacketAcked(acked_packet_number) | OnPacketAcked(acked_packet.packet_number) | |||
DetectLostPackets(ack.largest_acked_packet) | DetectLostPackets(ack.largest_acked_packet) | |||
SetLossDetectionAlarm() | SetLossDetectionAlarm() | |||
UpdateRtt(rtt_sample): | UpdateRtt(rtt_sample): | |||
// Based on {{RFC6298}}. | // Based on {{RFC6298}}. | |||
if (smoothed_rtt == 0): | if (smoothed_rtt == 0): | |||
smoothed_rtt = rtt_sample | smoothed_rtt = rtt_sample | |||
rttvar = rtt_sample / 2 | rttvar = rtt_sample / 2 | |||
else: | else: | |||
rttvar = 3/4 * rttvar + 1/4 * (smoothed_rtt - rtt_sample) | rttvar = 3/4 * rttvar + 1/4 * (smoothed_rtt - rtt_sample) | |||
smoothed_rtt = 7/8 * smoothed_rtt + 1/8 * rtt_sample | smoothed_rtt = 7/8 * smoothed_rtt + 1/8 * rtt_sample | |||
3.6. On Packet Acknowledgment | 3.2.6. On Packet Acknowledgment | |||
When a packet is acked for the first time, the following | When a packet is acked for the first time, the following | |||
OnPacketAcked function is called. Note that a single ACK frame may | OnPacketAcked function is called. Note that a single ACK frame may | |||
newly acknowledge several packets. OnPacketAcked must be called once | newly acknowledge several packets. OnPacketAcked must be called once | |||
for each of these newly acked packets. | for each of these newly acked packets. | |||
OnPacketAcked takes one parameter, acked_packet, which is the packet | OnPacketAcked takes one parameter, acked_packet, which is the packet | |||
number of the newly acked packet, and returns a list of packet | number of the newly acked packet, and returns a list of packet | |||
numbers that are detected as lost. | numbers that are detected as lost. | |||
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] | ||||
Pseudocode for OnPacketAcked follows: | Pseudocode for OnPacketAcked follows: | |||
OnPacketAcked(acked_packet_number): | OnPacketAcked(acked_packet_number): | |||
// If a packet sent prior to RTO was acked, then the RTO | ||||
// was spurious. Otherwise, inform congestion control. | ||||
if (rto_count > 0 && | ||||
acked_packet_number > largest_sent_before_rto) | ||||
OnRetransmissionTimeoutVerified() | ||||
handshake_count = 0 | handshake_count = 0 | |||
tlp_count = 0 | tlp_count = 0 | |||
rto_count = 0 | rto_count = 0 | |||
sent_packets.remove(acked_packet_number) | sent_packets.remove(acked_packet_number) | |||
3.7. Setting the Loss Detection Alarm | 3.2.7. Setting the Loss Detection Alarm | |||
QUIC loss detection uses a single alarm for all timer-based loss | QUIC loss detection uses a single alarm for all timer-based loss | |||
detection. The duration of the alarm is based on the alarm's mode, | detection. The duration of the alarm is based on the alarm's mode, | |||
which is set in the packet and timer events further below. The | which is set in the packet and timer events further below. The | |||
function SetLossDetectionAlarm defined below shows how the single | function SetLossDetectionAlarm defined below shows how the single | |||
timer is set based on the alarm mode. | timer is set based on the alarm mode. | |||
3.7.1. Handshake Packets | 3.2.7.1. Handshake Packets | |||
The initial flight has no prior RTT sample. A client SHOULD remember | The initial flight has no prior RTT sample. A client SHOULD remember | |||
the previous RTT it observed when resumption is attempted and use | the previous RTT it observed when resumption is attempted and use | |||
that for an initial RTT value. If no previous RTT is available, the | that for an initial RTT value. If no previous RTT is available, the | |||
initial RTT defaults to 200ms. Once an RTT measurement is taken, it | initial RTT defaults to 200ms. | |||
MUST replace initial_rtt. | ||||
Endpoints MUST retransmit handshake frames if not acknowledged within | Endpoints MUST retransmit handshake frames if not acknowledged within | |||
a time limit. This time limit will start as the largest of twice the | a time limit. This time limit will start as the largest of twice the | |||
rtt value and MinTLPTimeout. Each consecutive handshake | rtt value and MinTLPTimeout. Each consecutive handshake | |||
retransmission doubles the time limit, until an acknowledgement is | retransmission doubles the time limit, until an acknowledgement is | |||
received. | received. | |||
Handshake frames may be cancelled by handshake state transitions. In | Handshake frames may be cancelled by handshake state transitions. In | |||
particular, all non-protected frames SHOULD be no longer be | particular, all non-protected frames SHOULD be no longer be | |||
transmitted once packet protection is available. | transmitted once packet protection is available. | |||
When stateless rejects are in use, the connection is considered | When stateless rejects are in use, the connection is considered | |||
immediately closed once a reject is sent, so no timer is set to | immediately closed once a reject is sent, so no timer is set to | |||
retransmit the reject. | retransmit the reject. | |||
Version negotiation packets are always stateless, and MUST be sent | Version negotiation packets are always stateless, and MUST be sent | |||
once per per handshake packet that uses an unsupported QUIC version, | once per per handshake packet that uses an unsupported QUIC version, | |||
and MAY be sent in response to 0RTT packets. | and MAY be sent in response to 0RTT packets. | |||
3.7.2. Tail Loss Probe and Retransmission Timeout | 3.2.7.2. Tail Loss Probe and Retransmission Timeout | |||
Tail loss probes [I-D.dukkipati-tcpm-tcp-loss-probe] and | Tail loss probes [LOSS-PROBE] and retransmission timeouts [RFC6298] | |||
retransmission timeouts[RFC6298] are an alarm based mechanism to | are an alarm based mechanism to recover from cases when there are | |||
recover from cases when there are outstanding retransmittable | outstanding retransmittable packets, but an acknowledgement has not | |||
packets, but an acknowledgement has not been received in a timely | been received in a timely manner. | |||
manner. | ||||
3.7.3. Early Retransmit | 3.2.7.3. Early Retransmit | |||
Early retransmit [RFC5827] is implemented with a 1/4 RTT timer. It | Early retransmit [RFC5827] is implemented with a 1/4 RTT timer. It | |||
is part of QUIC's time based loss detection, but is always enabled, | is part of QUIC's time based loss detection, but is always enabled, | |||
even when only packet reordering loss detection is enabled. | even when only packet reordering loss detection is enabled. | |||
3.7.4. Pseudocode | 3.2.7.4. Pseudocode | |||
Pseudocode for SetLossDetectionAlarm follows: | Pseudocode for SetLossDetectionAlarm follows: | |||
SetLossDetectionAlarm(): | SetLossDetectionAlarm(): | |||
if (retransmittable packets are not outstanding): | if (retransmittable packets are not outstanding): | |||
loss_detection_alarm.cancel(); | loss_detection_alarm.cancel() | |||
return | return | |||
if (handshake packets are outstanding): | if (handshake packets are outstanding): | |||
// Handshake retransmission alarm. | // Handshake retransmission alarm. | |||
if (smoothed_rtt == 0): | if (smoothed_rtt == 0): | |||
alarm_duration = 2 * initial_rtt | alarm_duration = 2 * kDefaultInitialRtt | |||
else: | else: | |||
alarm_duration = 2 * smoothed_rtt | alarm_duration = 2 * smoothed_rtt | |||
alarm_duration = max(alarm_duration, kMinTLPTimeout) | alarm_duration = max(alarm_duration, kMinTLPTimeout) | |||
alarm_duration = alarm_duration << handshake_count | alarm_duration = alarm_duration * (2 ^ handshake_count) | |||
else if (loss_time != 0): | else if (loss_time != 0): | |||
// Early retransmit timer or time loss detection. | // Early retransmit timer or time loss detection. | |||
alarm_duration = loss_time - now | alarm_duration = loss_time - now | |||
else if (tlp_count < kMaxTLPs): | else if (tlp_count < kMaxTLPs): | |||
// Tail Loss Probe | // Tail Loss Probe | |||
if (retransmittable_packets_outstanding = 1): | if (retransmittable_packets_outstanding = 1): | |||
alarm_duration = 1.5 * smoothed_rtt + kDelayedAckTimeout | alarm_duration = 1.5 * smoothed_rtt + kDelayedAckTimeout | |||
else: | else: | |||
alarm_duration = kMinTLPTimeout | alarm_duration = kMinTLPTimeout | |||
alarm_duration = max(alarm_duration, 2 * smoothed_rtt) | alarm_duration = max(alarm_duration, 2 * smoothed_rtt) | |||
else: | else: | |||
// RTO alarm | // RTO alarm | |||
if (rto_count = 0): | alarm_duration = smoothed_rtt + 4 * rttvar | |||
alarm_duration = smoothed_rtt + 4 * rttvar | alarm_duration = max(alarm_duration, kMinRTOTimeout) | |||
alarm_duration = max(alarm_duration, kMinRTOTimeout) | alarm_duration = alarm_duration * (2 ^ rto_count) | |||
else: | ||||
alarm_duration = loss_detection_alarm.get_delay() << 1 | ||||
loss_detection_alarm.set(now + alarm_duration) | loss_detection_alarm.set(now + alarm_duration) | |||
3.8. On Alarm Firing | 3.2.8. On Alarm Firing | |||
QUIC uses one loss recovery alarm, which when set, can be in one of | QUIC uses one loss recovery alarm, which when set, can be in one of | |||
several modes. When the alarm fires, the mode determines the action | several modes. When the alarm fires, the mode determines the action | |||
to be performed. | to be performed. | |||
Pseudocode for OnLossDetectionAlarm follows: | Pseudocode for OnLossDetectionAlarm follows: | |||
OnLossDetectionAlarm(): | OnLossDetectionAlarm(): | |||
if (handshake packets are outstanding): | if (handshake packets are outstanding): | |||
// Handshake retransmission alarm. | // Handshake retransmission alarm. | |||
RetransmitAllHandshakePackets(); | RetransmitAllHandshakePackets() | |||
handshake_count++; | handshake_count++ | |||
// TODO: Clarify early retransmit and time loss. | ||||
else if (loss_time != 0): | else if (loss_time != 0): | |||
// Early retransmit or Time Loss Detection | // Early retransmit or Time Loss Detection | |||
DetectLostPackets(largest_acked_packet) | DetectLostPackets(largest_acked_packet) | |||
else if (tlp_count < kMaxTLPs): | else if (tlp_count < kMaxTLPs): | |||
// Tail Loss Probe. | // Tail Loss Probe. | |||
if (HasNewDataToSend()): | SendOnePacket() | |||
SendOnePacketOfNewData() | ||||
else: | ||||
RetransmitOldestPacket() | ||||
tlp_count++ | tlp_count++ | |||
else: | else: | |||
// RTO. | // RTO. | |||
RetransmitOldestTwoPackets() | if (rto_count == 0) | |||
largest_sent_before_rto = largest_sent_packet | ||||
SendTwoPackets() | ||||
rto_count++ | rto_count++ | |||
SetLossDetectionAlarm() | SetLossDetectionAlarm() | |||
3.9. Detecting Lost Packets | 3.2.9. Detecting Lost Packets | |||
Packets in QUIC are only considered lost once a larger packet number | Packets in QUIC are only considered lost once a larger packet number | |||
is acknowledged. DetectLostPackets is called every time an ack is | is acknowledged. DetectLostPackets is called every time an ack is | |||
received. If the loss detection alarm fires and the loss_time is | received. If the loss detection alarm fires and the loss_time is | |||
set, the previous largest acked packet is supplied. | set, the previous largest acked packet is supplied. | |||
3.9.1. Handshake Packets | 3.2.9.1. Handshake Packets | |||
The receiver MUST ignore unprotected packets that ack protected | The receiver MUST ignore unprotected packets that ack protected | |||
packets. The receiver MUST trust protected acks for unprotected | packets. The receiver MUST trust protected acks for unprotected | |||
packets, however. Aside from this, loss detection for handshake | packets, however. Aside from this, loss detection for handshake | |||
packets when an ack is processed is identical to other packets. | packets when an ack is processed is identical to other packets. | |||
3.9.2. Pseudocode | 3.2.9.2. Pseudocode | |||
DetectLostPackets takes one parameter, acked, which is the largest | DetectLostPackets takes one parameter, acked, which is the largest | |||
acked packet. | acked packet. | |||
Pseudocode for DetectLostPackets follows: | Pseudocode for DetectLostPackets follows: | |||
DetectLostPackets(largest_acked): | DetectLostPackets(largest_acked): | |||
loss_time = 0 | loss_time = 0 | |||
lost_packets = {} | lost_packets = {} | |||
delay_until_lost = infinite; | delay_until_lost = infinite | |||
if (time_reordering_fraction != infinite): | if (time_reordering_fraction != infinite): | |||
delay_until_lost = | delay_until_lost = | |||
(1 + time_reordering_fraction) * max(latest_rtt, smoothed_rtt) | (1 + time_reordering_fraction) * max(latest_rtt, smoothed_rtt) | |||
else if (largest_acked.packet_number == largest_sent_packet): | else if (largest_acked.packet_number == largest_sent_packet): | |||
// Early retransmit alarm. | // Early retransmit alarm. | |||
delay_until_lost = 9/8 * max(latest_rtt, smoothed_rtt) | delay_until_lost = 9/8 * max(latest_rtt, smoothed_rtt) | |||
foreach (unacked less than largest_acked.packet_number): | foreach (unacked < largest_acked.packet_number): | |||
time_since_sent = now() - unacked.time_sent | time_since_sent = now() - unacked.time_sent | |||
packet_delta = largest_acked.packet_number - unacked.packet_number | packet_delta = largest_acked.packet_number - unacked.packet_number | |||
if (time_since_sent > delay_until_lost): | if (time_since_sent > delay_until_lost): | |||
lost_packets.insert(unacked) | lost_packets.insert(unacked) | |||
else if (packet_delta > reordering_threshold) | else if (packet_delta > reordering_threshold) | |||
lost_packets.insert(unacked) | lost_packets.insert(unacked) | |||
else if (loss_time == 0 && delay_until_lost != infinite): | else if (loss_time == 0 && delay_until_lost != infinite): | |||
loss_time = delay_until_lost - time_since_sent | loss_time = now() + delay_until_lost - time_since_sent | |||
// Inform the congestion controller of lost packets and | // Inform the congestion controller of lost packets and | |||
// lets it decide whether to retransmit immediately. | // lets it decide whether to retransmit immediately. | |||
OnPacketsLost(lost_packets) | if (!lost_packets.empty()) | |||
foreach (packet in lost_packets) | OnPacketsLost(lost_packets) | |||
sent_packets.remove(packet.packet_number) | foreach (packet in lost_packets) | |||
sent_packets.remove(packet.packet_number) | ||||
3.3. Discussion | ||||
The majority of constants were derived from best common practices | ||||
among widely deployed TCP implementations on the internet. | ||||
Exceptions follow. | ||||
A shorter delayed ack time of 25ms was chosen because longer delayed | ||||
acks can delay loss recovery and for the small number of connections | ||||
where less than packet per 25ms is delivered, acking every packet is | ||||
beneficial to congestion control and loss recovery. | ||||
The default initial RTT of 100ms was chosen because it is slightly | ||||
higher than both the median and mean min_rtt typically observed on | ||||
the public internet. | ||||
4. Congestion Control | 4. Congestion Control | |||
(describe NewReno-style congestion control [RFC6582] for QUIC.) | QUIC's congestion control is based on TCP NewReno[RFC6582] congestion | |||
(describe appropriate byte counting.) (define recovery based on | control to determine the congestion window and pacing rate. | |||
packet numbers.) (describe min_rtt based hystart.) (describe how | ||||
QUIC's F-RTO [RFC5682] delays reducing CWND.) (describe PRR | 4.1. Slow Start | |||
[RFC6937]) | ||||
QUIC begins every connection in slow start and exits slow start upon | ||||
loss. While in slow start, QUIC increases the congestion window by | ||||
the number of acknowledged bytes when each ack is processed. | ||||
4.2. Recovery | ||||
Recovery is a period of time beginning with detection of a lost | ||||
packet. It ends when all packets outstanding at the time recovery | ||||
began have been acknowledged or lost. During recovery, the | ||||
congestion window is not increased or decreased. | ||||
4.3. Constants of interest | ||||
Constants used in congestion control are based on a combination of | ||||
RFCs, papers, and common practice. Some may need to be changed or | ||||
negotiated in order to better suit a variety of environments. | ||||
kDefaultMss (default 1460 bytes): The default max packet size used | ||||
for calculating default and minimum congestion windows. | ||||
kInitialWindow (default 10 * kDefaultMss): Default limit on the | ||||
amount of outstanding data in bytes. | ||||
kMinimumWindow (default 2 * kDefaultMss): Default minimum congestion | ||||
window. | ||||
kLossReductionFactor (default 0.5): Reduction in congestion window | ||||
when a new loss event is detected. | ||||
4.4. Variables of interest | ||||
Variables required to implement the congestion control mechanisms are | ||||
described in this section. | ||||
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 lost. | ||||
congestion_window: Maximum number of bytes in flight that may be | ||||
sent. | ||||
end_of_recovery: The packet number after which QUIC will no longer | ||||
be in recovery. | ||||
ssthresh Slow start threshold in bytes. When the congestion window | ||||
is below ssthresh, it grows by the number of bytes acknowledged | ||||
for each ack. | ||||
4.5. Initialization | ||||
At the beginning of the connection, initialize the loss detection | ||||
variables as follows: | ||||
congestion_window = kInitialWindow | ||||
bytes_in_flight = 0 | ||||
end_of_recovery = 0 | ||||
ssthresh = infinite | ||||
4.6. On Packet Acknowledgement | ||||
Invoked at the same time loss detection's OnPacketAcked is called and | ||||
supplied with the acked_packet from sent_packets. | ||||
Pseudocode for OnPacketAcked follows: | ||||
OnPacketAcked(acked_packet): | ||||
if (acked_packet.packet_number < end_of_recovery): | ||||
return | ||||
if (congestion_window < ssthresh): | ||||
congestion_window += acket_packets.bytes | ||||
else: | ||||
congestion_window += | ||||
acked_packets.bytes / congestion_window | ||||
4.7. On Packets Lost | ||||
Invoked by loss detection from DetectLostPackets when new packets are | ||||
detected lost. | ||||
OnPacketsLost(lost_packets): | ||||
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 (end_of_recovery < largest_lost_packet.packet_number): | ||||
end_of_recovery = largest_sent_packet | ||||
congestion_window *= kLossReductionFactor | ||||
congestion_window = max(congestion_window, kMinimumWindow) | ||||
ssthresh = congestion_window | ||||
4.8. On Retransmission Timeout Verified | ||||
QUIC decreases the congestion window to the minimum value once the | ||||
retransmission timeout has been confirmed to not be spurious when the | ||||
first post-RTO acknowledgement is processed. | ||||
OnRetransmissionTimeoutVerified() | ||||
congestion_window = kMinimumWindow | ||||
4.9. Pacing Packets | ||||
QUIC sends a packet if there is available congestion window and | ||||
sending the packet does not exceed the pacing rate. | ||||
TimeToSend returns infinite if the congestion controller is | ||||
congestion window limited, a time in the past if the packet can be | ||||
sent immediately, and a time in the future if sending is pacing | ||||
limited. | ||||
TimeToSend(packet_size): | ||||
if (bytes_in_flight + packet_size > congestion_window) | ||||
return infinite | ||||
return time_of_last_sent_packet + | ||||
(packet_size * smoothed_rtt) / congestion_window | ||||
5. IANA Considerations | 5. IANA Considerations | |||
This document has no IANA actions. Yet. | This document has no IANA actions. Yet. | |||
6. References | 6. References | |||
6.1. Normative References | 6.1. Normative References | |||
[QUIC-TRANSPORT] | [QUIC-TRANSPORT] | |||
Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based | Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based | |||
Multiplexed and Secure Transport". | Multiplexed and Secure Transport", draft-ietf-quic- | |||
transport (work in progress), May 2017. | ||||
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | |||
Requirement Levels", BCP 14, RFC 2119, | Requirement Levels", BCP 14, RFC 2119, | |||
DOI 10.17487/RFC2119, March 1997, | DOI 10.17487/RFC2119, March 1997, | |||
<http://www.rfc-editor.org/info/rfc2119>. | <http://www.rfc-editor.org/info/rfc2119>. | |||
6.2. Informative References | 6.2. Informative References | |||
[I-D.dukkipati-tcpm-tcp-loss-probe] | [LOSS-PROBE] | |||
Dukkipati, N., Cardwell, N., Cheng, Y., and M. Mathis, | Dukkipati, N., Cardwell, N., Cheng, Y., and M. Mathis, | |||
"Tail Loss Probe (TLP): An Algorithm for Fast Recovery of | "Tail Loss Probe (TLP): An Algorithm for Fast Recovery of | |||
Tail Losses", draft-dukkipati-tcpm-tcp-loss-probe-01 (work | Tail Losses", draft-dukkipati-tcpm-tcp-loss-probe-01 (work | |||
in progress), February 2013. | in progress), February 2013. | |||
[RFC5682] Sarolahti, P., Kojo, M., Yamamoto, K., and M. Hata, | [RFC5682] Sarolahti, P., Kojo, M., Yamamoto, K., and M. Hata, | |||
"Forward RTO-Recovery (F-RTO): An Algorithm for Detecting | "Forward RTO-Recovery (F-RTO): An Algorithm for Detecting | |||
Spurious Retransmission Timeouts with TCP", RFC 5682, | Spurious Retransmission Timeouts with TCP", RFC 5682, | |||
DOI 10.17487/RFC5682, September 2009, | DOI 10.17487/RFC5682, September 2009, | |||
<http://www.rfc-editor.org/info/rfc5682>. | <http://www.rfc-editor.org/info/rfc5682>. | |||
skipping to change at page 13, line 40 ¶ | skipping to change at page 17, line 33 ¶ | |||
[RFC6298] Paxson, V., Allman, M., Chu, J., and M. Sargent, | [RFC6298] Paxson, V., Allman, M., Chu, J., and M. Sargent, | |||
"Computing TCP's Retransmission Timer", RFC 6298, | "Computing TCP's Retransmission Timer", RFC 6298, | |||
DOI 10.17487/RFC6298, June 2011, | DOI 10.17487/RFC6298, June 2011, | |||
<http://www.rfc-editor.org/info/rfc6298>. | <http://www.rfc-editor.org/info/rfc6298>. | |||
[RFC6582] Henderson, T., Floyd, S., Gurtov, A., and Y. Nishida, "The | [RFC6582] Henderson, T., Floyd, S., Gurtov, A., and Y. Nishida, "The | |||
NewReno Modification to TCP's Fast Recovery Algorithm", | NewReno Modification to TCP's Fast Recovery Algorithm", | |||
RFC 6582, DOI 10.17487/RFC6582, April 2012, | RFC 6582, DOI 10.17487/RFC6582, April 2012, | |||
<http://www.rfc-editor.org/info/rfc6582>. | <http://www.rfc-editor.org/info/rfc6582>. | |||
[RFC6937] Mathis, M., Dukkipati, N., and Y. Cheng, "Proportional | ||||
Rate Reduction for TCP", RFC 6937, DOI 10.17487/RFC6937, | ||||
May 2013, <http://www.rfc-editor.org/info/rfc6937>. | ||||
Appendix A. Acknowledgments | Appendix A. Acknowledgments | |||
Appendix B. Change Log | Appendix B. Change Log | |||
*RFC Editor's Note:* Please remove this section prior to | *RFC Editor's Note:* Please remove this section prior to | |||
publication of a final version of this document. | publication of a final version of this document. | |||
B.1. Since draft-ietf-quic-recovery-01 | B.1. Since draft-ietf-quic-recovery-02 | |||
o Integrate F-RTO (#544, #409) | ||||
o Add congestion control (#545, #395) | ||||
o Require connection abort if a skipped packet was acknowledged | ||||
(#415) | ||||
o Simplify RTO calculations (#142, #417) | ||||
B.2. Since draft-ietf-quic-recovery-01 | ||||
o Overview added to loss detection | ||||
o Changes initial default RTT to 100ms | o Changes initial default RTT to 100ms | |||
o Added time-based loss detection and fixes early retransmit | o Added time-based loss detection and fixes early retransmit | |||
o Clarified loss recovery for handshake packets | o Clarified loss recovery for handshake packets | |||
o Fixed references and made TCP references informative | o Fixed references and made TCP references informative | |||
B.2. Since draft-ietf-quic-recovery-00: | B.3. Since draft-ietf-quic-recovery-00 | |||
o Improved description of constants and ACK behavior | o Improved description of constants and ACK behavior | |||
B.3. Since draft-iyengar-quic-loss-recovery-01: | B.4. Since draft-iyengar-quic-loss-recovery-01 | |||
o Adopted as base for draft-ietf-quic-recovery. | o Adopted as base for draft-ietf-quic-recovery | |||
o Updated authors/editors list. | o Updated authors/editors list | |||
o Added table of contents. | o Added table of contents | |||
Authors' Addresses | Authors' Addresses | |||
Jana Iyengar (editor) | Jana Iyengar (editor) | |||
Email: jri@google.com | Email: jri@google.com | |||
Ian Swett (editor) | Ian Swett (editor) | |||
End of changes. 59 change blocks. | ||||
126 lines changed or deleted | 309 lines changed or added | |||
This html diff was produced by rfcdiff 1.45. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |