idnits 2.17.1 draft-ietf-quic-recovery-08.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack a Security Considerations section. ** The abstract seems to contain references ([2], [3], [1]), which it shouldn't. Please replace those with straight textual mentions of the documents in question. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (December 5, 2017) is 2334 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Looks like a reference, but probably isn't: '1' on line 1112 -- Looks like a reference, but probably isn't: '2' on line 1114 -- Looks like a reference, but probably isn't: '3' on line 1116 == Outdated reference: A later version (-34) exists of draft-ietf-quic-transport-00 ** Downref: Normative reference to an Experimental RFC: RFC 4653 ** Downref: Normative reference to an Experimental RFC: RFC 5827 -- Duplicate reference: draft-dukkipati-tcpm-tcp-loss-probe, mentioned in 'TLP', was also mentioned in 'LOSS-PROBE'. Summary: 4 errors (**), 0 flaws (~~), 2 warnings (==), 5 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 QUIC J. Iyengar, Ed. 3 Internet-Draft I. Swett, Ed. 4 Intended status: Standards Track Google 5 Expires: June 8, 2018 December 5, 2017 7 QUIC Loss Detection and Congestion Control 8 draft-ietf-quic-recovery-08 10 Abstract 12 This document describes loss detection and congestion control 13 mechanisms for QUIC. 15 Note to Readers 17 Discussion of this draft takes place on the QUIC working group 18 mailing list (quic@ietf.org), which is archived at 19 https://mailarchive.ietf.org/arch/search/?email_list=quic [1]. 21 Working Group information can be found at https://github.com/quicwg 22 [2]; source code and issues list for this draft can be found at 23 https://github.com/quicwg/base-drafts/labels/-recovery [3]. 25 Status of This Memo 27 This Internet-Draft is submitted in full conformance with the 28 provisions of BCP 78 and BCP 79. 30 Internet-Drafts are working documents of the Internet Engineering 31 Task Force (IETF). Note that other groups may also distribute 32 working documents as Internet-Drafts. The list of current Internet- 33 Drafts is at https://datatracker.ietf.org/drafts/current/. 35 Internet-Drafts are draft documents valid for a maximum of six months 36 and may be updated, replaced, or obsoleted by other documents at any 37 time. It is inappropriate to use Internet-Drafts as reference 38 material or to cite them other than as "work in progress." 40 This Internet-Draft will expire on June 8, 2018. 42 Copyright Notice 44 Copyright (c) 2017 IETF Trust and the persons identified as the 45 document authors. All rights reserved. 47 This document is subject to BCP 78 and the IETF Trust's Legal 48 Provisions Relating to IETF Documents 49 (https://trustee.ietf.org/license-info) in effect on the date of 50 publication of this document. Please review these documents 51 carefully, as they describe your rights and restrictions with respect 52 to this document. Code Components extracted from this document must 53 include Simplified BSD License text as described in Section 4.e of 54 the Trust Legal Provisions and are provided without warranty as 55 described in the Simplified BSD License. 57 Table of Contents 59 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 60 1.1. Notational Conventions . . . . . . . . . . . . . . . . . 3 61 2. Design of the QUIC Transmission Machinery . . . . . . . . . . 4 62 2.1. Relevant Differences Between QUIC and TCP . . . . . . . . 4 63 2.1.1. Monotonically Increasing Packet Numbers . . . . . . . 4 64 2.1.2. No Reneging . . . . . . . . . . . . . . . . . . . . . 5 65 2.1.3. More ACK Ranges . . . . . . . . . . . . . . . . . . . 5 66 2.1.4. Explicit Correction For Delayed Acks . . . . . . . . 5 67 3. Loss Detection . . . . . . . . . . . . . . . . . . . . . . . 5 68 3.1. Computing the RTT estimate . . . . . . . . . . . . . . . 6 69 3.2. Ack-based Detection . . . . . . . . . . . . . . . . . . . 6 70 3.2.1. Fast Retransmit . . . . . . . . . . . . . . . . . . . 6 71 3.2.2. Early Retransmit . . . . . . . . . . . . . . . . . . 7 72 3.3. Timer-based Detection . . . . . . . . . . . . . . . . . . 8 73 3.3.1. Tail Loss Probe . . . . . . . . . . . . . . . . . . . 8 74 3.3.2. Retransmission Timeout . . . . . . . . . . . . . . . 9 75 3.3.3. Handshake Timeout . . . . . . . . . . . . . . . . . . 10 76 3.4. Pseudocode . . . . . . . . . . . . . . . . . . . . . . . 11 77 3.4.1. Constants of interest . . . . . . . . . . . . . . . . 11 78 3.4.2. Variables of interest . . . . . . . . . . . . . . . . 12 79 3.4.3. Initialization . . . . . . . . . . . . . . . . . . . 13 80 3.4.4. On Sending a Packet . . . . . . . . . . . . . . . . . 13 81 3.4.5. On Ack Receipt . . . . . . . . . . . . . . . . . . . 14 82 3.4.6. On Packet Acknowledgment . . . . . . . . . . . . . . 15 83 3.4.7. Setting the Loss Detection Alarm . . . . . . . . . . 16 84 3.4.8. On Alarm Firing . . . . . . . . . . . . . . . . . . . 17 85 3.4.9. Detecting Lost Packets . . . . . . . . . . . . . . . 18 86 3.5. Discussion . . . . . . . . . . . . . . . . . . . . . . . 19 87 4. Congestion Control . . . . . . . . . . . . . . . . . . . . . 19 88 4.1. Slow Start . . . . . . . . . . . . . . . . . . . . . . . 20 89 4.2. Congestion Avoidance . . . . . . . . . . . . . . . . . . 20 90 4.3. Recovery Period . . . . . . . . . . . . . . . . . . . . . 20 91 4.4. Tail Loss Probe . . . . . . . . . . . . . . . . . . . . . 20 92 4.5. Retransmission Timeout . . . . . . . . . . . . . . . . . 20 93 4.6. Pacing Rate . . . . . . . . . . . . . . . . . . . . . . . 21 94 4.7. Pseudocode . . . . . . . . . . . . . . . . . . . . . . . 21 95 4.7.1. Constants of interest . . . . . . . . . . . . . . . . 21 96 4.7.2. Variables of interest . . . . . . . . . . . . . . . . 21 97 4.7.3. Initialization . . . . . . . . . . . . . . . . . . . 22 98 4.7.4. On Packet Sent . . . . . . . . . . . . . . . . . . . 22 99 4.7.5. On Packet Acknowledgement . . . . . . . . . . . . . . 22 100 4.7.6. On Packets Lost . . . . . . . . . . . . . . . . . . . 23 101 4.7.7. On Retransmission Timeout Verified . . . . . . . . . 23 102 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 23 103 6. References . . . . . . . . . . . . . . . . . . . . . . . . . 23 104 6.1. Normative References . . . . . . . . . . . . . . . . . . 23 105 6.2. Informative References . . . . . . . . . . . . . . . . . 24 106 6.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 25 107 Appendix A. Acknowledgments . . . . . . . . . . . . . . . . . . 25 108 Appendix B. Change Log . . . . . . . . . . . . . . . . . . . . . 25 109 B.1. Since draft-ietf-quic-recovery-06 . . . . . . . . . . . . 25 110 B.2. Since draft-ietf-quic-recovery-05 . . . . . . . . . . . . 25 111 B.3. Since draft-ietf-quic-recovery-04 . . . . . . . . . . . . 25 112 B.4. Since draft-ietf-quic-recovery-03 . . . . . . . . . . . . 25 113 B.5. Since draft-ietf-quic-recovery-02 . . . . . . . . . . . . 25 114 B.6. Since draft-ietf-quic-recovery-01 . . . . . . . . . . . . 26 115 B.7. Since draft-ietf-quic-recovery-00 . . . . . . . . . . . . 26 116 B.8. Since draft-iyengar-quic-loss-recovery-01 . . . . . . . . 26 117 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 26 119 1. Introduction 121 QUIC is a new multiplexed and secure transport atop UDP. QUIC builds 122 on decades of transport and security experience, and implements 123 mechanisms that make it attractive as a modern general-purpose 124 transport. The QUIC protocol is described in [QUIC-TRANSPORT]. 126 QUIC implements the spirit of known TCP loss recovery mechanisms, 127 described in RFCs, various Internet-drafts, and also those prevalent 128 in the Linux TCP implementation. This document describes QUIC 129 congestion control and loss recovery, and where applicable, 130 attributes the TCP equivalent in RFCs, Internet-drafts, academic 131 papers, and/or TCP implementations. 133 1.1. Notational Conventions 135 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 136 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 137 "OPTIONAL" in this document are to be interpreted as described in BCP 138 14 [RFC2119] [RFC8174] when, and only when, they appear in all 139 capitals, as shown here. 141 2. Design of the QUIC Transmission Machinery 143 All transmissions in QUIC are sent with a packet-level header, which 144 includes a packet sequence number (referred to below as a packet 145 number). These packet numbers never repeat in the lifetime of a 146 connection, and are monotonically increasing, which prevents 147 ambiguity. This fundamental design decision obviates the need for 148 disambiguating between transmissions and retransmissions and 149 eliminates significant complexity from QUIC's interpretation of TCP 150 loss detection mechanisms. 152 Every packet may contain several frames. We outline the frames that 153 are important to the loss detection and congestion control machinery 154 below. 156 o Retransmittable frames are frames requiring reliable delivery. 157 The most common are STREAM frames, which typically contain 158 application data. 160 o Crypto handshake data is sent on stream 0, and uses the 161 reliability machinery of QUIC underneath. 163 o ACK frames contain acknowledgment information. ACK frames contain 164 one or more ranges of acknowledged packets. 166 2.1. Relevant Differences Between QUIC and TCP 168 Readers familiar with TCP's loss detection and congestion control 169 will find algorithms here that parallel well-known TCP ones. 170 Protocol differences between QUIC and TCP however contribute to 171 algorithmic differences. We briefly describe these protocol 172 differences below. 174 2.1.1. Monotonically Increasing Packet Numbers 176 TCP conflates transmission sequence number at the sender with 177 delivery sequence number at the receiver, which results in 178 retransmissions of the same data carrying the same sequence number, 179 and consequently to problems caused by "retransmission ambiguity". 180 QUIC separates the two: QUIC uses a packet number for transmissions, 181 and any data that is to be delivered to the receiving application(s) 182 is sent in one or more streams, with delivery order determined by 183 stream offsets encoded within STREAM frames. 185 QUIC's packet number is strictly increasing, and directly encodes 186 transmission order. A higher QUIC packet number signifies that the 187 packet was sent later, and a lower QUIC packet number signifies that 188 the packet was sent earlier. When a packet containing frames is 189 deemed lost, QUIC rebundles necessary frames in a new packet with a 190 new packet number, removing ambiguity about which packet is 191 acknowledged when an ACK is received. Consequently, more accurate 192 RTT measurements can be made, spurious retransmissions are trivially 193 detected, and mechanisms such as Fast Retransmit can be applied 194 universally, based only on packet number. 196 This design point significantly simplifies loss detection mechanisms 197 for QUIC. Most TCP mechanisms implicitly attempt to infer 198 transmission ordering based on TCP sequence numbers - a non-trivial 199 task, especially when TCP timestamps are not available. 201 2.1.2. No Reneging 203 QUIC ACKs contain information that is similar to TCP SACK, but QUIC 204 does not allow any acked packet to be reneged, greatly simplifying 205 implementations on both sides and reducing memory pressure on the 206 sender. 208 2.1.3. More ACK Ranges 210 QUIC supports many ACK ranges, opposed to TCP's 3 SACK ranges. In 211 high loss environments, this speeds recovery, reduces spurious 212 retransmits, and ensures forward progress without relying on 213 timeouts. 215 2.1.4. Explicit Correction For Delayed Acks 217 QUIC ACKs explicitly encode the delay incurred at the receiver 218 between when a packet is received and when the corresponding ACK is 219 sent. This allows the receiver of the ACK to adjust for receiver 220 delays, specifically the delayed ack timer, when estimating the path 221 RTT. This mechanism also allows a receiver to measure and report the 222 delay from when a packet was received by the OS kernel, which is 223 useful in receivers which may incur delays such as context-switch 224 latency before a userspace QUIC receiver processes a received packet. 226 3. Loss Detection 228 QUIC senders use both ack information and timeouts to detect lost 229 packets, and this section provides a description of these algorithms. 230 Estimating the network round-trip time (RTT) is critical to these 231 algorithms and is described first. 233 3.1. Computing the RTT estimate 235 RTT is calculated when an ACK frame arrives by computing the 236 difference between the current time and the time the largest newly 237 acked packet was sent. If no packets are newly acknowledged, RTT 238 cannot be calculated. When RTT is calculated, the ack delay field 239 from the ACK frame SHOULD be subtracted from the RTT as long as the 240 result is larger than the Min RTT. If the result is smaller than the 241 min_rtt, the RTT should be used, but the ack delay field should be 242 ignored. 244 Like TCP, QUIC calculates both smoothed RTT and RTT variance as 245 specified in [RFC6298]. 247 Min RTT is the minimum RTT measured over the connection, prior to 248 adjusting by ack delay. Ignoring ack delay for min RTT prevents 249 intentional or unintentional underestimation of min RTT, which in 250 turn prevents underestimating smoothed RTT. 252 3.2. Ack-based Detection 254 Ack-based loss detection implements the spirit of TCP's Fast 255 Retransmit [RFC5681], Early Retransmit [RFC5827], FACK, and SACK loss 256 recovery [RFC6675]. This section provides an overview of how these 257 algorithms are implemented in QUIC. 259 (TODO: Define unacknowledged packet, ackable packet, outstanding 260 bytes.) 262 3.2.1. Fast Retransmit 264 An unacknowledged packet is marked as lost when an acknowledgment is 265 received for a packet that was sent a threshold number of packets 266 (kReorderingThreshold) after the unacknowledged packet. Receipt of 267 the ack indicates that a later packet was received, while 268 kReorderingThreshold provides some tolerance for reordering of 269 packets in the network. 271 The RECOMMENDED initial value for kReorderingThreshold is 3. 273 We derive this default from recommendations for TCP loss recovery 274 [RFC5681] [RFC6675]. It is possible for networks to exhibit higher 275 degrees of reordering, causing a sender to detect spurious losses. 276 Detecting spurious losses leads to unnecessary retransmissions and 277 may result in degraded performance due to the actions of the 278 congestion controller upon detecting loss. Implementers MAY use 279 algorithms developed for TCP, such as TCP-NCR [RFC4653], to improve 280 QUIC's reordering resilience, though care should be taken to map TCP 281 specifics to QUIC correctly. Similarly, using time-based loss 282 detection to deal with reordering, such as in PR-TCP, should be more 283 readily usable in QUIC. Making QUIC deal with such networks is 284 important open research, and implementers are encouraged to explore 285 this space. 287 3.2.2. Early Retransmit 289 Unacknowledged packets close to the tail may have fewer than 290 kReorderingThreshold number of ackable packets sent after them. Loss 291 of such packets cannot be detected via Fast Retransmit. To enable 292 ack-based loss detection of such packets, receipt of an 293 acknowledgment for the last outstanding ackable packet triggers the 294 Early Retransmit process, as follows. 296 If there are unacknowledged ackable packets still pending, they ought 297 to be marked as lost. To compensate for the reduced reordering 298 resilience, the sender SHOULD set an alarm for a small period of 299 time. If the unacknowledged ackable packets are not acknowledged 300 during this time, then these packets MUST be marked as lost. 302 An endpoint SHOULD set the alarm such that a packet is marked as lost 303 no earlier than 1.25 * max(SRTT, latest_RTT) since when it was sent. 305 Using max(SRTT, latest_RTT) protects from the two following cases: 307 o the latest RTT sample is lower than the SRTT, perhaps due to 308 reordering where packet whose ack triggered the Early Retransit 309 process encountered a shorter path; 311 o the latest RTT sample is higher than the SRTT, perhaps due to a 312 sustained increase in the actual RTT, but the smoothed SRTT has 313 not yet caught up. 315 The 1.25 multiplier increases reordering resilience. Implementers 316 MAY experiment with using other multipliers, bearing in mind that a 317 lower multiplier reduces reordering resilience and increases spurious 318 retransmissions, and a higher multipler increases loss recovery 319 delay. 321 This mechanism is based on Early Retransmit for TCP [RFC5827]. 322 However, [RFC5827] does not include the alarm described above. Early 323 Retransmit is prone to spurious retransmissions due to its reduced 324 reordering resilence without the alarm. This observation led Linux 325 TCP implementers to implement an alarm for TCP as well, and this 326 document incorporates this advancement. 328 3.3. Timer-based Detection 330 Timer-based loss detection implements the spirit of TCP's Tail Loss 331 Probe and Retransmission Timeout mechanisms. 333 3.3.1. Tail Loss Probe 335 The algorithm described in this section is an adaptation of the Tail 336 Loss Probe algorithm proposed for TCP [TLP]. 338 A packet sent at the tail is particularly vulnerable to slow loss 339 detection, since acks of subsequent packets are needed to trigger 340 ack-based detection. To ameliorate this weakness of tail packets, 341 the sender schedules an alarm when the last ackable packet before 342 quiescence is transmitted. When this alarm fires, a Tail Loss Probe 343 (TLP) packet is sent to evoke an acknowledgement from the receiver. 345 The alarm duration, or Probe Timeout (PTO), is set based on the 346 following conditions: 348 o PTO SHOULD be scheduled for max(1.5*SRTT+MaxAckDelay, 10ms) 350 o If RTO (Section 3.3.2) is earlier, schedule a TLP alarm in its 351 place. That is, PTO SHOULD be scheduled for min(RTO, PTO). 353 MaxAckDelay is the maximum ack delay supplied in an incoming ACK 354 frame. MaxAckDelay excludes ack delays that aren't included in an 355 RTT sample because they're too large and excludes those which 356 reference an ack-only packet. 358 QUIC diverges from TCP by calculating MaxAckDelay dynamically, 359 instead of assuming a constant delayed ack timeout for all 360 connections. QUIC includes this in all probe timeouts, because it 361 assume the ack delay may come into play, regardless of the number of 362 packets outstanding. TCP's TLP assumes if at least 2 packets are 363 outstanding, acks will not be delayed. 365 A PTO value of at least 1.5*SRTT ensures that the ACK is overdue. 366 The 1.5 is based on [LOSS-PROBE], but implementations MAY experiment 367 with other constants. 369 To reduce latency, it is RECOMMENDED that the sender set and allow 370 the TLP alarm to fire twice before setting an RTO alarm. In other 371 words, when the TLP alarm fires the first time, a TLP packet is sent, 372 and it is RECOMMENDED that the TLP alarm be scheduled for a second 373 time. When the TLP alarm fires the second time, a second TLP packet 374 is sent, and an RTO alarm SHOULD be scheduled Section 3.3.2. 376 A TLP packet SHOULD carry new data when possible. If new data is 377 unavailable or new data cannot be sent due to flow control, a TLP 378 packet MAY retransmit unacknowledged data to potentially reduce 379 recovery time. Since a TLP alarm is used to send a probe into the 380 network prior to establishing any packet loss, prior unacknowledged 381 packets SHOULD NOT be marked as lost when a TLP alarm fires. 383 A TLP packet MUST NOT be blocked by the sender's congestion 384 controller. The sender MUST however count these bytes as additional 385 bytes in flight, since a TLP adds network load without establishing 386 packet loss. 388 A sender may not know that a packet being sent is a tail packet. 389 Consequently, a sender may have to arm or adjust the TLP alarm on 390 every sent ackable packet. 392 3.3.2. Retransmission Timeout 394 A Retransmission Timeout (RTO) alarm is the final backstop for loss 395 detection. The algorithm used in QUIC is based on the RTO algorithm 396 for TCP [RFC5681] and is additionally resilient to spurious RTO 397 events [RFC5682]. 399 When the last TLP packet is sent, an alarm is scheduled for the RTO 400 period. When this alarm fires, the sender sends two packets, to 401 evoke acknowledgements from the receiver, and restarts the RTO alarm. 403 Similar to TCP [RFC6298], the RTO period is set based on the 404 following conditions: 406 o When the final TLP packet is sent, the RTO period is set to 407 max(SRTT + 4*RTTVAR + MaxAckDelay, minRTO) 409 o When an RTO alarm fires, the RTO period is doubled. 411 The sender typically has incurred a high latency penalty by the time 412 an RTO alarm fires, and this penalty increases exponentially in 413 subsequent consecutive RTO events. Sending a single packet on an RTO 414 event therefore makes the connection very sensitive to single packet 415 loss. Sending two packets instead of one significantly increases 416 resilience to packet drop in both directions, thus reducing the 417 probability of consecutive RTO events. 419 QUIC's RTO algorithm differs from TCP in that the firing of an RTO 420 alarm is not considered a strong enough signal of packet loss, so 421 does not result in an immediate change to congestion window or 422 recovery state. An RTO alarm fires only when there's a prolonged 423 period of network silence, which could be caused by a change in the 424 underlying network RTT. 426 QUIC also diverges from TCP by including MaxAckDelay in the RTO 427 period. QUIC is able to explicitly model delay at the receiver via 428 the ack delay field in the ACK frame. Since QUIC corrects for this 429 delay in its SRTT and RTTVAR computations, it is necessary to add 430 this delay explicitly in the TLP and RTO computation. 432 When an acknowledgment is received for a packet sent on an RTO event, 433 any unacknowledged packets with lower packet numbers than those 434 acknowledged MUST be marked as lost. 436 A packet sent when an RTO alarm fires MAY carry new data if available 437 or unacknowledged data to potentially reduce recovery time. Since 438 this packet is sent as a probe into the network prior to establishing 439 any packet loss, prior unacknowledged packets SHOULD NOT be marked as 440 lost. 442 A packet sent on an RTO alarm MUST NOT be blocked by the sender's 443 congestion controller. A sender MUST however count these bytes as 444 additional bytes in flight, since this packet adds network load 445 without establishing packet loss. 447 3.3.3. Handshake Timeout 449 Handshake packets, which contain STREAM frames for stream 0, are 450 critical to QUIC transport and crypto negotiation, so a separate 451 alarm is used for them. 453 The initial handshake timeout SHOULD be set to twice the initial RTT. 455 At the beginning, there are no prior RTT samples within a connection. 456 Resumed connections over the same network SHOULD use the previous 457 connection's final smoothed RTT value as the resumed connection's 458 initial RTT. 460 If no previous RTT is available, or if the network changes, the 461 initial RTT SHOULD be set to 100ms. 463 When the first handshake packet is sent, the sender SHOULD set an 464 alarm for the handshake timeout period. 466 When the alarm fires, the sender MUST retransmit all unacknowledged 467 handshake data. On each consecutive firing of the handshake alarm, 468 the sender SHOULD double the handshake timeout and set an alarm for 469 this period. 471 When an acknowledgement is received for a handshake packet, the new 472 RTT is computed and the alarm SHOULD be set for twice the newly 473 computed smoothed RTT. 475 Handshake data may be cancelled by handshake state transitions. In 476 particular, all non-protected data SHOULD no longer be transmitted 477 once packet protection is available. 479 (TODO: Work this section some more. Add text on client vs. server, 480 and on stateless retry.) 482 3.4. Pseudocode 484 3.4.1. Constants of interest 486 Constants used in loss recovery are based on a combination of RFCs, 487 papers, and common practice. Some may need to be changed or 488 negotiated in order to better suit a variety of environments. 490 kMaxTLPs (default 2): Maximum number of tail loss probes before an 491 RTO fires. 493 kReorderingThreshold (default 3): Maximum reordering in packet 494 number space before FACK style loss detection considers a packet 495 lost. 497 kTimeReorderingFraction (default 1/8): Maximum reordering in time 498 space before time based loss detection considers a packet lost. 499 In fraction of an RTT. 501 kUsingTimeLossDetection (default false): Whether time based loss 502 detection is in use. If false, uses FACK style loss detection. 504 kMinTLPTimeout (default 10ms): Minimum time in the future a tail 505 loss probe alarm may be set for. 507 kMinRTOTimeout (default 200ms): Minimum time in the future an RTO 508 alarm may be set for. 510 kDelayedAckTimeout (default 25ms): The length of the peer's delayed 511 ack timer. 513 kDefaultInitialRtt (default 100ms): The default RTT used before an 514 RTT sample is taken. 516 3.4.2. Variables of interest 518 Variables required to implement the congestion control mechanisms are 519 described in this section. 521 loss_detection_alarm: Multi-modal alarm used for loss detection. 523 handshake_count: The number of times the handshake packets have been 524 retransmitted without receiving an ack. 526 tlp_count: The number of times a tail loss probe has been sent 527 without receiving an ack. 529 rto_count: The number of times an rto has been sent without 530 receiving an ack. 532 largest_sent_before_rto: The last packet number sent prior to the 533 first retransmission timeout. 535 time_of_last_sent_packet: The time the most recent packet was sent. 537 largest_sent_packet: The packet number of the most recently sent 538 packet. 540 largest_acked_packet: The largest packet number acknowledged in an 541 ACK frame. 543 latest_rtt: The most recent RTT measurement made when receiving an 544 ack for a previously unacked packet. 546 smoothed_rtt: The smoothed RTT of the connection, computed as 547 described in [RFC6298] 549 rttvar: The RTT variance, computed as described in [RFC6298] 551 min_rtt: The minimum RTT seen in the connection, ignoring ack delay. 553 max_ack_delay: The maximum ack delay in an incoming ACK frame for 554 this connection. Excludes ack delays for ack only packets and 555 those that create an RTT sample less than min_rtt. 557 reordering_threshold: The largest delta between the largest acked 558 retransmittable packet and a packet containing retransmittable 559 frames before it's declared lost. 561 time_reordering_fraction: The reordering window as a fraction of 562 max(smoothed_rtt, latest_rtt). 564 loss_time: The time at which the next packet will be considered lost 565 based on early transmit or exceeding the reordering window in 566 time. 568 sent_packets: An association of packet numbers to information about 569 them, including a number field indicating the packet number, a 570 time field indicating the time a packet was sent, a boolean 571 indicating whether the packet is ack only, and a bytes field 572 indicating the packet's size. sent_packets is ordered by packet 573 number, and packets remain in sent_packets until acknowledged or 574 lost. 576 3.4.3. Initialization 578 At the beginning of the connection, initialize the loss detection 579 variables as follows: 581 loss_detection_alarm.reset() 582 handshake_count = 0 583 tlp_count = 0 584 rto_count = 0 585 if (kUsingTimeLossDetection) 586 reordering_threshold = infinite 587 time_reordering_fraction = kTimeReorderingFraction 588 else: 589 reordering_threshold = kReorderingThreshold 590 time_reordering_fraction = infinite 591 loss_time = 0 592 smoothed_rtt = 0 593 rttvar = 0 594 min_rtt = 0 595 max_ack_delay = 0 596 largest_sent_before_rto = 0 597 time_of_last_sent_packet = 0 598 largest_sent_packet = 0 600 3.4.4. On Sending a Packet 602 After any packet is sent, be it a new transmission or a rebundled 603 transmission, the following OnPacketSent function is called. The 604 parameters to OnPacketSent are as follows: 606 o packet_number: The packet number of the sent packet. 608 o is_ack_only: A boolean that indicates whether a packet only 609 contains an ACK frame. If true, it is still expected an ack will 610 be received for this packet, but it is not congestion controlled. 612 o sent_bytes: The number of bytes sent in the packet, not including 613 UDP or IP overhead, but including QUIC framing overhead. 615 Pseudocode for OnPacketSent follows: 617 OnPacketSent(packet_number, is_ack_only, sent_bytes): 618 time_of_last_sent_packet = now 619 largest_sent_packet = packet_number 620 sent_packets[packet_number].packet_number = packet_number 621 sent_packets[packet_number].time = now 622 sent_packets[packet_number].ack_only = is_ack_only 623 if !is_ack_only: 624 OnPacketSentCC(sent_bytes) 625 sent_packets[packet_number].bytes = sent_bytes 626 SetLossDetectionAlarm() 628 3.4.5. On Ack Receipt 630 When an ack is received, it may acknowledge 0 or more packets. 632 Pseudocode for OnAckReceived and UpdateRtt follow: 634 OnAckReceived(ack): 635 largest_acked_packet = ack.largest_acked 636 // If the largest acked is newly acked, update the RTT. 637 if (sent_packets[ack.largest_acked]): 638 latest_rtt = now - sent_packets[ack.largest_acked].time 639 UpdateRtt(latest_rtt, ack.ack_delay) 640 // Find all newly acked packets. 641 for acked_packet in DetermineNewlyAckedPackets(): 642 OnPacketAcked(acked_packet.packet_number) 644 DetectLostPackets(ack.largest_acked_packet) 645 SetLossDetectionAlarm() 647 UpdateRtt(latest_rtt, ack_delay): 648 // min_rtt ignores ack delay. 649 min_rtt = min(min_rtt, latest_rtt) 650 // Adjust for ack delay if it's plausible. 651 if (latest_rtt - min_rtt > ack_delay): 652 latest_rtt -= ack_delay 653 // Only save into max ack delay if it's used 654 // for rtt calculation and is not ack only. 655 if (!sent_packets[ack.largest_acked].ack_only) 656 max_ack_delay = max(max_ack_delay, ack_delay) 657 // Based on {{RFC6298}}. 658 if (smoothed_rtt == 0): 659 smoothed_rtt = latest_rtt 660 rttvar = latest_rtt / 2 661 else: 662 rttvar = 3/4 * rttvar + 1/4 * abs(smoothed_rtt - latest_rtt) 663 smoothed_rtt = 7/8 * smoothed_rtt + 1/8 * latest_rtt 665 3.4.6. On Packet Acknowledgment 667 When a packet is acked for the first time, the following 668 OnPacketAcked function is called. Note that a single ACK frame may 669 newly acknowledge several packets. OnPacketAcked must be called once 670 for each of these newly acked packets. 672 OnPacketAcked takes one parameter, acked_packet, which is the packet 673 number of the newly acked packet, and returns a list of packet 674 numbers that are detected as lost. 676 If this is the first acknowledgement following RTO, check if the 677 smallest newly acknowledged packet is one sent by the RTO, and if so, 678 inform congestion control of a verified RTO, similar to F-RTO 679 [RFC5682] 680 Pseudocode for OnPacketAcked follows: 682 OnPacketAcked(acked_packet_number): 683 OnPacketAckedCC(acked_packet_number) 684 // If a packet sent prior to RTO was acked, then the RTO 685 // was spurious. Otherwise, inform congestion control. 686 if (rto_count > 0 && 687 acked_packet_number > largest_sent_before_rto) 688 OnRetransmissionTimeoutVerified() 689 handshake_count = 0 690 tlp_count = 0 691 rto_count = 0 692 sent_packets.remove(acked_packet_number) 694 3.4.7. Setting the Loss Detection Alarm 696 QUIC loss detection uses a single alarm for all timer-based loss 697 detection. The duration of the alarm is based on the alarm's mode, 698 which is set in the packet and timer events further below. The 699 function SetLossDetectionAlarm defined below shows how the single 700 timer is set based on the alarm mode. 702 3.4.7.1. Handshake Alarm 704 When a connection has unacknowledged handshake data, the handshake 705 alarm is set and when it expires, all unacknowledgedd handshake data 706 is retransmitted. 708 When stateless rejects are in use, the connection is considered 709 immediately closed once a reject is sent, so no timer is set to 710 retransmit the reject. 712 Version negotiation packets are always stateless, and MUST be sent 713 once per handshake packet that uses an unsupported QUIC version, and 714 MAY be sent in response to 0RTT packets. 716 3.4.7.2. Tail Loss Probe and Retransmission Alarm 718 Tail loss probes [LOSS-PROBE] and retransmission timeouts [RFC6298] 719 are an alarm based mechanism to recover from cases when there are 720 outstanding retransmittable packets, but an acknowledgement has not 721 been received in a timely manner. 723 The TLP and RTO timers are armed when there is not unacknowledged 724 handshake data. The TLP alarm is set until the max number of TLP 725 packets have been sent, and then the RTO tiemr is set. 727 3.4.7.3. Early Retransmit Alarm 729 Early retransmit [RFC5827] is implemented with a 1/4 RTT timer. It 730 is part of QUIC's time based loss detection, but is always enabled, 731 even when only packet reordering loss detection is enabled. 733 3.4.7.4. Pseudocode 735 Pseudocode for SetLossDetectionAlarm follows: 737 SetLossDetectionAlarm(): 738 // Don't arm the alarm if there are no packets with 739 // retransmittable data in flight. 740 if (num_retransmittable_packets_outstanding == 0): 741 loss_detection_alarm.cancel() 742 return 744 if (handshake packets are outstanding): 745 // Handshake retransmission alarm. 746 if (smoothed_rtt == 0): 747 alarm_duration = 2 * kDefaultInitialRtt 748 else: 749 alarm_duration = 2 * smoothed_rtt 750 alarm_duration = max(alarm_duration, kMinTLPTimeout) 751 alarm_duration = alarm_duration * (2 ^ handshake_count) 752 else if (loss_time != 0): 753 // Early retransmit timer or time loss detection. 754 alarm_duration = loss_time - time_of_last_sent_packet 755 else if (tlp_count < kMaxTLPs): 756 // Tail Loss Probe 757 alarm_duration = max(1.5 * smoothed_rtt + max_ack_delay, 758 kMinTLPTimeout) 759 else: 760 // RTO alarm 761 alarm_duration = smoothed_rtt + 4 * rttvar 762 alarm_duration = max(alarm_duration, kMinRTOTimeout) 763 alarm_duration = alarm_duration * (2 ^ rto_count) 765 loss_detection_alarm.set(time_of_last_sent_packet 766 + alarm_duration) 768 3.4.8. On Alarm Firing 770 QUIC uses one loss recovery alarm, which when set, can be in one of 771 several modes. When the alarm fires, the mode determines the action 772 to be performed. 774 Pseudocode for OnLossDetectionAlarm follows: 776 OnLossDetectionAlarm(): 777 if (handshake packets are outstanding): 778 // Handshake retransmission alarm. 779 RetransmitAllHandshakePackets() 780 handshake_count++ 781 else if (loss_time != 0): 782 // Early retransmit or Time Loss Detection 783 DetectLostPackets(largest_acked_packet) 784 else if (tlp_count < kMaxTLPs): 785 // Tail Loss Probe. 786 SendOnePacket() 787 tlp_count++ 788 else: 789 // RTO. 790 if (rto_count == 0) 791 largest_sent_before_rto = largest_sent_packet 792 SendTwoPackets() 793 rto_count++ 795 SetLossDetectionAlarm() 797 3.4.9. Detecting Lost Packets 799 Packets in QUIC are only considered lost once a larger packet number 800 is acknowledged. DetectLostPackets is called every time an ack is 801 received. If the loss detection alarm fires and the loss_time is 802 set, the previous largest acked packet is supplied. 804 3.4.9.1. Handshake Packets 806 The receiver MUST close the connection with an error of type 807 OPTIMISTIC_ACK when receiving an unprotected packet that acks 808 protected packets. The receiver MUST trust protected acks for 809 unprotected packets, however. Aside from this, loss detection for 810 handshake packets when an ack is processed is identical to other 811 packets. 813 3.4.9.2. Pseudocode 815 DetectLostPackets takes one parameter, acked, which is the largest 816 acked packet. 818 Pseudocode for DetectLostPackets follows: 820 DetectLostPackets(largest_acked): 821 loss_time = 0 822 lost_packets = {} 823 delay_until_lost = infinite 824 if (kUsingTimeLossDetection): 825 delay_until_lost = 826 (1 + time_reordering_fraction) * max(latest_rtt, smoothed_rtt) 827 else if (largest_acked.packet_number == largest_sent_packet): 828 // Early retransmit alarm. 829 delay_until_lost = 5/4 * max(latest_rtt, smoothed_rtt) 830 foreach (unacked < largest_acked.packet_number): 831 time_since_sent = now() - unacked.time_sent 832 delta = largest_acked.packet_number - unacked.packet_number 833 if (time_since_sent > delay_until_lost): 834 lost_packets.insert(unacked) 835 else if (delta > reordering_threshold) 836 lost_packets.insert(unacked) 837 else if (loss_time == 0 && delay_until_lost != infinite): 838 loss_time = now() + delay_until_lost - time_since_sent 840 // Inform the congestion controller of lost packets and 841 // lets it decide whether to retransmit immediately. 842 if (!lost_packets.empty()) 843 OnPacketsLost(lost_packets) 844 foreach (packet in lost_packets) 845 sent_packets.remove(packet.packet_number) 847 3.5. Discussion 849 The majority of constants were derived from best common practices 850 among widely deployed TCP implementations on the internet. 851 Exceptions follow. 853 A shorter delayed ack time of 25ms was chosen because longer delayed 854 acks can delay loss recovery and for the small number of connections 855 where less than packet per 25ms is delivered, acking every packet is 856 beneficial to congestion control and loss recovery. 858 The default initial RTT of 100ms was chosen because it is slightly 859 higher than both the median and mean min_rtt typically observed on 860 the public internet. 862 4. Congestion Control 864 QUIC's congestion control is based on TCP NewReno[RFC6582] congestion 865 control to determine the congestion window and pacing rate. QUIC 866 congestion control is specified in bytes due to finer control and the 867 ease of appropriate byte counting[RFC3465]. 869 4.1. Slow Start 871 QUIC begins every connection in slow start and exits slow start upon 872 loss. QUIC re-enters slow start anytime the congestion window is 873 less than sshthresh, which typically only occurs after an RTO. While 874 in slow start, QUIC increases the congestion window by the number of 875 acknowledged bytes when each ack is processed. 877 4.2. Congestion Avoidance 879 Slow start exits to congestion avoidance. Congestion avoidance in 880 NewReno uses an additive increase multiplicative decrease (AIMD) 881 approach that increases the congestion window by one MSS of bytes per 882 congestion window acknowledged. When a loss is detected, NewReno 883 halves the congestion window and sets the slow start threshold to the 884 new congestion window. 886 4.3. Recovery Period 888 Recovery is a period of time beginning with detection of a lost 889 packet. Because QUIC retransmits stream data and control frames, not 890 packets, it defines the end of recovery as a packet sent after the 891 start of recovery being acknowledged. This is slightly different 892 from TCP's definition of recovery ending when the lost packet that 893 started recovery is acknowledged. 895 During recovery, the congestion window is not increased or decreased. 896 As such, multiple lost packets only decrease the congestion window 897 once as long as they're lost before exiting recovery. This causes 898 QUIC to decrease the congestion window multiple times if 899 retransmisions are lost, but limits the reduction to once per round 900 trip. 902 4.4. Tail Loss Probe 904 If recovery sends a tail loss probe, no change is made to the 905 congestion window or pacing rate. Acknowledgement or loss of tail 906 loss probes are treated like any other packet. 908 4.5. Retransmission Timeout 910 When retransmissions are sent due to a retransmission timeout alarm, 911 no change is made to the congestion window or pacing rate until the 912 next acknowledgement arrives. When an ack arrives, if packets prior 913 to the first retransmission timeout are acknowledged, then the 914 congestion window remains the same. If no packets prior to the first 915 retransmission timeout are acknowledged, the retransmission timeout 916 has been validated and the congestion window must be reduced to the 917 minimum congestion window and slow start is begun. 919 4.6. Pacing Rate 921 The pacing rate is a function of the mode, the congestion window, and 922 the smoothed rtt. Specifically, the pacing rate is 2 times the 923 congestion window divided by the smoothed RTT during slow start and 924 1.25 times the congestion window divided by the smoothed RTT during 925 congestion avoidance. In order to fairly compete with flows that are 926 not pacing, it is recommended to not pace the first 10 sent packets 927 when exiting quiescence. 929 4.7. Pseudocode 931 4.7.1. Constants of interest 933 Constants used in congestion control are based on a combination of 934 RFCs, papers, and common practice. Some may need to be changed or 935 negotiated in order to better suit a variety of environments. 937 kDefaultMss (default 1460 bytes): The default max packet size used 938 for calculating default and minimum congestion windows. 940 kInitialWindow (default 10 * kDefaultMss): Default limit on the 941 amount of outstanding data in bytes. 943 kMinimumWindow (default 2 * kDefaultMss): Default minimum congestion 944 window. 946 kLossReductionFactor (default 0.5): Reduction in congestion window 947 when a new loss event is detected. 949 4.7.2. Variables of interest 951 Variables required to implement the congestion control mechanisms are 952 described in this section. 954 bytes_in_flight: The sum of the size in bytes of all sent packets 955 that contain at least one retransmittable or PADDING frame, and 956 have not been acked or declared lost. The size does not include 957 IP or UDP overhead. Packets only containing ACK frames do not 958 count towards byte_in_flight to ensure congestion control does not 959 impede congestion feedback. 961 congestion_window: Maximum number of bytes in flight that may be 962 sent. 964 end_of_recovery: The largest packet number sent when QUIC detects a 965 loss. When a larger packet is acknowledged, QUIC exits recovery. 967 ssthresh: Slow start threshold in bytes. When the congestion window 968 is below ssthresh, the mode is slow start and the window grows by 969 the number of bytes acknowledged. 971 4.7.3. Initialization 973 At the beginning of the connection, initialize the congestion control 974 variables as follows: 976 congestion_window = kInitialWindow 977 bytes_in_flight = 0 978 end_of_recovery = 0 979 ssthresh = infinite 981 4.7.4. On Packet Sent 983 Whenever a packet is sent, and it contains non-ACK frames, the packet 984 increases bytes_in_flight. 986 OnPacketSentCC(bytes_sent): 987 bytes_in_flight += bytes_sent 989 4.7.5. On Packet Acknowledgement 991 Invoked from loss detection's OnPacketAcked and is supplied with 992 acked_packet from sent_packets. 994 OnPacketAckedCC(acked_packet): 995 // Remove from bytes_in_flight. 996 bytes_in_flight -= acked_packet.bytes 997 if (acked_packet.packet_number < end_of_recovery): 998 // Do not increase congestion window in recovery period. 999 return 1000 if (congestion_window < ssthresh): 1001 // Slow start. 1002 congestion_window += acked_packets.bytes 1003 else: 1004 // Congestion avoidance. 1005 congestion_window += 1006 kDefaultMss * acked_packets.bytes / congestion_window 1008 4.7.6. On Packets Lost 1010 Invoked by loss detection from DetectLostPackets when new packets are 1011 detected lost. 1013 OnPacketsLost(lost_packets): 1014 // Remove lost packets from bytes_in_flight. 1015 for (lost_packet : lost_packets): 1016 bytes_in_flight -= lost_packet.bytes 1017 largest_lost_packet = lost_packets.last() 1018 // Start a new recovery epoch if the lost packet is larger 1019 // than the end of the previous recovery epoch. 1020 if (end_of_recovery < largest_lost_packet.packet_number): 1021 end_of_recovery = largest_sent_packet 1022 congestion_window *= kLossReductionFactor 1023 congestion_window = max(congestion_window, kMinimumWindow) 1024 ssthresh = congestion_window 1026 4.7.7. On Retransmission Timeout Verified 1028 QUIC decreases the congestion window to the minimum value once the 1029 retransmission timeout has been verified. 1031 OnRetransmissionTimeoutVerified() 1032 congestion_window = kMinimumWindow 1034 5. IANA Considerations 1036 This document has no IANA actions. Yet. 1038 6. References 1040 6.1. Normative References 1042 [QUIC-TRANSPORT] 1043 Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based 1044 Multiplexed and Secure Transport", draft-ietf-quic- 1045 transport-00 (work in progress), December 2017. 1047 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1048 Requirement Levels", BCP 14, RFC 2119, 1049 DOI 10.17487/RFC2119, March 1997, 1050 . 1052 [RFC4653] Bhandarkar, S., Reddy, A., Allman, M., and E. Blanton, 1053 "Improving the Robustness of TCP to Non-Congestion 1054 Events", RFC 4653, DOI 10.17487/RFC4653, August 2006, 1055 . 1057 [RFC5681] Allman, M., Paxson, V., and E. Blanton, "TCP Congestion 1058 Control", RFC 5681, DOI 10.17487/RFC5681, September 2009, 1059 . 1061 [RFC5682] Sarolahti, P., Kojo, M., Yamamoto, K., and M. Hata, 1062 "Forward RTO-Recovery (F-RTO): An Algorithm for Detecting 1063 Spurious Retransmission Timeouts with TCP", RFC 5682, 1064 DOI 10.17487/RFC5682, September 2009, 1065 . 1067 [RFC5827] Allman, M., Avrachenkov, K., Ayesta, U., Blanton, J., and 1068 P. Hurtig, "Early Retransmit for TCP and Stream Control 1069 Transmission Protocol (SCTP)", RFC 5827, 1070 DOI 10.17487/RFC5827, May 2010, 1071 . 1073 [RFC6298] Paxson, V., Allman, M., Chu, J., and M. Sargent, 1074 "Computing TCP's Retransmission Timer", RFC 6298, 1075 DOI 10.17487/RFC6298, June 2011, 1076 . 1078 [RFC6675] Blanton, E., Allman, M., Wang, L., Jarvinen, I., Kojo, M., 1079 and Y. Nishida, "A Conservative Loss Recovery Algorithm 1080 Based on Selective Acknowledgment (SACK) for TCP", 1081 RFC 6675, DOI 10.17487/RFC6675, August 2012, 1082 . 1084 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 1085 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 1086 May 2017, . 1088 6.2. Informative References 1090 [LOSS-PROBE] 1091 Dukkipati, N., Cardwell, N., Cheng, Y., and M. Mathis, 1092 "Tail Loss Probe (TLP): An Algorithm for Fast Recovery of 1093 Tail Losses", draft-dukkipati-tcpm-tcp-loss-probe-01 (work 1094 in progress), February 2013. 1096 [RFC3465] Allman, M., "TCP Congestion Control with Appropriate Byte 1097 Counting (ABC)", RFC 3465, DOI 10.17487/RFC3465, February 1098 2003, . 1100 [RFC6582] Henderson, T., Floyd, S., Gurtov, A., and Y. Nishida, "The 1101 NewReno Modification to TCP's Fast Recovery Algorithm", 1102 RFC 6582, DOI 10.17487/RFC6582, April 2012, 1103 . 1105 [TLP] Dukkipati, N., Cardwell, N., Cheng, Y., and M. Mathis, 1106 "Tail Loss Probe (TLP): An Algorithm for Fast Recovery of 1107 Tail Losses", draft-dukkipati-tcpm-tcp-loss-probe-01 (work 1108 in progress), February 2013. 1110 6.3. URIs 1112 [1] https://mailarchive.ietf.org/arch/search/?email_list=quic 1114 [2] https://github.com/quicwg 1116 [3] https://github.com/quicwg/base-drafts/labels/-recovery 1118 Appendix A. Acknowledgments 1120 Appendix B. Change Log 1122 *RFC Editor's Note:* Please remove this section prior to 1123 publication of a final version of this document. 1125 B.1. Since draft-ietf-quic-recovery-06 1127 Nothing yet. 1129 B.2. Since draft-ietf-quic-recovery-05 1131 o Add more congestion control text (#776) 1133 B.3. Since draft-ietf-quic-recovery-04 1135 No significant changes. 1137 B.4. Since draft-ietf-quic-recovery-03 1139 No significant changes. 1141 B.5. Since draft-ietf-quic-recovery-02 1143 o Integrate F-RTO (#544, #409) 1145 o Add congestion control (#545, #395) 1147 o Require connection abort if a skipped packet was acknowledged 1148 (#415) 1150 o Simplify RTO calculations (#142, #417) 1152 B.6. Since draft-ietf-quic-recovery-01 1154 o Overview added to loss detection 1156 o Changes initial default RTT to 100ms 1158 o Added time-based loss detection and fixes early retransmit 1160 o Clarified loss recovery for handshake packets 1162 o Fixed references and made TCP references informative 1164 B.7. Since draft-ietf-quic-recovery-00 1166 o Improved description of constants and ACK behavior 1168 B.8. Since draft-iyengar-quic-loss-recovery-01 1170 o Adopted as base for draft-ietf-quic-recovery 1172 o Updated authors/editors list 1174 o Added table of contents 1176 Authors' Addresses 1178 Jana Iyengar (editor) 1179 Google 1181 Email: jri@google.com 1183 Ian Swett (editor) 1184 Google 1186 Email: ianswett@google.com