draft-ietf-tcpm-rack-04.txt   draft-ietf-tcpm-rack-05.txt 
TCP Maintenance Working Group Y. Cheng TCP Maintenance Working Group Y. Cheng
Internet-Draft N. Cardwell Internet-Draft N. Cardwell
Intended status: Experimental N. Dukkipati Intended status: Experimental N. Dukkipati
Expires: January 3, 2019 P. Jha Expires: October 28, 2019 P. Jha
Google, Inc Google, Inc
July 2, 2018 April 26, 2019
RACK: a time-based fast loss detection algorithm for TCP RACK: a time-based fast loss detection algorithm for TCP
draft-ietf-tcpm-rack-04 draft-ietf-tcpm-rack-05
Abstract Abstract
This document presents a new TCP loss detection algorithm called RACK This document presents a new TCP loss detection algorithm called RACK
("Recent ACKnowledgment"). RACK uses the notion of time, instead of ("Recent ACKnowledgment"). RACK uses the notion of time, instead of
packet or sequence counts, to detect losses, for modern TCP packet or sequence counts, to detect losses, for modern TCP
implementations that can support per-packet timestamps and the implementations that can support per-packet timestamps and the
selective acknowledgment (SACK) option. It is intended to replace selective acknowledgment (SACK) option. It is intended to replace
the conventional DUPACK threshold approach and its variants, as well the conventional DUPACK threshold approach and its variants, as well
as other nonstandard approaches. as other nonstandard approaches.
skipping to change at page 1, line 38 skipping to change at page 1, line 38
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 https://datatracker.ietf.org/drafts/current/. Drafts is at https://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 January 3, 2019. This Internet-Draft will expire on October 28, 2019.
Copyright Notice Copyright Notice
Copyright (c) 2018 IETF Trust and the persons identified as the Copyright (c) 2019 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
(https://trustee.ietf.org/license-info) in effect on the date of (https://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
carefully, as they describe your rights and restrictions with respect carefully, as they describe your rights and restrictions with respect
to this document. Code Components extracted from this document must to this document. Code Components extracted from this document must
include Simplified BSD License text as described in Section 4.e of include Simplified BSD License text as described in Section 4.e of
the Trust Legal Provisions and are provided without warranty as the Trust Legal Provisions and are provided without warranty as
skipping to change at page 2, line 31 skipping to change at page 2, line 31
1. Lost retransmissions. Traffic policers [POLICER16] and burst 1. Lost retransmissions. Traffic policers [POLICER16] and burst
losses often cause retransmissions to be lost again, severely losses often cause retransmissions to be lost again, severely
increasing TCP latency. increasing TCP latency.
2. Tail drops. Structured request-response traffic turns more 2. Tail drops. Structured request-response traffic turns more
losses into tail drops. In such cases, TCP is application- losses into tail drops. In such cases, TCP is application-
limited, so it cannot send new data to probe losses and has to limited, so it cannot send new data to probe losses and has to
rely on retransmission timeouts (RTOs). rely on retransmission timeouts (RTOs).
3. Reordering. Link layer protocols (e.g., 802.11 block ACK) or 3. Reordering. Link-layer protocols (e.g., 802.11 block ACK), link
routers' internal load-balancing can deliver TCP packets out of bonding, or routers' internal load-balancing can deliver TCP
order. The degree of such reordering is usually within the order packets out of order. The degree of such reordering is usually
of the path round trip time. within the order of the path round trip time.
Despite TCP stacks (e.g. Linux) that implement many of the standard Despite TCP stacks (e.g. Linux) that implement many of the standard
and proposed loss detection algorithms and proposed loss detection algorithms
[RFC4653][RFC5827][RFC5681][RFC6675][RFC7765][FACK][THIN-STREAM], [RFC4653][RFC5827][RFC5681][RFC6675][RFC7765][FACK][THIN-STREAM],
we've found that together they do not perform well. The main reason we've found that together they do not perform well. The main reason
is that many of them are based on the classic rule of counting is that many of them are based on the classic rule of counting
duplicate acknowledgments [RFC5681]. They can either detect loss duplicate acknowledgments [RFC5681]. They can either detect loss
quickly or accurately, but not both, especially when the sender is quickly or accurately, but not both, especially when the sender is
application-limited or under reordering that is unpredictable. And application-limited or under reordering that is unpredictable. And
under these conditions none of them can detect lost retransmissions under these conditions none of them can detect lost retransmissions
skipping to change at page 6, line 35 skipping to change at page 6, line 35
We assume that requirement 1 implies the sender keeps a SACK We assume that requirement 1 implies the sender keeps a SACK
scoreboard, which is a data structure to store selective scoreboard, which is a data structure to store selective
acknowledgment information on a per-connection basis ([RFC6675] acknowledgment information on a per-connection basis ([RFC6675]
section 3). For the ease of explaining the algorithm, we use a section 3). For the ease of explaining the algorithm, we use a
pseudo-scoreboard that manages the data in sequence number ranges. pseudo-scoreboard that manages the data in sequence number ranges.
But the specifics of the data structure are left to the implementor. But the specifics of the data structure are left to the implementor.
RACK does not need any change on the receiver. RACK does not need any change on the receiver.
5. Definitions of variables 5. Definitions
A sender needs to store these new RACK variables: 5.1. Terminology
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in [RFC2119 [1]]. In
this document, these words will appear with that interpretation only
when in UPPER CASE. Lower case uses of these words are not to be
interpreted as carrying [RFC2119 [2]] significance.
The reader is expected to be familiar with the definitions given in
[RFC793], including SND.UNA, SND.NXT, SEG.ACK, and SEG.SEQ.
5.2. Definitions of variables
A sender implementing RACK needs to store these new RACK variables:
"Packet.xmit_ts" is the time of the last transmission of a data "Packet.xmit_ts" is the time of the last transmission of a data
packet, including retransmissions, if any. The sender needs to packet, including retransmissions, if any. The sender needs to
record the transmission time for each packet sent and not yet record the transmission time for each packet sent and not yet
acknowledged. The time MUST be stored at millisecond granularity or acknowledged. The time MUST be stored at millisecond granularity or
finer. finer.
"RACK.packet". Among all the packets that have been either "RACK.packet". Among all the packets that have been either
selectively or cumulatively acknowledged, RACK.packet is the one that selectively or cumulatively acknowledged, RACK.packet is the one that
was sent most recently (including retransmissions). was sent most recently (including retransmissions).
skipping to change at page 7, line 15 skipping to change at page 7, line 33
"RACK.rtt" is the RTT of the most recently transmitted packet that "RACK.rtt" is the RTT of the most recently transmitted packet that
has been delivered (either cumulatively acknowledged or selectively has been delivered (either cumulatively acknowledged or selectively
acknowledged) on the connection. acknowledged) on the connection.
"RACK.rtt_seq" is the SND.NXT when RACK.rtt is updated. "RACK.rtt_seq" is the SND.NXT when RACK.rtt is updated.
"RACK.reo_wnd" is a reordering window computed in the unit of time "RACK.reo_wnd" is a reordering window computed in the unit of time
used for recording packet transmission times. It is used to defer used for recording packet transmission times. It is used to defer
the moment at which RACK marks a packet lost. the moment at which RACK marks a packet lost.
"RACK.dupthresh" is a constant specifying the number of duplicate
acknowledgments, or selectively acknowledged segments, that can
(under certain conditions) trigger fast recovery, similar to
[RFC6675]. As in [RFC5681] and [RFC6675], this threshold is defined
to be 3.
"RACK.min_RTT" is the estimated minimum round-trip time (RTT) of the "RACK.min_RTT" is the estimated minimum round-trip time (RTT) of the
connection. connection.
"RACK.ack_ts" is the time when all the sequences in RACK.packet were "RACK.ack_ts" is the time when all the sequences in RACK.packet were
selectively or cumulatively acknowledged. selectively or cumulatively acknowledged.
"RACK.reo_wnd_incr" is the multiplier applied to adjust RACK.reo_wnd "RACK.reo_wnd_incr" is the multiplier applied to adjust RACK.reo_wnd
"RACK.reo_wnd_persist" is the number of loss recoveries before "RACK.reo_wnd_persist" is the number of loss recoveries before
resetting RACK.reo_wnd "RACK.dsack" indicates if a DSACK option has resetting RACK.reo_wnd
been received since last RACK.reo_wnd change "RACK.pkts_sacked"
returns the total number of packets selectively acknowledged in the "RACK.dsack" indicates if a DSACK option has been received since last
SACK scoreboard. RACK.reo_wnd change "RACK.pkts_sacked" returns the total number of
packets selectively acknowledged in the SACK scoreboard.
"RACK.reord" indicates the connection has detected packet reordering "RACK.reord" indicates the connection has detected packet reordering
event(s) event(s)
"RACK.fack" is the highest selectively or cumulatively acknowledged "RACK.fack" is the highest selectively or cumulatively acknowledged
sequence sequence
Note that the Packet.xmit_ts variable is per packet in flight. The Note that the Packet.xmit_ts variable is per packet in flight. The
RACK.xmit_ts, RACK.end_seq, RACK.rtt, RACK.reo_wnd, and RACK.min_RTT RACK.xmit_ts, RACK.end_seq, RACK.rtt, RACK.reo_wnd, and RACK.min_RTT
variables are kept in the per-connection TCP control block. variables are kept in the per-connection TCP control block.
skipping to change at page 9, line 30 skipping to change at page 10, line 4
Return Return
If rtt < RACK.min_rtt: If rtt < RACK.min_rtt:
Return Return
RACK.rtt = rtt RACK.rtt = rtt
If RACK_sent_after(Packet.xmit_ts, Packet.end_seq If RACK_sent_after(Packet.xmit_ts, Packet.end_seq
RACK.xmit_ts, RACK.end_seq): RACK.xmit_ts, RACK.end_seq):
RACK.xmit_ts = Packet.xmit_ts RACK.xmit_ts = Packet.xmit_ts
Step 3: Detect packet reordering Step 3: Detect packet reordering
To detect reordering, the sender looks for original data packets To detect reordering, the sender looks for original data packets
being delivered out of order in sequence space. The sender tracks being delivered out of order in sequence space. The sender tracks
the highest sequence selectively or cumulatively acknowledged in the the highest sequence selectively or cumulatively acknowledged in the
RACK.fack variable. The name fack stands for the most forward ACK RACK.fack variable. The name fack stands for the most forward ACK
originated from the [FACK] draft. If the ACK selectively or originated from the [FACK] draft. If the ACK selectively or
cumulatively acknowledges an unacknowledged and also never cumulatively acknowledges an unacknowledged and also never
retransmitted sequence below RACK.fack, then the corresponding packet retransmitted sequence below RACK.fack, then the corresponding packet
has been reordered and RACK.reord is set to 1. has been reordered and RACK.reord is set to TRUE.
The heuristic above only detects reordering if the re-ordered packet The heuristic above only detects reordering if the re-ordered packet
has not yet been retransmitted. This is a major drawback because if has not yet been retransmitted. This is a major drawback because if
RACK has a low reordering window and the network is reordering RACK has a low reordering window and the network is reordering
packets, RACK may falsely retransmit frequently. Consequently RACK packets, RACK may falsely retransmit frequently. Consequently RACK
may fail to detect reordering to increase the reordering window, may fail to detect reordering to increase the reordering window,
because the reordered packets were already (falsely) retransmitted. because the reordered packets were already (falsely) retransmitted.
DSACK [RFC3708] can help mitigate this issue. The false DSACK [RFC3708] can help mitigate this issue. The false
retransmission would solicit DSACK option in the ACK. Therefore if retransmission would solicit DSACK option in the ACK. Therefore if
the ACK has a DSACK option covering some sequence that were both the ACK has a DSACK option covering some sequence that were both
acknowledged and retransmitted, this implies the original packet was acknowledged and retransmitted, this implies the original packet was
reordered but RACK retransmitted the packet too quickly and should reordered but RACK retransmitted the packet too quickly and should
set RACK.reord to 1. set RACK.reord to TRUE.
RACK_detect_reordering(): RACK_detect_reordering():
For each Packet newly acknowledged cumulatively or selectively: For each Packet newly acknowledged cumulatively or selectively:
If Packet.end_seq > RACK.fack: If Packet.end_seq > RACK.fack:
RACK.fack = Packet.end_seq RACK.fack = Packet.end_seq
Else if Packet.end_seq < RACK.fack AND Else if Packet.end_seq < RACK.fack AND
Packet.retransmitted is FALSE: Packet.retransmitted is FALSE:
RACK.reord = TRUE RACK.reord = TRUE
For each Packet covered by the DSACK option: For each Packet covered by the DSACK option:
If Packet.retransmitted is TRUE: If Packet.retransmitted is TRUE:
RACK.reord = TRUE RACK.reord = TRUE
Step 4: Update RACK reordering window Step 4: Update RACK reordering window
To handle the prevalent small degree of reordering, RACK.reo_wnd To handle the prevalent small degree of reordering, RACK.reo_wnd
serves as an allowance for settling time before marking a packet serves as an allowance for settling time before marking a packet
lost. This section documents a detailed algorithm following the lost. This section documents a detailed algorithm following the
design rationale section. RACK starts initially with a conservative design rationale section. RACK starts initially with a conservative
skipping to change at page 11, line 23 skipping to change at page 11, line 38
If RACK.dsack: If RACK.dsack:
RACK.reo_wnd_incr += 1 RACK.reo_wnd_incr += 1
RACK.dsack = false RACK.dsack = false
RACK.rtt_seq = SND.NXT RACK.rtt_seq = SND.NXT
RACK.reo_wnd_persist = 16 /* Keep window for 16 recoveries */ RACK.reo_wnd_persist = 16 /* Keep window for 16 recoveries */
Else if exiting loss recovery: Else if exiting loss recovery:
RACK.reo_wnd_persist -= 1 RACK.reo_wnd_persist -= 1
If RACK.reo_wnd_persist <= 0: If RACK.reo_wnd_persist <= 0:
RACK.reo_wnd_incr = 1 RACK.reo_wnd_incr = 1
If RACK.reordering_seen is FALSE: If RACK.reord is FALSE:
If in loss recovery: /* If in fast or timeout recovery */ If in loss recovery: /* If in fast or timeout recovery */
RACK.reo_wnd = 0 RACK.reo_wnd = 0
Return Return
Else if RACK.pkts_sacked >= RACK.dupthresh: Else if RACK.pkts_sacked >= RACK.dupthresh:
RACK.reo_wnd = 0 RACK.reo_wnd = 0
return return
RACK.reo_wnd = RACK.min_RTT / 4 * RACK.reo_wnd_incr RACK.reo_wnd = RACK.min_RTT / 4 * RACK.reo_wnd_incr
RACK.reo_wnd = min(RACK.reo_wnd, SRTT) RACK.reo_wnd = min(RACK.reo_wnd, SRTT)
Step 5: Detect losses. Step 5: Detect losses.
skipping to change at page 12, line 13 skipping to change at page 12, line 28
of the earliest unacked packet in flight. of the earliest unacked packet in flight.
This timer expiration value can be derived as follows. As a starting This timer expiration value can be derived as follows. As a starting
point, we consider that the reordering window has passed if the point, we consider that the reordering window has passed if the
RACK.packet was sent sufficiently after the packet in question, or a RACK.packet was sent sufficiently after the packet in question, or a
sufficient time has elapsed since the RACK.packet was S/ACKed, or sufficient time has elapsed since the RACK.packet was S/ACKed, or
some combination of the two. More precisely, RACK marks a packet as some combination of the two. More precisely, RACK marks a packet as
lost if the reordering window for a packet has elapsed through the lost if the reordering window for a packet has elapsed through the
sum of: sum of:
1. delta in transmit time between a packet and the RACK.packet 1. delta in transmit time between a packet and the RACK.packet
2. delta in time between RACK.ack_ts and now 2. delta in time between RACK.ack_ts and now
So we mark a packet as lost if: So we mark a packet as lost if:
RACK.xmit_ts >= Packet.xmit_ts RACK.xmit_ts >= Packet.xmit_ts
AND AND
(RACK.xmit_ts - Packet.xmit_ts) + (now - RACK.ack_ts) >= RACK.reo_wnd (RACK.xmit_ts - Packet.xmit_ts) + (now - RACK.ack_ts) >= RACK.reo_wnd
If we solve this second condition for "now", the moment at which we If we solve this second condition for "now", the moment at which we
can declare a packet lost, then we get: can declare a packet lost, then we get:
now >= Packet.xmit_ts + RACK.reo_wnd + (RACK.ack_ts - RACK.xmit_ts) now >= Packet.xmit_ts + RACK.reo_wnd + (RACK.ack_ts - RACK.xmit_ts)
Then (RACK.ack_ts - RACK.xmit_ts) is just the RTT of the packet we Then (RACK.ack_ts - RACK.xmit_ts) is just the RTT of the packet we
used to set RACK.xmit_ts, so this reduces to: used to set RACK.xmit_ts, so this reduces to:
Packet.xmit_ts + RACK.rtt + RACK.reo_wnd - now <= 0 Packet.xmit_ts + RACK.rtt + RACK.reo_wnd - now <= 0
The following pseudocode implements the algorithm above. When an ACK The following pseudocode implements the algorithm above. When an ACK
is received or the RACK timer expires, call RACK_detect_loss(). The is received or the RACK timer expires, call RACK_detect_loss(). The
algorithm includes an additional optimization to break timestamp ties algorithm includes an additional optimization to break timestamp ties
by using the TCP sequence space. The optimization is particularly by using the TCP sequence space. The optimization is particularly
useful to detect losses in a timely manner with TCP Segmentation useful to detect losses in a timely manner with TCP Segmentation
Offload, where multiple packets in one TSO blob have identical Offload, where multiple packets in one TSO blob have identical
timestamps. It is also useful when the timestamp clock granularity timestamps. It is also useful when the timestamp clock granularity
is close to or longer than the actual round trip time. is close to or longer than the actual round trip time.
RACK_detect_loss(): RACK_detect_loss():
timeout = 0 timeout = 0
For each packet, Packet, not acknowledged yet: For each packet, Packet, not acknowledged yet:
If Packet.lost is TRUE or Packet.retransmitted is FALSE: If Packet.lost is TRUE AND Packet.retransmitted is FALSE:
Continue /* Lost packet not retransmitted yet */ Continue /* Packet lost but not yet retransmitted */
If RACK_sent_after(RACK.xmit_ts, RACK.end_seq, If RACK_sent_after(RACK.xmit_ts, RACK.end_seq,
Packet.xmit_ts, Packet.end_seq): Packet.xmit_ts, Packet.end_seq):
remaining = Packet.xmit_ts + RACK.rtt + RACK.reo_wnd - Now() remaining = Packet.xmit_ts + RACK.rtt +
If remaining <= 0: RACK.reo_wnd - Now()
Packet.lost = TRUE If remaining <= 0:
Else: Packet.lost = TRUE
timeout = max(remaining, timeout) Else:
timeout = max(remaining, timeout)
If timeout != 0 If timeout != 0
Arm a timer to call RACK_detect_loss() after timeout Arm a timer to call RACK_detect_loss() after timeout
Implementation optimization: looping through packets in the SACK Implementation optimization: looping through packets in the SACK
scoreboard above could be very costly on large-BDP networks since the scoreboard above could be very costly on large-BDP networks since the
inflight could be very large. If the implementation can organize the inflight could be very large. If the implementation can organize the
scoreboard data structures to have packets sorted by the last scoreboard data structures to have packets sorted by the last
(re)transmission time, then the loop can start on the least recently (re)transmission time, then the loop can start on the least recently
sent packet and abort on the first packet sent after RACK.time_ts. sent packet and abort on the first packet sent after RACK.time_ts.
This can be implemented by using a seperate list sorted in time This can be implemented by using a seperate list sorted in time
order. The implementation inserts the packet at the tail of the list order. The implementation inserts the packet at the tail of the list
when it is (re)transmitted, and removes a packet from the list when when it is (re)transmitted, and removes a packet from the list when
skipping to change at page 17, line 38 skipping to change at page 17, line 42
there is only one original outstanding segment of data (N=1), the there is only one original outstanding segment of data (N=1), the
same logic (trivially) applies: an ACK for a single outstanding same logic (trivially) applies: an ACK for a single outstanding
segment tells the sender the N-1=0 segments preceding that segment segment tells the sender the N-1=0 segments preceding that segment
were lost. Furthermore, whether there are N>1 or N=1 outstanding were lost. Furthermore, whether there are N>1 or N=1 outstanding
segments, there is a question about whether the original last segment segments, there is a question about whether the original last segment
or its TLP retransmission were lost; the sender estimates this using or its TLP retransmission were lost; the sender estimates this using
TLP recovery detection (see below). TLP recovery detection (see below).
Note that after transmitting a TLP, the sender MUST arm an RTO timer, Note that after transmitting a TLP, the sender MUST arm an RTO timer,
and not the PTO timer. This ensures that the sender does not send and not the PTO timer. This ensures that the sender does not send
repeated, back-to-back TLP probes. repeated, back-to-back TLP probes. This is important to avoid TLP
loops if an application writes periodically at an interval less than
PTO.
6.5.3. Phase 3: ACK processing 6.5.3. Phase 3: ACK processing
On each incoming ACK, the sender should check the conditions in Step On each incoming ACK, the sender should check the conditions in Step
1 of Phase 1 to see if it should schedule (or reschedule) the loss 1 of Phase 1 to see if it should schedule (or reschedule) the loss
probe timer. probe timer.
6.6. TLP recovery detection 6.6. TLP recovery detection
If the only loss in an outstanding window of data was the last If the only loss in an outstanding window of data was the last
skipping to change at page 19, line 44 skipping to change at page 19, line 50
2. This is an ACK acknowledging a sequence number at or above 2. This is an ACK acknowledging a sequence number at or above
TLPHighRxt and it contains a D-SACK; i.e. all of the following TLPHighRxt and it contains a D-SACK; i.e. all of the following
conditions are met: conditions are met:
1. TLPRxtOut is true 1. TLPRxtOut is true
2. SEG.ACK >= TLPHighRxt 2. SEG.ACK >= TLPHighRxt
3. the ACK contains a D-SACK block 3. the ACK contains a D-SACK block
If neither conditions are met, then the sender estimates that the If either of the conditions is met, then the sender estimates that
receiver received both the original data segment and the TLP probe the receiver received both the original data segment and the TLP
retransmission, and so the sender considers the TLP episode to be probe retransmission, and so the sender considers the TLP episode to
done, and records that fact by setting TLPRxtOut to false. be done, and records that fact by setting TLPRxtOut to false.
Step 2: Mark the end of a TLP retransmission episode and detect Step 2: Mark the end of a TLP retransmission episode and detect
losses losses
If the sender receives a cumulative ACK for data beyond the TLP loss If the sender receives a cumulative ACK for data beyond the TLP loss
probe retransmission then, in the absence of reordering on the return probe retransmission then, in the absence of reordering on the return
path of ACKs, it should have received any ACKs for the original path of ACKs, it should have received any ACKs for the original
segment and TLP probe retransmission segment. At that time, if the segment and TLP probe retransmission segment. At that time, if the
TLPRxtOut flag is still true and thus indicates that the TLP probe TLPRxtOut flag is still true and thus indicates that the TLP probe
retransmission remains unacknowledged, then the sender should presume retransmission remains unacknowledged, then the sender should presume
that at least one of its data segments was lost, so it SHOULD invoke that at least one of its data segments was lost, so it SHOULD invoke
a congestion control response equivalent to fast recovery. a congestion control response equivalent to fast recovery.
More precisely, on each ACK the sender executes the following: More precisely, on each ACK the sender executes the following:
skipping to change at page 26, line 37 skipping to change at page 26, line 45
Note to RFC Editor: this section may be removed on publication as an Note to RFC Editor: this section may be removed on publication as an
RFC. RFC.
11. Acknowledgments 11. Acknowledgments
The authors thank Matt Mathis for his insights in FACK and Michael The authors thank Matt Mathis for his insights in FACK and Michael
Welzl for his per-packet timer idea that inspired this work. Eric Welzl for his per-packet timer idea that inspired this work. Eric
Dumazet, Randy Stewart, Van Jacobson, Ian Swett, Rick Jones, Jana Dumazet, Randy Stewart, Van Jacobson, Ian Swett, Rick Jones, Jana
Iyengar, Hiren Panchasara, Praveen Balasubramanian, Yoshifumi Iyengar, Hiren Panchasara, Praveen Balasubramanian, Yoshifumi
Nishida, and Bob Briscoe contributed to the draft and the Nishida, Bob Briscoe, Felix Weinrank, and Michael Tuexen contributed
implementations in Linux, FreeBSD and QUIC. to the draft or the implementations in Linux, FreeBSD, Windows and
QUIC.
12. References 12. References
12.1. Normative References 12.1. Normative References
[RFC2018] Mathis, M. and J. Mahdavi, "TCP Selective Acknowledgment [RFC2018] Mathis, M. and J. Mahdavi, "TCP Selective Acknowledgment
Options", RFC 2018, October 1996. Options", RFC 2018, October 1996.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", RFC 2119, March 1997. Requirement Levels", RFC 2119, March 1997.
skipping to change at page 28, line 26 skipping to change at page 28, line 39
[THIN-STREAM] [THIN-STREAM]
Petlund, A., Evensen, K., Griwodz, C., and P. Halvorsen, Petlund, A., Evensen, K., Griwodz, C., and P. Halvorsen,
"TCP enhancements for interactive thin-stream "TCP enhancements for interactive thin-stream
applications", NOSSDAV , 2008. applications", NOSSDAV , 2008.
[TLP] Dukkipati, N., Cardwell, N., Cheng, Y., and M. Mathis, [TLP] 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 Drops", draft-dukkipati-tcpm-tcp-loss-probe-01 (work Tail Drops", draft-dukkipati-tcpm-tcp-loss-probe-01 (work
in progress), August 2013. in progress), August 2013.
Authors' Addresses 12.3. URIs
[1] https://tools.ietf.org/html/rfc2119
[2] https://tools.ietf.org/html/rfc2119
Authors' Addresses
Yuchung Cheng Yuchung Cheng
Google, Inc Google, Inc
1600 Amphitheater Parkway 1600 Amphitheater Parkway
Mountain View, California 94043 Mountain View, California 94043
USA USA
Email: ycheng@google.com Email: ycheng@google.com
Neal Cardwell Neal Cardwell
Google, Inc Google, Inc
 End of changes. 28 change blocks. 
46 lines changed or deleted 77 lines changed or added

This html diff was produced by rfcdiff 1.47. The latest version is available from http://tools.ietf.org/tools/rfcdiff/