blob: 53d9f0eca22803f7cd7b1419acd9f9d8df97907a [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
QUICHE team5be974e2020-12-29 18:35:24 -05005#include "quic/core/quic_sent_packet_manager.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -05006
7#include <algorithm>
haoyuewangc921f8d2020-10-14 18:06:52 -07008#include <cstddef>
vasilvv872e7a32019-03-12 16:42:44 -07009#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -050010
QUICHE team5be974e2020-12-29 18:35:24 -050011#include "quic/core/congestion_control/general_loss_algorithm.h"
12#include "quic/core/congestion_control/pacing_sender.h"
danzhb11d12d2021-01-12 10:39:32 -080013#include "quic/core/congestion_control/send_algorithm_interface.h"
QUICHE team5be974e2020-12-29 18:35:24 -050014#include "quic/core/crypto/crypto_protocol.h"
15#include "quic/core/frames/quic_ack_frequency_frame.h"
16#include "quic/core/proto/cached_network_parameters_proto.h"
17#include "quic/core/quic_connection_stats.h"
18#include "quic/core/quic_constants.h"
19#include "quic/core/quic_packet_number.h"
20#include "quic/core/quic_transmission_info.h"
21#include "quic/core/quic_types.h"
22#include "quic/core/quic_utils.h"
23#include "quic/platform/api/quic_bug_tracker.h"
24#include "quic/platform/api/quic_flag_utils.h"
25#include "quic/platform/api/quic_flags.h"
26#include "quic/platform/api/quic_logging.h"
27#include "quic/platform/api/quic_map_util.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050028
29namespace quic {
30
31namespace {
32static const int64_t kDefaultRetransmissionTimeMs = 500;
33static const int64_t kMaxRetransmissionTimeMs = 60000;
34// Maximum number of exponential backoffs used for RTO timeouts.
35static const size_t kMaxRetransmissions = 10;
36// Maximum number of packets retransmitted upon an RTO.
37static const size_t kMaxRetransmissionsOnTimeout = 2;
38// The path degrading delay is the sum of this number of consecutive RTO delays.
39const size_t kNumRetransmissionDelaysForPathDegradingDelay = 2;
40
41// Ensure the handshake timer isnt't faster than 10ms.
42// This limits the tenth retransmitted packet to 10s after the initial CHLO.
43static const int64_t kMinHandshakeTimeoutMs = 10;
44
45// Sends up to two tail loss probes before firing an RTO,
46// per draft RFC draft-dukkipati-tcpm-tcp-loss-probe.
47static const size_t kDefaultMaxTailLossProbes = 2;
48
QUICHE teama6ef0a62019-03-07 20:34:33 -050049// Returns true of retransmissions of the specified type should retransmit
50// the frames directly (as opposed to resulting in a loss notification).
51inline bool ShouldForceRetransmission(TransmissionType transmission_type) {
52 return transmission_type == HANDSHAKE_RETRANSMISSION ||
53 transmission_type == TLP_RETRANSMISSION ||
54 transmission_type == PROBING_RETRANSMISSION ||
fayang73d0ac42019-10-31 12:45:31 -070055 transmission_type == RTO_RETRANSMISSION ||
56 transmission_type == PTO_RETRANSMISSION;
QUICHE teama6ef0a62019-03-07 20:34:33 -050057}
58
fayang4ba55982019-05-13 05:53:22 -070059// If pacing rate is accurate, > 2 burst token is not likely to help first ACK
60// to arrive earlier, and overly large burst token could cause incast packet
61// losses.
62static const uint32_t kConservativeUnpacedBurst = 2;
63
QUICHE teama6ef0a62019-03-07 20:34:33 -050064} // namespace
65
66#define ENDPOINT \
67 (unacked_packets_.perspective() == Perspective::IS_SERVER ? "Server: " \
68 : "Client: ")
69
70QuicSentPacketManager::QuicSentPacketManager(
71 Perspective perspective,
72 const QuicClock* clock,
QUICHE team73957f12019-04-18 16:21:52 -070073 QuicRandom* random,
QUICHE teama6ef0a62019-03-07 20:34:33 -050074 QuicConnectionStats* stats,
fayang3be090d2020-02-11 14:05:08 -080075 CongestionControlType congestion_control_type)
QUICHE teama6ef0a62019-03-07 20:34:33 -050076 : unacked_packets_(perspective),
77 clock_(clock),
QUICHE team73957f12019-04-18 16:21:52 -070078 random_(random),
QUICHE teama6ef0a62019-03-07 20:34:33 -050079 stats_(stats),
80 debug_delegate_(nullptr),
81 network_change_visitor_(nullptr),
82 initial_congestion_window_(kInitialCongestionWindow),
ianswett34030d02020-04-10 07:57:15 -070083 loss_algorithm_(&uber_loss_algorithm_),
QUICHE teama6ef0a62019-03-07 20:34:33 -050084 consecutive_rto_count_(0),
85 consecutive_tlp_count_(0),
86 consecutive_crypto_retransmission_count_(0),
87 pending_timer_transmission_count_(0),
88 max_tail_loss_probes_(kDefaultMaxTailLossProbes),
89 max_rto_packets_(kMaxRetransmissionsOnTimeout),
90 enable_half_rtt_tail_loss_probe_(false),
91 using_pacing_(false),
92 use_new_rto_(false),
93 conservative_handshake_retransmits_(false),
94 min_tlp_timeout_(
95 QuicTime::Delta::FromMilliseconds(kMinTailLossProbeTimeoutMs)),
96 min_rto_timeout_(
97 QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs)),
QUICHE teama6ef0a62019-03-07 20:34:33 -050098 largest_mtu_acked_(0),
fayang63a19842020-01-23 02:51:28 -080099 handshake_finished_(false),
fkastenholz59c653b2019-07-15 09:55:53 -0700100 peer_max_ack_delay_(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500101 QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)),
102 rtt_updated_(false),
QUICHE team9929cc42019-03-13 08:17:43 -0700103 acked_packets_iter_(last_ack_frame_.packets.rbegin()),
fayang5d011982020-05-13 14:14:38 -0700104 pto_enabled_(GetQuicReloadableFlag(quic_default_on_pto)),
fayangce0a3162019-08-15 09:05:36 -0700105 max_probe_packets_per_pto_(2),
106 consecutive_pto_count_(0),
fayang19d2d5b2019-09-11 14:22:03 -0700107 handshake_mode_disabled_(false),
fayang4c908f02019-11-01 07:26:17 -0700108 skip_packet_number_for_pto_(false),
109 always_include_max_ack_delay_for_pto_timeout_(true),
fayang7085a6d2019-11-04 07:03:57 -0800110 pto_exponential_backoff_start_point_(0),
fayang75db4342019-11-04 13:29:14 -0800111 pto_rttvar_multiplier_(4),
fayang4aa22402020-01-07 11:36:07 -0800112 num_tlp_timeout_ptos_(0),
fayang53ddf442020-07-16 12:18:44 -0700113 handshake_packet_acked_(false),
fayangf2e0d902020-09-25 14:47:19 -0700114 zero_rtt_packet_acked_(false),
fayang9a0e1bd2020-02-19 13:13:04 -0800115 one_rtt_packet_acked_(false),
fayangc2fd6102020-03-02 17:27:38 -0800116 first_pto_srtt_multiplier_(0),
fayangbc9f56f2020-06-19 03:49:22 -0700117 use_standard_deviation_for_pto_(false),
renjietang89b32a62020-11-19 12:32:41 -0800118 pto_multiplier_without_rtt_samples_(3),
fayange0b2bb02020-11-23 11:29:48 -0800119 num_ptos_for_path_degrading_(0),
120 ignore_pings_(false) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500121 SetSendAlgorithm(congestion_control_type);
fayang5d011982020-05-13 14:14:38 -0700122 if (pto_enabled_) {
123 QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_on_pto, 1, 2);
124 // TODO(fayang): change the default values when deprecating
125 // quic_default_on_pto.
126 first_pto_srtt_multiplier_ = 1.5;
127 pto_rttvar_multiplier_ = 2;
128 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500129}
130
131QuicSentPacketManager::~QuicSentPacketManager() {}
132
133void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
134 const Perspective perspective = unacked_packets_.perspective();
135 if (config.HasReceivedInitialRoundTripTimeUs() &&
136 config.ReceivedInitialRoundTripTimeUs() > 0) {
137 if (!config.HasClientSentConnectionOption(kNRTT, perspective)) {
138 SetInitialRtt(QuicTime::Delta::FromMicroseconds(
139 config.ReceivedInitialRoundTripTimeUs()));
140 }
141 } else if (config.HasInitialRoundTripTimeUsToSend() &&
142 config.GetInitialRoundTripTimeUsToSend() > 0) {
143 SetInitialRtt(QuicTime::Delta::FromMicroseconds(
144 config.GetInitialRoundTripTimeUsToSend()));
145 }
ianswett43eefae2019-08-02 12:27:15 -0700146 if (config.HasReceivedMaxAckDelayMs()) {
147 peer_max_ack_delay_ =
148 QuicTime::Delta::FromMilliseconds(config.ReceivedMaxAckDelayMs());
149 }
haoyuewangc921f8d2020-10-14 18:06:52 -0700150 if (GetQuicReloadableFlag(quic_can_send_ack_frequency) &&
151 perspective == Perspective::IS_SERVER) {
152 if (config.HasReceivedMinAckDelayMs()) {
153 peer_min_ack_delay_ =
154 QuicTime::Delta::FromMilliseconds(config.ReceivedMinAckDelayMs());
155 }
haoyuewanged303572020-10-15 14:21:12 -0700156 if (config.HasClientSentConnectionOption(kAFF1, perspective)) {
157 use_smoothed_rtt_in_ack_delay_ = true;
158 }
haoyuewangc921f8d2020-10-14 18:06:52 -0700159 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500160 if (config.HasClientSentConnectionOption(kMAD0, perspective)) {
161 rtt_stats_.set_ignore_max_ack_delay(true);
162 }
ianswettad65ab92019-10-28 07:19:07 -0700163 if (config.HasClientSentConnectionOption(kMAD2, perspective)) {
164 // Set the minimum to the alarm granularity.
ianswett8f90e512019-12-18 10:50:27 -0800165 min_tlp_timeout_ = kAlarmGranularity;
ianswettad65ab92019-10-28 07:19:07 -0700166 }
167 if (config.HasClientSentConnectionOption(kMAD3, perspective)) {
168 // Set the minimum to the alarm granularity.
ianswett8f90e512019-12-18 10:50:27 -0800169 min_rto_timeout_ = kAlarmGranularity;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500170 }
171
fayang961eaa02020-01-10 13:04:22 -0800172 if (config.HasClientSentConnectionOption(k2PTO, perspective)) {
173 pto_enabled_ = true;
174 }
175 if (config.HasClientSentConnectionOption(k1PTO, perspective)) {
176 pto_enabled_ = true;
177 max_probe_packets_per_pto_ = 1;
fayangce0a3162019-08-15 09:05:36 -0700178 }
179
fayang91ab42f2020-01-13 17:18:48 -0800180 if (config.HasClientSentConnectionOption(kPTOS, perspective)) {
fayang4c908f02019-11-01 07:26:17 -0700181 if (!pto_enabled_) {
QUICHE team7939a6e2021-03-16 19:47:54 -0700182 QUIC_PEER_BUG(quic_peer_bug_12552_1)
fayang4c908f02019-11-01 07:26:17 -0700183 << "PTO is not enabled when receiving PTOS connection option.";
184 pto_enabled_ = true;
185 max_probe_packets_per_pto_ = 1;
186 }
187 skip_packet_number_for_pto_ = true;
188 }
189
fayang7085a6d2019-11-04 07:03:57 -0800190 if (pto_enabled_) {
191 if (config.HasClientSentConnectionOption(kPTOA, perspective)) {
fayang7085a6d2019-11-04 07:03:57 -0800192 always_include_max_ack_delay_for_pto_timeout_ = false;
193 }
194 if (config.HasClientSentConnectionOption(kPEB1, perspective)) {
fayang7085a6d2019-11-04 07:03:57 -0800195 StartExponentialBackoffAfterNthPto(1);
196 }
197 if (config.HasClientSentConnectionOption(kPEB2, perspective)) {
fayang7085a6d2019-11-04 07:03:57 -0800198 StartExponentialBackoffAfterNthPto(2);
199 }
fayang75db4342019-11-04 13:29:14 -0800200 if (config.HasClientSentConnectionOption(kPVS1, perspective)) {
fayang75db4342019-11-04 13:29:14 -0800201 pto_rttvar_multiplier_ = 2;
202 }
fayang4aa22402020-01-07 11:36:07 -0800203 if (config.HasClientSentConnectionOption(kPAG1, perspective)) {
204 QUIC_CODE_COUNT(one_aggressive_pto);
205 num_tlp_timeout_ptos_ = 1;
206 }
207 if (config.HasClientSentConnectionOption(kPAG2, perspective)) {
208 QUIC_CODE_COUNT(two_aggressive_ptos);
209 num_tlp_timeout_ptos_ = 2;
210 }
fayanga3745bc2020-04-06 10:51:03 -0700211 if (config.HasClientSentConnectionOption(kPLE1, perspective) ||
212 config.HasClientSentConnectionOption(kTLPR, perspective)) {
213 first_pto_srtt_multiplier_ = 0.5;
214 } else if (config.HasClientSentConnectionOption(kPLE2, perspective)) {
215 first_pto_srtt_multiplier_ = 1.5;
fayang2ccfbcf2020-02-28 12:37:08 -0800216 }
fayangbc9f56f2020-06-19 03:49:22 -0700217 if (config.HasClientSentConnectionOption(kAPTO, perspective)) {
218 pto_multiplier_without_rtt_samples_ = 1.5;
219 }
fayangb86cd3f2020-04-06 09:04:25 -0700220 if (config.HasClientSentConnectionOption(kPSDA, perspective)) {
fayangc2fd6102020-03-02 17:27:38 -0800221 use_standard_deviation_for_pto_ = true;
222 rtt_stats_.EnableStandardDeviationCalculation();
223 }
renjietang89b32a62020-11-19 12:32:41 -0800224 if (config.HasClientRequestedIndependentOption(kPDP2, perspective)) {
225 num_ptos_for_path_degrading_ = 2;
226 }
227 if (config.HasClientRequestedIndependentOption(kPDP3, perspective)) {
228 num_ptos_for_path_degrading_ = 3;
229 }
230 if (config.HasClientRequestedIndependentOption(kPDP4, perspective)) {
231 num_ptos_for_path_degrading_ = 4;
232 }
233 if (config.HasClientRequestedIndependentOption(kPDP5, perspective)) {
234 num_ptos_for_path_degrading_ = 5;
235 }
fayang4c908f02019-11-01 07:26:17 -0700236 }
237
QUICHE teama6ef0a62019-03-07 20:34:33 -0500238 // Configure congestion control.
239 if (config.HasClientRequestedIndependentOption(kTBBR, perspective)) {
240 SetSendAlgorithm(kBBR);
241 }
wuba9a43cb2019-07-17 15:22:42 -0700242 if (GetQuicReloadableFlag(quic_allow_client_enabled_bbr_v2) &&
243 config.HasClientRequestedIndependentOption(kB2ON, perspective)) {
244 QUIC_RELOADABLE_FLAG_COUNT(quic_allow_client_enabled_bbr_v2);
245 SetSendAlgorithm(kBBRv2);
246 }
247
QUICHE teama6ef0a62019-03-07 20:34:33 -0500248 if (config.HasClientRequestedIndependentOption(kRENO, perspective)) {
249 SetSendAlgorithm(kRenoBytes);
250 } else if (config.HasClientRequestedIndependentOption(kBYTE, perspective) ||
251 (GetQuicReloadableFlag(quic_default_to_bbr) &&
252 config.HasClientRequestedIndependentOption(kQBIC, perspective))) {
253 SetSendAlgorithm(kCubicBytes);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500254 }
wuba9a43cb2019-07-17 15:22:42 -0700255
QUICHE teama6ef0a62019-03-07 20:34:33 -0500256 // Initial window.
257 if (GetQuicReloadableFlag(quic_unified_iw_options)) {
258 if (config.HasClientRequestedIndependentOption(kIW03, perspective)) {
259 initial_congestion_window_ = 3;
260 send_algorithm_->SetInitialCongestionWindowInPackets(3);
261 }
262 if (config.HasClientRequestedIndependentOption(kIW10, perspective)) {
263 initial_congestion_window_ = 10;
264 send_algorithm_->SetInitialCongestionWindowInPackets(10);
265 }
266 if (config.HasClientRequestedIndependentOption(kIW20, perspective)) {
267 initial_congestion_window_ = 20;
268 send_algorithm_->SetInitialCongestionWindowInPackets(20);
269 }
270 if (config.HasClientRequestedIndependentOption(kIW50, perspective)) {
271 initial_congestion_window_ = 50;
272 send_algorithm_->SetInitialCongestionWindowInPackets(50);
273 }
274 }
wuba5812a02020-07-13 12:12:16 -0700275 if (config.HasClientRequestedIndependentOption(kBWS5, perspective)) {
fayang402103c2020-01-10 13:36:24 -0800276 initial_congestion_window_ = 10;
277 send_algorithm_->SetInitialCongestionWindowInPackets(10);
278 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500279
fayange0b2bb02020-11-23 11:29:48 -0800280 if (config.HasClientRequestedIndependentOption(kIGNP, perspective)) {
281 ignore_pings_ = true;
282 }
283
danzh88e3e052019-06-13 11:47:18 -0700284 using_pacing_ = !GetQuicFlag(FLAGS_quic_disable_pacing_for_perf_tests);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500285
QUICHE teama6ef0a62019-03-07 20:34:33 -0500286 if (config.HasClientSentConnectionOption(kNTLP, perspective)) {
287 max_tail_loss_probes_ = 0;
288 }
289 if (config.HasClientSentConnectionOption(k1TLP, perspective)) {
290 max_tail_loss_probes_ = 1;
291 }
292 if (config.HasClientSentConnectionOption(k1RTO, perspective)) {
293 max_rto_packets_ = 1;
294 }
295 if (config.HasClientSentConnectionOption(kTLPR, perspective)) {
296 enable_half_rtt_tail_loss_probe_ = true;
297 }
fayang3a018972020-07-01 12:25:13 -0700298 if (config.HasClientRequestedIndependentOption(kTLPR, perspective)) {
299 enable_half_rtt_tail_loss_probe_ = true;
300 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500301 if (config.HasClientSentConnectionOption(kNRTO, perspective)) {
302 use_new_rto_ = true;
303 }
304 // Configure loss detection.
fayanga590b752020-01-13 06:37:35 -0800305 if (config.HasClientRequestedIndependentOption(kILD0, perspective)) {
fayang3be090d2020-02-11 14:05:08 -0800306 uber_loss_algorithm_.SetReorderingShift(kDefaultIetfLossDelayShift);
307 uber_loss_algorithm_.DisableAdaptiveReorderingThreshold();
fayanga590b752020-01-13 06:37:35 -0800308 }
309 if (config.HasClientRequestedIndependentOption(kILD1, perspective)) {
fayanga590b752020-01-13 06:37:35 -0800310 uber_loss_algorithm_.SetReorderingShift(kDefaultLossDelayShift);
fayang3be090d2020-02-11 14:05:08 -0800311 uber_loss_algorithm_.DisableAdaptiveReorderingThreshold();
fayanga590b752020-01-13 06:37:35 -0800312 }
313 if (config.HasClientRequestedIndependentOption(kILD2, perspective)) {
fayanga590b752020-01-13 06:37:35 -0800314 uber_loss_algorithm_.EnableAdaptiveReorderingThreshold();
fayang3be090d2020-02-11 14:05:08 -0800315 uber_loss_algorithm_.SetReorderingShift(kDefaultIetfLossDelayShift);
fayanga590b752020-01-13 06:37:35 -0800316 }
317 if (config.HasClientRequestedIndependentOption(kILD3, perspective)) {
fayanga590b752020-01-13 06:37:35 -0800318 uber_loss_algorithm_.SetReorderingShift(kDefaultLossDelayShift);
319 uber_loss_algorithm_.EnableAdaptiveReorderingThreshold();
320 }
321 if (config.HasClientRequestedIndependentOption(kILD4, perspective)) {
fayanga590b752020-01-13 06:37:35 -0800322 uber_loss_algorithm_.SetReorderingShift(kDefaultLossDelayShift);
323 uber_loss_algorithm_.EnableAdaptiveReorderingThreshold();
324 uber_loss_algorithm_.EnableAdaptiveTimeThreshold();
fayangb0c7b4b2019-09-12 06:45:24 -0700325 }
fayang72e02632020-04-21 10:59:49 -0700326 if (config.HasClientRequestedIndependentOption(kRUNT, perspective)) {
fayang84427fc2020-03-09 12:43:26 -0700327 uber_loss_algorithm_.DisablePacketThresholdForRuntPackets();
328 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500329 if (config.HasClientSentConnectionOption(kCONH, perspective)) {
330 conservative_handshake_retransmits_ = true;
331 }
332 send_algorithm_->SetFromConfig(config, perspective);
wub5b000532020-04-07 08:29:03 -0700333 loss_algorithm_->SetFromConfig(config, perspective);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500334
335 if (network_change_visitor_ != nullptr) {
336 network_change_visitor_->OnCongestionChange();
337 }
338}
339
wubd09f1a62020-05-04 06:57:40 -0700340void QuicSentPacketManager::ApplyConnectionOptions(
341 const QuicTagVector& connection_options) {
wub67a2b6e2021-03-02 15:33:17 -0800342 absl::optional<CongestionControlType> cc_type;
343 if (ContainsQuicTag(connection_options, kB2ON)) {
344 cc_type = kBBRv2;
345 } else if (ContainsQuicTag(connection_options, kTBBR)) {
346 cc_type = kBBR;
347 } else if (ContainsQuicTag(connection_options, kRENO)) {
348 cc_type = kRenoBytes;
349 } else if (ContainsQuicTag(connection_options, kQBIC)) {
350 cc_type = kCubicBytes;
351 }
352
353 if (cc_type.has_value()) {
354 SetSendAlgorithm(*cc_type);
355 }
356
wubd09f1a62020-05-04 06:57:40 -0700357 send_algorithm_->ApplyConnectionOptions(connection_options);
358}
359
QUICHE teama6ef0a62019-03-07 20:34:33 -0500360void QuicSentPacketManager::ResumeConnectionState(
361 const CachedNetworkParameters& cached_network_params,
362 bool max_bandwidth_resumption) {
363 QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(
364 max_bandwidth_resumption
365 ? cached_network_params.max_bandwidth_estimate_bytes_per_second()
366 : cached_network_params.bandwidth_estimate_bytes_per_second());
367 QuicTime::Delta rtt =
368 QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms());
QUICHE teamb4e187c2019-11-14 06:22:50 -0800369 // This calls the old AdjustNetworkParameters interface, and fills certain
370 // fields in SendAlgorithmInterface::NetworkParams
371 // (e.g., quic_bbr_fix_pacing_rate) using GFE flags.
372 AdjustNetworkParameters(SendAlgorithmInterface::NetworkParams(
373 bandwidth, rtt, /*allow_cwnd_to_decrease = */ false));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500374}
375
fayangf1b99dc2019-05-14 06:29:18 -0700376void QuicSentPacketManager::AdjustNetworkParameters(
QUICHE teamfdcfe3b2019-11-06 10:54:25 -0800377 const SendAlgorithmInterface::NetworkParams& params) {
QUICHE teamb4e187c2019-11-14 06:22:50 -0800378 const QuicBandwidth& bandwidth = params.bandwidth;
379 const QuicTime::Delta& rtt = params.rtt;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500380 if (!rtt.IsZero()) {
381 SetInitialRtt(rtt);
382 }
fayangbe83ecd2019-04-26 13:58:09 -0700383 const QuicByteCount old_cwnd = send_algorithm_->GetCongestionWindow();
fayang6c2d64f2019-05-20 17:12:05 -0700384 if (GetQuicReloadableFlag(quic_conservative_bursts) && using_pacing_ &&
385 !bandwidth.IsZero()) {
fayang4ba55982019-05-13 05:53:22 -0700386 QUIC_RELOADABLE_FLAG_COUNT(quic_conservative_bursts);
387 pacing_sender_.SetBurstTokens(kConservativeUnpacedBurst);
388 }
QUICHE teamb4e187c2019-11-14 06:22:50 -0800389 send_algorithm_->AdjustNetworkParameters(params);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500390 if (debug_delegate_ != nullptr) {
fayangbe83ecd2019-04-26 13:58:09 -0700391 debug_delegate_->OnAdjustNetworkParameters(
QUICHE team780461d2020-05-07 12:14:50 -0700392 bandwidth, rtt.IsZero() ? rtt_stats_.MinOrInitialRtt() : rtt, old_cwnd,
393 send_algorithm_->GetCongestionWindow());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500394 }
395}
396
wub44e33052020-03-03 17:11:40 -0800397void QuicSentPacketManager::SetLossDetectionTuner(
398 std::unique_ptr<LossDetectionTunerInterface> tuner) {
399 uber_loss_algorithm_.SetLossDetectionTuner(std::move(tuner));
400}
401
402void QuicSentPacketManager::OnConfigNegotiated() {
403 loss_algorithm_->OnConfigNegotiated();
404}
405
406void QuicSentPacketManager::OnConnectionClosed() {
407 loss_algorithm_->OnConnectionClosed();
408}
409
QUICHE teama6ef0a62019-03-07 20:34:33 -0500410void QuicSentPacketManager::SetHandshakeConfirmed() {
fayang63a19842020-01-23 02:51:28 -0800411 if (!handshake_finished_) {
412 handshake_finished_ = true;
vasilvv975c2352019-10-03 16:53:57 -0400413 NeuterHandshakePackets();
414 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500415}
416
fayang3eb82212019-04-16 12:05:46 -0700417void QuicSentPacketManager::PostProcessNewlyAckedPackets(
fayangf8e918b2019-07-16 13:03:16 -0700418 QuicPacketNumber ack_packet_number,
vasilvv923b6d22020-03-23 11:17:58 -0700419 EncryptionLevel ack_decrypted_level,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500420 const QuicAckFrame& ack_frame,
421 QuicTime ack_receive_time,
422 bool rtt_updated,
423 QuicByteCount prior_bytes_in_flight) {
fayangcff885a2019-10-22 07:39:04 -0700424 unacked_packets_.NotifyAggregatedStreamFrameAcked(
425 last_ack_frame_.ack_delay_time);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500426 InvokeLossDetection(ack_receive_time);
427 // Ignore losses in RTO mode.
428 if (consecutive_rto_count_ > 0 && !use_new_rto_) {
429 packets_lost_.clear();
430 }
431 MaybeInvokeCongestionEvent(rtt_updated, prior_bytes_in_flight,
432 ack_receive_time);
433 unacked_packets_.RemoveObsoletePackets();
434
435 sustained_bandwidth_recorder_.RecordEstimate(
436 send_algorithm_->InRecovery(), send_algorithm_->InSlowStart(),
437 send_algorithm_->BandwidthEstimate(), ack_receive_time, clock_->WallNow(),
438 rtt_stats_.smoothed_rtt());
439
440 // Anytime we are making forward progress and have a new RTT estimate, reset
441 // the backoff counters.
442 if (rtt_updated) {
443 if (consecutive_rto_count_ > 0) {
444 // If the ack acknowledges data sent prior to the RTO,
445 // the RTO was spurious.
446 if (LargestAcked(ack_frame) < first_rto_transmission_) {
447 // Replace SRTT with latest_rtt and increase the variance to prevent
448 // a spurious RTO from happening again.
449 rtt_stats_.ExpireSmoothedMetrics();
450 } else {
451 if (!use_new_rto_) {
452 send_algorithm_->OnRetransmissionTimeout(true);
453 }
454 }
455 }
fayang2a379bf2020-05-18 11:49:25 -0700456 // Records the max consecutive RTO or PTO before forward progress has been
457 // made.
458 if (consecutive_rto_count_ >
459 stats_->max_consecutive_rto_with_forward_progress) {
460 stats_->max_consecutive_rto_with_forward_progress =
461 consecutive_rto_count_;
462 } else if (consecutive_pto_count_ >
463 stats_->max_consecutive_rto_with_forward_progress) {
464 stats_->max_consecutive_rto_with_forward_progress =
465 consecutive_pto_count_;
466 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500467 // Reset all retransmit counters any time a new packet is acked.
468 consecutive_rto_count_ = 0;
469 consecutive_tlp_count_ = 0;
fayangce0a3162019-08-15 09:05:36 -0700470 consecutive_pto_count_ = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500471 consecutive_crypto_retransmission_count_ = 0;
472 }
473
474 if (debug_delegate_ != nullptr) {
vasilvv923b6d22020-03-23 11:17:58 -0700475 debug_delegate_->OnIncomingAck(
476 ack_packet_number, ack_decrypted_level, ack_frame, ack_receive_time,
477 LargestAcked(ack_frame), rtt_updated, GetLeastUnacked());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500478 }
479 // Remove packets below least unacked from all_packets_acked_ and
480 // last_ack_frame_.
481 last_ack_frame_.packets.RemoveUpTo(unacked_packets_.GetLeastUnacked());
482 last_ack_frame_.received_packet_times.clear();
483}
484
485void QuicSentPacketManager::MaybeInvokeCongestionEvent(
486 bool rtt_updated,
487 QuicByteCount prior_in_flight,
488 QuicTime event_time) {
489 if (!rtt_updated && packets_acked_.empty() && packets_lost_.empty()) {
490 return;
491 }
fayang74ee6642020-07-30 07:41:02 -0700492 const bool overshooting_detected =
493 stats_->overshooting_detected_with_network_parameters_adjusted;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500494 if (using_pacing_) {
495 pacing_sender_.OnCongestionEvent(rtt_updated, prior_in_flight, event_time,
496 packets_acked_, packets_lost_);
497 } else {
498 send_algorithm_->OnCongestionEvent(rtt_updated, prior_in_flight, event_time,
499 packets_acked_, packets_lost_);
500 }
fayang74ee6642020-07-30 07:41:02 -0700501 if (debug_delegate_ != nullptr && !overshooting_detected &&
502 stats_->overshooting_detected_with_network_parameters_adjusted) {
503 debug_delegate_->OnOvershootingDetected();
504 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500505 packets_acked_.clear();
506 packets_lost_.clear();
507 if (network_change_visitor_ != nullptr) {
508 network_change_visitor_->OnCongestionChange();
509 }
510}
511
renjietang74ae0912021-01-12 16:43:14 -0800512void QuicSentPacketManager::MarkInitialPacketsForRetransmission() {
haoyuewangcbd1dd72021-02-08 11:46:44 -0800513 if (unacked_packets_.empty()) {
514 return;
515 }
516 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
517 QuicPacketNumber largest_sent_packet = unacked_packets_.largest_sent_packet();
518 for (; packet_number <= largest_sent_packet; ++packet_number) {
519 QuicTransmissionInfo* transmission_info =
520 unacked_packets_.GetMutableTransmissionInfo(packet_number);
521 if (transmission_info->encryption_level == ENCRYPTION_INITIAL) {
522 if (transmission_info->in_flight) {
523 unacked_packets_.RemoveFromInFlight(transmission_info);
renjietang74ae0912021-01-12 16:43:14 -0800524 }
haoyuewangcbd1dd72021-02-08 11:46:44 -0800525 if (unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
526 MarkForRetransmission(packet_number, ALL_INITIAL_RETRANSMISSION);
renjietang74ae0912021-01-12 16:43:14 -0800527 }
528 }
529 }
530}
531
renjietangb2b8ff22020-07-07 16:18:54 -0700532void QuicSentPacketManager::MarkZeroRttPacketsForRetransmission() {
haoyuewangcbd1dd72021-02-08 11:46:44 -0800533 if (unacked_packets_.empty()) {
534 return;
535 }
536 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
537 QuicPacketNumber largest_sent_packet = unacked_packets_.largest_sent_packet();
538 for (; packet_number <= largest_sent_packet; ++packet_number) {
539 QuicTransmissionInfo* transmission_info =
540 unacked_packets_.GetMutableTransmissionInfo(packet_number);
541 if (transmission_info->encryption_level == ENCRYPTION_ZERO_RTT) {
542 if (transmission_info->in_flight) {
543 // Remove 0-RTT packets and packets of the wrong version from flight,
544 // because neither can be processed by the peer.
545 unacked_packets_.RemoveFromInFlight(transmission_info);
ianswett898306b2019-04-23 11:05:57 -0700546 }
haoyuewangcbd1dd72021-02-08 11:46:44 -0800547 if (unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
548 MarkForRetransmission(packet_number, ALL_ZERO_RTT_RETRANSMISSION);
ianswett898306b2019-04-23 11:05:57 -0700549 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500550 }
551 }
552}
553
554void QuicSentPacketManager::NeuterUnencryptedPackets() {
wubf4ab9652020-02-20 14:45:43 -0800555 for (QuicPacketNumber packet_number :
556 unacked_packets_.NeuterUnencryptedPackets()) {
wub64863212020-05-28 10:33:59 -0700557 send_algorithm_->OnPacketNeutered(packet_number);
wubf4ab9652020-02-20 14:45:43 -0800558 }
fayang42834942020-03-30 10:56:15 -0700559 if (handshake_mode_disabled_) {
560 consecutive_pto_count_ = 0;
561 uber_loss_algorithm_.ResetLossDetection(INITIAL_DATA);
562 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500563}
564
565void QuicSentPacketManager::NeuterHandshakePackets() {
wubf4ab9652020-02-20 14:45:43 -0800566 for (QuicPacketNumber packet_number :
567 unacked_packets_.NeuterHandshakePackets()) {
wub64863212020-05-28 10:33:59 -0700568 send_algorithm_->OnPacketNeutered(packet_number);
wubf4ab9652020-02-20 14:45:43 -0800569 }
fayang42834942020-03-30 10:56:15 -0700570 if (handshake_mode_disabled_) {
571 consecutive_pto_count_ = 0;
572 uber_loss_algorithm_.ResetLossDetection(HANDSHAKE_DATA);
573 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500574}
575
fayange1d2a272020-06-26 10:18:41 -0700576bool QuicSentPacketManager::ShouldAddMaxAckDelay(
577 PacketNumberSpace space) const {
vasilvvf8035162021-02-01 14:49:14 -0800578 QUICHE_DCHECK(pto_enabled_);
fayang319fb622020-07-13 07:34:37 -0700579 if (supports_multiple_packet_number_spaces() && space != APPLICATION_DATA) {
fayange1d2a272020-06-26 10:18:41 -0700580 // When the PTO is armed for Initial or Handshake packet number spaces,
581 // the max_ack_delay is 0.
582 return false;
583 }
fayang4c908f02019-11-01 07:26:17 -0700584 if (always_include_max_ack_delay_for_pto_timeout_) {
585 return true;
586 }
587 if (!unacked_packets_
588 .GetLargestSentRetransmittableOfPacketNumberSpace(APPLICATION_DATA)
589 .IsInitialized() ||
590 unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
591 APPLICATION_DATA) <
592 FirstSendingPacketNumber() + kMinReceivedBeforeAckDecimation - 1) {
593 // Peer is doing TCP style acking. Expect an immediate ACK if more than 1
594 // packet are outstanding.
595 if (unacked_packets_.packets_in_flight() >=
596 kDefaultRetransmittablePacketsBeforeAck) {
597 return false;
598 }
599 } else if (unacked_packets_.packets_in_flight() >=
600 kMaxRetransmittablePacketsBeforeAck) {
601 // Peer is doing ack decimation. Expect an immediate ACK if >= 10
602 // packets are outstanding.
603 return false;
604 }
605 if (skip_packet_number_for_pto_ && consecutive_pto_count_ > 0) {
606 // An immediate ACK is expected when doing PTOS. Please note, this will miss
607 // cases when PTO fires and turns out to be spurious.
608 return false;
609 }
610 return true;
611}
612
fayang18ff23b2020-01-28 09:19:00 -0800613QuicTime QuicSentPacketManager::GetEarliestPacketSentTimeForPto(
614 PacketNumberSpace* packet_number_space) const {
vasilvvf8035162021-02-01 14:49:14 -0800615 QUICHE_DCHECK(supports_multiple_packet_number_spaces());
fayang18ff23b2020-01-28 09:19:00 -0800616 QuicTime earliest_sent_time = QuicTime::Zero();
617 for (int8_t i = 0; i < NUM_PACKET_NUMBER_SPACES; ++i) {
618 const QuicTime sent_time = unacked_packets_.GetLastInFlightPacketSentTime(
619 static_cast<PacketNumberSpace>(i));
fayang06d4c1f2020-12-03 08:15:27 -0800620 if (!handshake_finished_ && i == APPLICATION_DATA) {
621 // Do not arm PTO for application data until handshake gets confirmed.
fayang18ff23b2020-01-28 09:19:00 -0800622 continue;
623 }
fayang9a0e1bd2020-02-19 13:13:04 -0800624 if (!sent_time.IsInitialized() || (earliest_sent_time.IsInitialized() &&
625 earliest_sent_time <= sent_time)) {
626 continue;
fayang18ff23b2020-01-28 09:19:00 -0800627 }
fayang9a0e1bd2020-02-19 13:13:04 -0800628 earliest_sent_time = sent_time;
629 *packet_number_space = static_cast<PacketNumberSpace>(i);
fayang18ff23b2020-01-28 09:19:00 -0800630 }
fayang9a0e1bd2020-02-19 13:13:04 -0800631
fayang18ff23b2020-01-28 09:19:00 -0800632 return earliest_sent_time;
633}
634
QUICHE teama6ef0a62019-03-07 20:34:33 -0500635void QuicSentPacketManager::MarkForRetransmission(
636 QuicPacketNumber packet_number,
637 TransmissionType transmission_type) {
638 QuicTransmissionInfo* transmission_info =
639 unacked_packets_.GetMutableTransmissionInfo(packet_number);
fayangcff885a2019-10-22 07:39:04 -0700640 // A previous RTO retransmission may cause connection close; packets without
641 // retransmittable frames can be marked for loss retransmissions.
QUICHE team7939a6e2021-03-16 19:47:54 -0700642 QUIC_BUG_IF(quic_bug_12552_2, transmission_type != LOSS_RETRANSMISSION &&
643 transmission_type != RTO_RETRANSMISSION &&
644 !unacked_packets_.HasRetransmittableFrames(
645 *transmission_info))
danzha6906502021-01-25 09:10:59 -0800646 << "packet number " << packet_number
647 << " transmission_type: " << transmission_type << " transmission_info "
648 << transmission_info->DebugString();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500649 // Handshake packets should never be sent as probing retransmissions.
vasilvvf8035162021-02-01 14:49:14 -0800650 QUICHE_DCHECK(!transmission_info->has_crypto_handshake ||
651 transmission_type != PROBING_RETRANSMISSION);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500652
653 HandleRetransmission(transmission_type, transmission_info);
654
haoyuewange0acd512020-11-05 09:18:36 -0800655 // Get the latest transmission_info here as it can be invalidated after
656 // HandleRetransmission adding new sent packets into unacked_packets_.
657 transmission_info =
658 unacked_packets_.GetMutableTransmissionInfo(packet_number);
659
QUICHE teama6ef0a62019-03-07 20:34:33 -0500660 // Update packet state according to transmission type.
661 transmission_info->state =
662 QuicUtils::RetransmissionTypeToPacketState(transmission_type);
663}
664
665void QuicSentPacketManager::HandleRetransmission(
666 TransmissionType transmission_type,
667 QuicTransmissionInfo* transmission_info) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500668 if (ShouldForceRetransmission(transmission_type)) {
669 // TODO(fayang): Consider to make RTO and PROBING retransmission
670 // strategies be configurable by applications. Today, TLP, RTO and PROBING
671 // retransmissions are handled similarly, i.e., always retranmist the
672 // oldest outstanding data. This is not ideal in general because different
673 // applications may want different strategies. For example, some
674 // applications may want to use higher priority stream data for bandwidth
675 // probing, and some applications want to consider RTO is an indication of
676 // loss, etc.
haoyuewangb65d0fb2020-11-25 08:11:44 -0800677 // transmission_info owning these frames may be deallocated after each
678 // retransimission. Make a copy of retransmissible frames to prevent the
679 // invalidation.
haoyuewangcbd1dd72021-02-08 11:46:44 -0800680 unacked_packets_.RetransmitFrames(
681 QuicFrames(transmission_info->retransmittable_frames),
682 transmission_type);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500683 return;
684 }
685
686 unacked_packets_.NotifyFramesLost(*transmission_info, transmission_type);
687 if (transmission_info->retransmittable_frames.empty()) {
688 return;
689 }
690
691 if (transmission_type == LOSS_RETRANSMISSION) {
692 // Record the first packet sent after loss, which allows to wait 1
693 // more RTT before giving up on this lost packet.
renjietang178e6442020-07-30 11:00:27 -0700694 transmission_info->first_sent_after_loss =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500695 unacked_packets_.largest_sent_packet() + 1;
696 } else {
697 // Clear the recorded first packet sent after loss when version or
698 // encryption changes.
renjietang178e6442020-07-30 11:00:27 -0700699 transmission_info->first_sent_after_loss.Clear();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500700 }
701}
702
703void QuicSentPacketManager::RecordOneSpuriousRetransmission(
704 const QuicTransmissionInfo& info) {
705 stats_->bytes_spuriously_retransmitted += info.bytes_sent;
706 ++stats_->packets_spuriously_retransmitted;
707 if (debug_delegate_ != nullptr) {
708 debug_delegate_->OnSpuriousPacketRetransmission(info.transmission_type,
709 info.bytes_sent);
710 }
711}
712
QUICHE teama6ef0a62019-03-07 20:34:33 -0500713void QuicSentPacketManager::MarkPacketHandled(QuicPacketNumber packet_number,
714 QuicTransmissionInfo* info,
fayang19d2d5b2019-09-11 14:22:03 -0700715 QuicTime ack_receive_time,
QUICHE team9467db02019-05-30 09:38:45 -0700716 QuicTime::Delta ack_delay_time,
717 QuicTime receive_timestamp) {
haoyuewang5b0f14f2020-09-18 14:31:54 -0700718 if (info->has_ack_frequency) {
719 for (const auto& frame : info->retransmittable_frames) {
720 if (frame.type == ACK_FREQUENCY_FRAME) {
721 OnAckFrequencyFrameAcked(*frame.ack_frequency_frame);
722 }
723 }
724 }
fayangcff885a2019-10-22 07:39:04 -0700725 // Try to aggregate acked stream frames if acked packet is not a
726 // retransmission.
727 if (info->transmission_type == NOT_RETRANSMISSION) {
728 unacked_packets_.MaybeAggregateAckedStreamFrame(*info, ack_delay_time,
729 receive_timestamp);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500730 } else {
fayangcff885a2019-10-22 07:39:04 -0700731 unacked_packets_.NotifyAggregatedStreamFrameAcked(ack_delay_time);
732 const bool new_data_acked = unacked_packets_.NotifyFramesAcked(
733 *info, ack_delay_time, receive_timestamp);
734 if (!new_data_acked && info->transmission_type != NOT_RETRANSMISSION) {
735 // Record as a spurious retransmission if this packet is a
736 // retransmission and no new data gets acked.
737 QUIC_DVLOG(1) << "Detect spurious retransmitted packet " << packet_number
renjietang2b5e6622020-06-02 15:19:40 -0700738 << " transmission type: " << info->transmission_type;
fayangcc4ea6a2019-10-25 08:44:03 -0700739 RecordOneSpuriousRetransmission(*info);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500740 }
741 }
fayangcc4ea6a2019-10-25 08:44:03 -0700742 if (info->state == LOST) {
fayangcff885a2019-10-22 07:39:04 -0700743 // Record as a spurious loss as a packet previously declared lost gets
744 // acked.
fayangcff885a2019-10-22 07:39:04 -0700745 const PacketNumberSpace packet_number_space =
746 unacked_packets_.GetPacketNumberSpace(info->encryption_level);
747 const QuicPacketNumber previous_largest_acked =
748 supports_multiple_packet_number_spaces()
749 ? unacked_packets_.GetLargestAckedOfPacketNumberSpace(
750 packet_number_space)
751 : unacked_packets_.largest_acked();
752 QUIC_DVLOG(1) << "Packet " << packet_number
753 << " was detected lost spuriously, "
754 "previous_largest_acked: "
755 << previous_largest_acked;
756 loss_algorithm_->SpuriousLossDetected(unacked_packets_, rtt_stats_,
757 ack_receive_time, packet_number,
758 previous_largest_acked);
wub02831dc2020-02-28 12:00:54 -0800759 ++stats_->packet_spuriously_detected_lost;
fayangcff885a2019-10-22 07:39:04 -0700760 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500761
762 if (network_change_visitor_ != nullptr &&
763 info->bytes_sent > largest_mtu_acked_) {
764 largest_mtu_acked_ = info->bytes_sent;
765 network_change_visitor_->OnPathMtuIncreased(largest_mtu_acked_);
766 }
767 unacked_packets_.RemoveFromInFlight(info);
768 unacked_packets_.RemoveRetransmittability(info);
769 info->state = ACKED;
770}
771
haoyuewangc921f8d2020-10-14 18:06:52 -0700772bool QuicSentPacketManager::CanSendAckFrequency() const {
773 return !peer_min_ack_delay_.IsInfinite() && handshake_finished_;
774}
775
776QuicAckFrequencyFrame QuicSentPacketManager::GetUpdatedAckFrequencyFrame()
777 const {
778 QuicAckFrequencyFrame frame;
779 if (!CanSendAckFrequency()) {
QUICHE team7939a6e2021-03-16 19:47:54 -0700780 QUIC_BUG(quic_bug_10750_1)
QUICHE team8e6da712021-03-08 10:59:32 -0800781 << "New AckFrequencyFrame is created while it shouldn't.";
haoyuewangc921f8d2020-10-14 18:06:52 -0700782 return frame;
783 }
784
haoyuewang24d8d702020-10-19 08:05:01 -0700785 QUIC_RELOADABLE_FLAG_COUNT_N(quic_can_send_ack_frequency, 1, 3);
haoyuewangc921f8d2020-10-14 18:06:52 -0700786 frame.packet_tolerance = kMaxRetransmittablePacketsBeforeAck;
haoyuewanged303572020-10-15 14:21:12 -0700787 auto rtt = use_smoothed_rtt_in_ack_delay_ ? rtt_stats_.SmoothedOrInitialRtt()
788 : rtt_stats_.MinOrInitialRtt();
haoyuewang52701b02020-10-15 13:29:17 -0700789 frame.max_ack_delay = rtt * kAckDecimationDelay;
haoyuewangc921f8d2020-10-14 18:06:52 -0700790 frame.max_ack_delay = std::max(frame.max_ack_delay, peer_min_ack_delay_);
haoyuewang24d8d702020-10-19 08:05:01 -0700791 // TODO(haoyuewang) Remove this once kDefaultMinAckDelayTimeMs is updated to
792 // 5 ms on the client side.
793 frame.max_ack_delay =
794 std::max(frame.max_ack_delay,
795 QuicTime::Delta::FromMilliseconds(kDefaultMinAckDelayTimeMs));
haoyuewangc921f8d2020-10-14 18:06:52 -0700796 return frame;
797}
798
QUICHE teama6ef0a62019-03-07 20:34:33 -0500799bool QuicSentPacketManager::OnPacketSent(
wubb0567e22020-09-11 17:42:29 -0700800 SerializedPacket* mutable_packet,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500801 QuicTime sent_time,
802 TransmissionType transmission_type,
danzh8c7d1192020-08-25 08:01:43 -0700803 HasRetransmittableData has_retransmittable_data,
804 bool measure_rtt) {
wubb0567e22020-09-11 17:42:29 -0700805 const SerializedPacket& packet = *mutable_packet;
806 QuicPacketNumber packet_number = packet.packet_number;
vasilvvf8035162021-02-01 14:49:14 -0800807 QUICHE_DCHECK_LE(FirstSendingPacketNumber(), packet_number);
808 QUICHE_DCHECK(!unacked_packets_.IsUnacked(packet_number));
QUICHE team7939a6e2021-03-16 19:47:54 -0700809 QUIC_BUG_IF(quic_bug_10750_2, packet.encrypted_length == 0)
QUICHE team8e6da712021-03-08 10:59:32 -0800810 << "Cannot send empty packets.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500811 if (pending_timer_transmission_count_ > 0) {
812 --pending_timer_transmission_count_;
813 }
814
815 bool in_flight = has_retransmittable_data == HAS_RETRANSMITTABLE_DATA;
fayange0b2bb02020-11-23 11:29:48 -0800816 if (ignore_pings_ && mutable_packet->retransmittable_frames.size() == 1 &&
817 mutable_packet->retransmittable_frames[0].type == PING_FRAME) {
818 // Dot not use PING only packet for RTT measure or congestion control.
819 in_flight = false;
820 measure_rtt = false;
821 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500822 if (using_pacing_) {
wubb0567e22020-09-11 17:42:29 -0700823 pacing_sender_.OnPacketSent(sent_time, unacked_packets_.bytes_in_flight(),
824 packet_number, packet.encrypted_length,
825 has_retransmittable_data);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500826 } else {
wubb0567e22020-09-11 17:42:29 -0700827 send_algorithm_->OnPacketSent(sent_time, unacked_packets_.bytes_in_flight(),
828 packet_number, packet.encrypted_length,
829 has_retransmittable_data);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500830 }
831
haoyuewang70ceb222020-11-30 08:52:13 -0800832 // Deallocate message data in QuicMessageFrame immediately after packet
833 // sent.
834 if (packet.has_message) {
835 for (auto& frame : mutable_packet->retransmittable_frames) {
836 if (frame.type == MESSAGE_FRAME) {
837 frame.message_frame->message_data.clear();
838 frame.message_frame->message_length = 0;
haoyuewang11a54a12020-09-21 14:17:29 -0700839 }
840 }
841 }
842
haoyuewang5b0f14f2020-09-18 14:31:54 -0700843 if (packet.has_ack_frequency) {
844 for (const auto& frame : packet.retransmittable_frames) {
845 if (frame.type == ACK_FREQUENCY_FRAME) {
846 OnAckFrequencyFrameSent(*frame.ack_frequency_frame);
847 }
848 }
849 }
wubb0567e22020-09-11 17:42:29 -0700850 unacked_packets_.AddSentPacket(mutable_packet, transmission_type, sent_time,
851 in_flight, measure_rtt);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500852 // Reset the retransmission timer anytime a pending packet is sent.
853 return in_flight;
854}
855
fayang67f82272019-08-14 16:08:45 -0700856QuicSentPacketManager::RetransmissionTimeoutMode
857QuicSentPacketManager::OnRetransmissionTimeout() {
vasilvvf8035162021-02-01 14:49:14 -0800858 QUICHE_DCHECK(unacked_packets_.HasInFlightPackets() ||
859 (handshake_mode_disabled_ && !handshake_finished_));
860 QUICHE_DCHECK_EQ(0u, pending_timer_transmission_count_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500861 // Handshake retransmission, timer based loss detection, TLP, and RTO are
862 // implemented with a single alarm. The handshake alarm is set when the
863 // handshake has not completed, the loss alarm is set when the loss detection
864 // algorithm says to, and the TLP and RTO alarms are set after that.
865 // The TLP alarm is always set to run for under an RTO.
866 switch (GetRetransmissionMode()) {
867 case HANDSHAKE_MODE:
vasilvvf8035162021-02-01 14:49:14 -0800868 QUICHE_DCHECK(!handshake_mode_disabled_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500869 ++stats_->crypto_retransmit_count;
870 RetransmitCryptoPackets();
fayang67f82272019-08-14 16:08:45 -0700871 return HANDSHAKE_MODE;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500872 case LOSS_MODE: {
873 ++stats_->loss_timeout_count;
874 QuicByteCount prior_in_flight = unacked_packets_.bytes_in_flight();
875 const QuicTime now = clock_->Now();
876 InvokeLossDetection(now);
877 MaybeInvokeCongestionEvent(false, prior_in_flight, now);
fayang67f82272019-08-14 16:08:45 -0700878 return LOSS_MODE;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500879 }
880 case TLP_MODE:
881 ++stats_->tlp_count;
882 ++consecutive_tlp_count_;
883 pending_timer_transmission_count_ = 1;
884 // TLPs prefer sending new data instead of retransmitting data, so
885 // give the connection a chance to write before completing the TLP.
fayang67f82272019-08-14 16:08:45 -0700886 return TLP_MODE;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500887 case RTO_MODE:
888 ++stats_->rto_count;
889 RetransmitRtoPackets();
fayang67f82272019-08-14 16:08:45 -0700890 return RTO_MODE;
fayangce0a3162019-08-15 09:05:36 -0700891 case PTO_MODE:
892 QUIC_DVLOG(1) << ENDPOINT << "PTO mode";
893 ++stats_->pto_count;
fayang06d4c1f2020-12-03 08:15:27 -0800894 if (handshake_mode_disabled_ && !handshake_finished_) {
fayangaf9903b2020-05-14 14:34:28 -0700895 ++stats_->crypto_retransmit_count;
896 }
fayangce0a3162019-08-15 09:05:36 -0700897 ++consecutive_pto_count_;
898 pending_timer_transmission_count_ = max_probe_packets_per_pto_;
899 return PTO_MODE;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500900 }
QUICHE team7939a6e2021-03-16 19:47:54 -0700901 QUIC_BUG(quic_bug_10750_3)
QUICHE team8e6da712021-03-08 10:59:32 -0800902 << "Unknown retransmission mode " << GetRetransmissionMode();
danzh7f547142020-09-09 11:10:14 -0700903 return GetRetransmissionMode();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500904}
905
906void QuicSentPacketManager::RetransmitCryptoPackets() {
vasilvvf8035162021-02-01 14:49:14 -0800907 QUICHE_DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500908 ++consecutive_crypto_retransmission_count_;
909 bool packet_retransmitted = false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500910 std::vector<QuicPacketNumber> crypto_retransmissions;
haoyuewangcbd1dd72021-02-08 11:46:44 -0800911 if (!unacked_packets_.empty()) {
haoyuewange0acd512020-11-05 09:18:36 -0800912 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
haoyuewangcbd1dd72021-02-08 11:46:44 -0800913 QuicPacketNumber largest_sent_packet =
914 unacked_packets_.largest_sent_packet();
915 for (; packet_number <= largest_sent_packet; ++packet_number) {
916 QuicTransmissionInfo* transmission_info =
917 unacked_packets_.GetMutableTransmissionInfo(packet_number);
haoyuewange0acd512020-11-05 09:18:36 -0800918 // Only retransmit frames which are in flight, and therefore have been
919 // sent.
haoyuewangcbd1dd72021-02-08 11:46:44 -0800920 if (!transmission_info->in_flight ||
921 transmission_info->state != OUTSTANDING ||
922 !transmission_info->has_crypto_handshake ||
923 !unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
haoyuewange0acd512020-11-05 09:18:36 -0800924 continue;
925 }
926 packet_retransmitted = true;
927 crypto_retransmissions.push_back(packet_number);
928 ++pending_timer_transmission_count_;
929 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500930 }
vasilvvf8035162021-02-01 14:49:14 -0800931 QUICHE_DCHECK(packet_retransmitted)
932 << "No crypto packets found to retransmit.";
fayangcff885a2019-10-22 07:39:04 -0700933 for (QuicPacketNumber retransmission : crypto_retransmissions) {
934 MarkForRetransmission(retransmission, HANDSHAKE_RETRANSMISSION);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500935 }
936}
937
938bool QuicSentPacketManager::MaybeRetransmitTailLossProbe() {
vasilvvf8035162021-02-01 14:49:14 -0800939 QUICHE_DCHECK(!pto_enabled_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500940 if (pending_timer_transmission_count_ == 0) {
941 return false;
942 }
943 if (!MaybeRetransmitOldestPacket(TLP_RETRANSMISSION)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500944 return false;
945 }
946 return true;
947}
948
949bool QuicSentPacketManager::MaybeRetransmitOldestPacket(TransmissionType type) {
haoyuewangcbd1dd72021-02-08 11:46:44 -0800950 if (!unacked_packets_.empty()) {
haoyuewange0acd512020-11-05 09:18:36 -0800951 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
haoyuewangcbd1dd72021-02-08 11:46:44 -0800952 QuicPacketNumber largest_sent_packet =
953 unacked_packets_.largest_sent_packet();
954 for (; packet_number <= largest_sent_packet; ++packet_number) {
955 QuicTransmissionInfo* transmission_info =
956 unacked_packets_.GetMutableTransmissionInfo(packet_number);
haoyuewange0acd512020-11-05 09:18:36 -0800957 // Only retransmit frames which are in flight, and therefore have been
958 // sent.
haoyuewangcbd1dd72021-02-08 11:46:44 -0800959 if (!transmission_info->in_flight ||
960 transmission_info->state != OUTSTANDING ||
961 !unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
haoyuewange0acd512020-11-05 09:18:36 -0800962 continue;
963 }
964 MarkForRetransmission(packet_number, type);
965 return true;
966 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500967 }
968 QUIC_DVLOG(1)
969 << "No retransmittable packets, so RetransmitOldestPacket failed.";
970 return false;
971}
972
973void QuicSentPacketManager::RetransmitRtoPackets() {
vasilvvf8035162021-02-01 14:49:14 -0800974 QUICHE_DCHECK(!pto_enabled_);
QUICHE team7939a6e2021-03-16 19:47:54 -0700975 QUIC_BUG_IF(quic_bug_12552_3, pending_timer_transmission_count_ > 0)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500976 << "Retransmissions already queued:" << pending_timer_transmission_count_;
977 // Mark two packets for retransmission.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500978 std::vector<QuicPacketNumber> retransmissions;
haoyuewangcbd1dd72021-02-08 11:46:44 -0800979 if (!unacked_packets_.empty()) {
haoyuewange0acd512020-11-05 09:18:36 -0800980 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
haoyuewangcbd1dd72021-02-08 11:46:44 -0800981 QuicPacketNumber largest_sent_packet =
982 unacked_packets_.largest_sent_packet();
983 for (; packet_number <= largest_sent_packet; ++packet_number) {
984 QuicTransmissionInfo* transmission_info =
985 unacked_packets_.GetMutableTransmissionInfo(packet_number);
986 if (transmission_info->state == OUTSTANDING &&
987 unacked_packets_.HasRetransmittableFrames(*transmission_info) &&
haoyuewange0acd512020-11-05 09:18:36 -0800988 pending_timer_transmission_count_ < max_rto_packets_) {
haoyuewangcbd1dd72021-02-08 11:46:44 -0800989 QUICHE_DCHECK(transmission_info->in_flight);
haoyuewange0acd512020-11-05 09:18:36 -0800990 retransmissions.push_back(packet_number);
991 ++pending_timer_transmission_count_;
992 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500993 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500994 }
995 if (pending_timer_transmission_count_ > 0) {
996 if (consecutive_rto_count_ == 0) {
997 first_rto_transmission_ = unacked_packets_.largest_sent_packet() + 1;
998 }
999 ++consecutive_rto_count_;
1000 }
fayangcff885a2019-10-22 07:39:04 -07001001 for (QuicPacketNumber retransmission : retransmissions) {
1002 MarkForRetransmission(retransmission, RTO_RETRANSMISSION);
1003 }
1004 if (retransmissions.empty()) {
QUICHE team7939a6e2021-03-16 19:47:54 -07001005 QUIC_BUG_IF(quic_bug_12552_4, pending_timer_transmission_count_ != 0);
fayangcff885a2019-10-22 07:39:04 -07001006 // No packets to be RTO retransmitted, raise up a credit to allow
1007 // connection to send.
1008 QUIC_CODE_COUNT(no_packets_to_be_rto_retransmitted);
1009 pending_timer_transmission_count_ = 1;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001010 }
1011}
1012
fayangce0a3162019-08-15 09:05:36 -07001013void QuicSentPacketManager::MaybeSendProbePackets() {
1014 if (pending_timer_transmission_count_ == 0) {
1015 return;
1016 }
fayang18ff23b2020-01-28 09:19:00 -08001017 PacketNumberSpace packet_number_space;
1018 if (supports_multiple_packet_number_spaces()) {
1019 // Find out the packet number space to send probe packets.
1020 if (!GetEarliestPacketSentTimeForPto(&packet_number_space)
1021 .IsInitialized()) {
QUICHE team7939a6e2021-03-16 19:47:54 -07001022 QUIC_BUG_IF(quic_earliest_sent_time_not_initialized,
1023 unacked_packets_.perspective() == Perspective::IS_SERVER)
QUICHE team892fb832021-03-12 10:18:40 -08001024 << "earliest_sent_time not initialized when trying to send PTO "
fayangaecfd532020-04-28 12:35:12 -07001025 "retransmissions";
fayang18ff23b2020-01-28 09:19:00 -08001026 return;
1027 }
1028 }
fayangce0a3162019-08-15 09:05:36 -07001029 std::vector<QuicPacketNumber> probing_packets;
haoyuewangcbd1dd72021-02-08 11:46:44 -08001030 if (!unacked_packets_.empty()) {
haoyuewange0acd512020-11-05 09:18:36 -08001031 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
haoyuewangcbd1dd72021-02-08 11:46:44 -08001032 QuicPacketNumber largest_sent_packet =
1033 unacked_packets_.largest_sent_packet();
1034 for (; packet_number <= largest_sent_packet; ++packet_number) {
1035 QuicTransmissionInfo* transmission_info =
1036 unacked_packets_.GetMutableTransmissionInfo(packet_number);
1037 if (transmission_info->state == OUTSTANDING &&
1038 unacked_packets_.HasRetransmittableFrames(*transmission_info) &&
haoyuewange0acd512020-11-05 09:18:36 -08001039 (!supports_multiple_packet_number_spaces() ||
haoyuewangcbd1dd72021-02-08 11:46:44 -08001040 unacked_packets_.GetPacketNumberSpace(
1041 transmission_info->encryption_level) == packet_number_space)) {
1042 QUICHE_DCHECK(transmission_info->in_flight);
haoyuewange0acd512020-11-05 09:18:36 -08001043 probing_packets.push_back(packet_number);
1044 if (probing_packets.size() == pending_timer_transmission_count_) {
1045 break;
1046 }
fayangce0a3162019-08-15 09:05:36 -07001047 }
1048 }
1049 }
1050
1051 for (QuicPacketNumber retransmission : probing_packets) {
1052 QUIC_DVLOG(1) << ENDPOINT << "Marking " << retransmission
1053 << " for probing retransmission";
fayang73d0ac42019-10-31 12:45:31 -07001054 MarkForRetransmission(retransmission, PTO_RETRANSMISSION);
fayangce0a3162019-08-15 09:05:36 -07001055 }
1056 // It is possible that there is not enough outstanding data for probing.
1057}
1058
1059void QuicSentPacketManager::AdjustPendingTimerTransmissions() {
1060 if (pending_timer_transmission_count_ < max_probe_packets_per_pto_) {
1061 // There are packets sent already, clear credit.
1062 pending_timer_transmission_count_ = 0;
1063 return;
1064 }
1065 // No packet gets sent, leave 1 credit to allow data to be write eventually.
1066 pending_timer_transmission_count_ = 1;
1067}
1068
fayang08a6c952019-09-18 14:29:45 -07001069void QuicSentPacketManager::EnableIetfPtoAndLossDetection() {
fayang5d011982020-05-13 14:14:38 -07001070 if (pto_enabled_) {
1071 QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_on_pto, 2, 2);
1072 // Disable handshake mode.
1073 handshake_mode_disabled_ = true;
1074 return;
1075 }
fayang5f135052019-08-22 17:59:40 -07001076 pto_enabled_ = true;
1077 handshake_mode_disabled_ = true;
fayang1c2d1ab2020-03-11 12:08:41 -07001078 // Default to 1 packet per PTO and skip a packet number. Arm the 1st PTO with
1079 // max of earliest in flight sent time + PTO delay and 1.5 * srtt from
1080 // last in flight packet.
1081 max_probe_packets_per_pto_ = 1;
1082 skip_packet_number_for_pto_ = true;
1083 first_pto_srtt_multiplier_ = 1.5;
fayang2f1037e2020-11-30 13:57:07 -08001084 pto_rttvar_multiplier_ = 2;
fayang5f135052019-08-22 17:59:40 -07001085}
1086
fayang7085a6d2019-11-04 07:03:57 -08001087void QuicSentPacketManager::StartExponentialBackoffAfterNthPto(
1088 size_t exponential_backoff_start_point) {
1089 pto_exponential_backoff_start_point_ = exponential_backoff_start_point;
1090}
1091
fayanga39d0362020-06-22 08:57:35 -07001092void QuicSentPacketManager::RetransmitDataOfSpaceIfAny(
1093 PacketNumberSpace space) {
vasilvvf8035162021-02-01 14:49:14 -08001094 QUICHE_DCHECK(supports_multiple_packet_number_spaces());
fayanga39d0362020-06-22 08:57:35 -07001095 if (!unacked_packets_.GetLastInFlightPacketSentTime(space).IsInitialized()) {
1096 // No in flight data of space.
fayang7d4b0172020-06-18 14:05:45 -07001097 return;
1098 }
haoyuewangcbd1dd72021-02-08 11:46:44 -08001099 if (unacked_packets_.empty()) {
1100 return;
1101 }
1102 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
1103 QuicPacketNumber largest_sent_packet = unacked_packets_.largest_sent_packet();
1104 for (; packet_number <= largest_sent_packet; ++packet_number) {
1105 QuicTransmissionInfo* transmission_info =
1106 unacked_packets_.GetMutableTransmissionInfo(packet_number);
1107 if (transmission_info->state == OUTSTANDING &&
1108 unacked_packets_.HasRetransmittableFrames(*transmission_info) &&
1109 unacked_packets_.GetPacketNumberSpace(
1110 transmission_info->encryption_level) == space) {
1111 QUICHE_DCHECK(transmission_info->in_flight);
1112 if (pending_timer_transmission_count_ == 0) {
1113 pending_timer_transmission_count_ = 1;
1114 }
1115 MarkForRetransmission(packet_number, PTO_RETRANSMISSION);
fayang7d4b0172020-06-18 14:05:45 -07001116 return;
1117 }
1118 }
1119}
1120
QUICHE teama6ef0a62019-03-07 20:34:33 -05001121QuicSentPacketManager::RetransmissionTimeoutMode
1122QuicSentPacketManager::GetRetransmissionMode() const {
vasilvvf8035162021-02-01 14:49:14 -08001123 QUICHE_DCHECK(unacked_packets_.HasInFlightPackets() ||
1124 (handshake_mode_disabled_ && !handshake_finished_));
fayang63a19842020-01-23 02:51:28 -08001125 if (!handshake_mode_disabled_ && !handshake_finished_ &&
fayang5f135052019-08-22 17:59:40 -07001126 unacked_packets_.HasPendingCryptoPackets()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001127 return HANDSHAKE_MODE;
1128 }
1129 if (loss_algorithm_->GetLossTimeout() != QuicTime::Zero()) {
1130 return LOSS_MODE;
1131 }
fayang62f867a2019-08-22 12:05:01 -07001132 if (pto_enabled_) {
fayangce0a3162019-08-15 09:05:36 -07001133 return PTO_MODE;
1134 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001135 if (consecutive_tlp_count_ < max_tail_loss_probes_) {
ianswett7ddb34f2019-07-15 12:17:43 -07001136 if (unacked_packets_.HasUnackedRetransmittableFrames()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001137 return TLP_MODE;
1138 }
1139 }
1140 return RTO_MODE;
1141}
1142
1143void QuicSentPacketManager::InvokeLossDetection(QuicTime time) {
1144 if (!packets_acked_.empty()) {
vasilvvf8035162021-02-01 14:49:14 -08001145 QUICHE_DCHECK_LE(packets_acked_.front().packet_number,
1146 packets_acked_.back().packet_number);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001147 largest_newly_acked_ = packets_acked_.back().packet_number;
1148 }
wubaa51f0e2020-05-12 15:08:16 -07001149 LossDetectionInterface::DetectionStats detection_stats =
1150 loss_algorithm_->DetectLosses(unacked_packets_, time, rtt_stats_,
1151 largest_newly_acked_, packets_acked_,
1152 &packets_lost_);
1153
1154 if (detection_stats.sent_packets_max_sequence_reordering >
1155 stats_->sent_packets_max_sequence_reordering) {
1156 stats_->sent_packets_max_sequence_reordering =
1157 detection_stats.sent_packets_max_sequence_reordering;
1158 }
1159
wubd8b383e2020-05-22 07:24:39 -07001160 stats_->sent_packets_num_borderline_time_reorderings +=
1161 detection_stats.sent_packets_num_borderline_time_reorderings;
1162
wub050d2d42020-06-22 14:45:27 -07001163 stats_->total_loss_detection_response_time +=
1164 detection_stats.total_loss_detection_response_time;
1165
QUICHE teama6ef0a62019-03-07 20:34:33 -05001166 for (const LostPacket& packet : packets_lost_) {
wube330aa42020-02-27 07:49:09 -08001167 QuicTransmissionInfo* info =
1168 unacked_packets_.GetMutableTransmissionInfo(packet.packet_number);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001169 ++stats_->packets_lost;
1170 if (debug_delegate_ != nullptr) {
vasilvv923b6d22020-03-23 11:17:58 -07001171 debug_delegate_->OnPacketLoss(packet.packet_number,
1172 info->encryption_level, LOSS_RETRANSMISSION,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001173 time);
1174 }
wube330aa42020-02-27 07:49:09 -08001175 unacked_packets_.RemoveFromInFlight(info);
1176
QUICHE teama6ef0a62019-03-07 20:34:33 -05001177 MarkForRetransmission(packet.packet_number, LOSS_RETRANSMISSION);
1178 }
1179}
1180
1181bool QuicSentPacketManager::MaybeUpdateRTT(QuicPacketNumber largest_acked,
1182 QuicTime::Delta ack_delay_time,
1183 QuicTime ack_receive_time) {
1184 // We rely on ack_delay_time to compute an RTT estimate, so we
danzhb11d12d2021-01-12 10:39:32 -08001185 // only update rtt when the largest observed gets acked and the acked packet
1186 // is not useless.
QUICHE teama6ef0a62019-03-07 20:34:33 -05001187 if (!unacked_packets_.IsUnacked(largest_acked)) {
1188 return false;
1189 }
1190 // We calculate the RTT based on the highest ACKed packet number, the lower
1191 // packet numbers will include the ACK aggregation delay.
1192 const QuicTransmissionInfo& transmission_info =
1193 unacked_packets_.GetTransmissionInfo(largest_acked);
1194 // Ensure the packet has a valid sent time.
1195 if (transmission_info.sent_time == QuicTime::Zero()) {
QUICHE team7939a6e2021-03-16 19:47:54 -07001196 QUIC_BUG(quic_bug_10750_4)
QUICHE team8e6da712021-03-08 10:59:32 -08001197 << "Acked packet has zero sent time, largest_acked:" << largest_acked;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001198 return false;
1199 }
danzhb11d12d2021-01-12 10:39:32 -08001200 if (transmission_info.state == NOT_CONTRIBUTING_RTT) {
1201 return false;
1202 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001203 if (transmission_info.sent_time > ack_receive_time) {
1204 QUIC_CODE_COUNT(quic_receive_acked_before_sending);
1205 }
1206
1207 QuicTime::Delta send_delta = ack_receive_time - transmission_info.sent_time;
wub44e33052020-03-03 17:11:40 -08001208 const bool min_rtt_available = !rtt_stats_.min_rtt().IsZero();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001209 rtt_stats_.UpdateRtt(send_delta, ack_delay_time, ack_receive_time);
1210
wub44e33052020-03-03 17:11:40 -08001211 if (!min_rtt_available && !rtt_stats_.min_rtt().IsZero()) {
1212 loss_algorithm_->OnMinRttAvailable();
1213 }
1214
QUICHE teama6ef0a62019-03-07 20:34:33 -05001215 return true;
1216}
1217
1218QuicTime::Delta QuicSentPacketManager::TimeUntilSend(QuicTime now) const {
1219 // The TLP logic is entirely contained within QuicSentPacketManager, so the
1220 // send algorithm does not need to be consulted.
1221 if (pending_timer_transmission_count_ > 0) {
1222 return QuicTime::Delta::Zero();
1223 }
1224
1225 if (using_pacing_) {
1226 return pacing_sender_.TimeUntilSend(now,
1227 unacked_packets_.bytes_in_flight());
1228 }
1229
1230 return send_algorithm_->CanSend(unacked_packets_.bytes_in_flight())
1231 ? QuicTime::Delta::Zero()
1232 : QuicTime::Delta::Infinite();
1233}
1234
1235const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
fayang5f135052019-08-22 17:59:40 -07001236 if (!unacked_packets_.HasInFlightPackets() &&
fayang53ddf442020-07-16 12:18:44 -07001237 PeerCompletedAddressValidation()) {
fayang5f135052019-08-22 17:59:40 -07001238 return QuicTime::Zero();
1239 }
1240 if (pending_timer_transmission_count_ > 0) {
1241 // Do not set the timer if there is any credit left.
QUICHE teama6ef0a62019-03-07 20:34:33 -05001242 return QuicTime::Zero();
1243 }
fayangd0907232020-06-02 12:56:48 -07001244 PacketNumberSpace packet_number_space;
fayang4d08e812020-07-13 08:28:36 -07001245 if (supports_multiple_packet_number_spaces() &&
fayangd0907232020-06-02 12:56:48 -07001246 unacked_packets_.perspective() == Perspective::IS_SERVER &&
1247 !GetEarliestPacketSentTimeForPto(&packet_number_space).IsInitialized()) {
1248 // Do not set the timer on the server side if the only in flight packets are
1249 // half RTT data.
fayangd0907232020-06-02 12:56:48 -07001250 return QuicTime::Zero();
1251 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001252 switch (GetRetransmissionMode()) {
1253 case HANDSHAKE_MODE:
1254 return unacked_packets_.GetLastCryptoPacketSentTime() +
1255 GetCryptoRetransmissionDelay();
1256 case LOSS_MODE:
1257 return loss_algorithm_->GetLossTimeout();
1258 case TLP_MODE: {
vasilvvf8035162021-02-01 14:49:14 -08001259 QUICHE_DCHECK(!pto_enabled_);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001260 // TODO(ianswett): When CWND is available, it would be preferable to
1261 // set the timer based on the earliest retransmittable packet.
1262 // Base the updated timer on the send time of the last packet.
ianswett479fea32019-09-04 02:51:01 -07001263 const QuicTime sent_time =
1264 unacked_packets_.GetLastInFlightPacketSentTime();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001265 const QuicTime tlp_time = sent_time + GetTailLossProbeDelay();
1266 // Ensure the TLP timer never gets set to a time in the past.
1267 return std::max(clock_->ApproximateNow(), tlp_time);
1268 }
1269 case RTO_MODE: {
vasilvvf8035162021-02-01 14:49:14 -08001270 QUICHE_DCHECK(!pto_enabled_);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001271 // The RTO is based on the first outstanding packet.
ianswett479fea32019-09-04 02:51:01 -07001272 const QuicTime sent_time =
1273 unacked_packets_.GetLastInFlightPacketSentTime();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001274 QuicTime rto_time = sent_time + GetRetransmissionDelay();
1275 // Wait for TLP packets to be acked before an RTO fires.
ianswett479fea32019-09-04 02:51:01 -07001276 QuicTime tlp_time = sent_time + GetTailLossProbeDelay();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001277 return std::max(tlp_time, rto_time);
1278 }
fayangce0a3162019-08-15 09:05:36 -07001279 case PTO_MODE: {
fayang18ff23b2020-01-28 09:19:00 -08001280 if (!supports_multiple_packet_number_spaces()) {
fayangc5d9b2c2020-03-02 11:12:26 -08001281 if (first_pto_srtt_multiplier_ > 0 &&
fayang2ccfbcf2020-02-28 12:37:08 -08001282 unacked_packets_.HasInFlightPackets() &&
1283 consecutive_pto_count_ == 0) {
1284 // Arm 1st PTO with earliest in flight sent time, and make sure at
fayangc5d9b2c2020-03-02 11:12:26 -08001285 // least first_pto_srtt_multiplier_ * RTT has been passed since last
1286 // in flight packet.
fayang2ccfbcf2020-02-28 12:37:08 -08001287 return std::max(
1288 clock_->ApproximateNow(),
1289 std::max(unacked_packets_.GetFirstInFlightTransmissionInfo()
1290 ->sent_time +
fayange1d2a272020-06-26 10:18:41 -07001291 GetProbeTimeoutDelay(NUM_PACKET_NUMBER_SPACES),
fayang2ccfbcf2020-02-28 12:37:08 -08001292 unacked_packets_.GetLastInFlightPacketSentTime() +
fayangc5d9b2c2020-03-02 11:12:26 -08001293 first_pto_srtt_multiplier_ *
1294 rtt_stats_.SmoothedOrInitialRtt()));
fayang2ccfbcf2020-02-28 12:37:08 -08001295 }
fayang18ff23b2020-01-28 09:19:00 -08001296 // Ensure PTO never gets set to a time in the past.
1297 return std::max(clock_->ApproximateNow(),
1298 unacked_packets_.GetLastInFlightPacketSentTime() +
fayange1d2a272020-06-26 10:18:41 -07001299 GetProbeTimeoutDelay(NUM_PACKET_NUMBER_SPACES));
fayang18ff23b2020-01-28 09:19:00 -08001300 }
1301
fayang3ecc53b2020-03-12 07:12:03 -07001302 PacketNumberSpace packet_number_space = NUM_PACKET_NUMBER_SPACES;
fayang2ccfbcf2020-02-28 12:37:08 -08001303 // earliest_right_edge is the earliest sent time of the last in flight
1304 // packet of all packet number spaces.
fayangaecfd532020-04-28 12:35:12 -07001305 QuicTime earliest_right_edge =
fayang2ccfbcf2020-02-28 12:37:08 -08001306 GetEarliestPacketSentTimeForPto(&packet_number_space);
fayangaecfd532020-04-28 12:35:12 -07001307 if (!earliest_right_edge.IsInitialized()) {
1308 // Arm PTO from now if there is no in flight packets.
1309 earliest_right_edge = clock_->ApproximateNow();
1310 }
fayangc5d9b2c2020-03-02 11:12:26 -08001311 if (first_pto_srtt_multiplier_ > 0 &&
fayang2ccfbcf2020-02-28 12:37:08 -08001312 packet_number_space == APPLICATION_DATA &&
1313 consecutive_pto_count_ == 0) {
1314 const QuicTransmissionInfo* first_application_info =
1315 unacked_packets_.GetFirstInFlightTransmissionInfoOfSpace(
1316 APPLICATION_DATA);
1317 if (first_application_info != nullptr) {
1318 // Arm 1st PTO with earliest in flight sent time, and make sure at
fayangc5d9b2c2020-03-02 11:12:26 -08001319 // least first_pto_srtt_multiplier_ * RTT has been passed since last
1320 // in flight packet. Only do this for application data.
fayang2ccfbcf2020-02-28 12:37:08 -08001321 return std::max(
1322 clock_->ApproximateNow(),
1323 std::max(
fayange1d2a272020-06-26 10:18:41 -07001324 first_application_info->sent_time +
1325 GetProbeTimeoutDelay(packet_number_space),
fayangc5d9b2c2020-03-02 11:12:26 -08001326 earliest_right_edge + first_pto_srtt_multiplier_ *
1327 rtt_stats_.SmoothedOrInitialRtt()));
fayang2ccfbcf2020-02-28 12:37:08 -08001328 }
1329 }
fayange1d2a272020-06-26 10:18:41 -07001330 return std::max(
1331 clock_->ApproximateNow(),
1332 earliest_right_edge + GetProbeTimeoutDelay(packet_number_space));
fayangce0a3162019-08-15 09:05:36 -07001333 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001334 }
vasilvvf8035162021-02-01 14:49:14 -08001335 QUICHE_DCHECK(false);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001336 return QuicTime::Zero();
1337}
1338
1339const QuicTime::Delta QuicSentPacketManager::GetPathDegradingDelay() const {
renjietang89b32a62020-11-19 12:32:41 -08001340 if (num_ptos_for_path_degrading_ > 0) {
1341 return num_ptos_for_path_degrading_ * GetPtoDelay();
1342 }
fayang1640cc22020-03-21 14:11:02 -07001343 return GetNConsecutiveRetransmissionTimeoutDelay(
1344 max_tail_loss_probes_ + kNumRetransmissionDelaysForPathDegradingDelay);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001345}
1346
fayangddd3e9d2020-06-03 11:00:19 -07001347const QuicTime::Delta QuicSentPacketManager::GetNetworkBlackholeDelay(
1348 int8_t num_rtos_for_blackhole_detection) const {
fayangb59c6f12020-03-23 15:06:14 -07001349 return GetNConsecutiveRetransmissionTimeoutDelay(
fayangddd3e9d2020-06-03 11:00:19 -07001350 max_tail_loss_probes_ + num_rtos_for_blackhole_detection);
fayangb59c6f12020-03-23 15:06:14 -07001351}
1352
wub8add68a2020-07-27 12:07:38 -07001353QuicTime::Delta QuicSentPacketManager::GetMtuReductionDelay(
1354 int8_t num_rtos_for_blackhole_detection) const {
1355 return GetNetworkBlackholeDelay(num_rtos_for_blackhole_detection / 2);
1356}
1357
QUICHE teama6ef0a62019-03-07 20:34:33 -05001358const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay()
1359 const {
1360 // This is equivalent to the TailLossProbeDelay, but slightly more aggressive
1361 // because crypto handshake messages don't incur a delayed ack time.
1362 QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
1363 int64_t delay_ms;
1364 if (conservative_handshake_retransmits_) {
1365 // Using the delayed ack time directly could cause conservative handshake
1366 // retransmissions to actually be more aggressive than the default.
fkastenholz59c653b2019-07-15 09:55:53 -07001367 delay_ms = std::max(peer_max_ack_delay_.ToMilliseconds(),
QUICHE teama6ef0a62019-03-07 20:34:33 -05001368 static_cast<int64_t>(2 * srtt.ToMilliseconds()));
1369 } else {
1370 delay_ms = std::max(kMinHandshakeTimeoutMs,
1371 static_cast<int64_t>(1.5 * srtt.ToMilliseconds()));
1372 }
1373 return QuicTime::Delta::FromMilliseconds(
1374 delay_ms << consecutive_crypto_retransmission_count_);
1375}
1376
fayang1640cc22020-03-21 14:11:02 -07001377const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001378 QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
fayang1640cc22020-03-21 14:11:02 -07001379 if (enable_half_rtt_tail_loss_probe_ && consecutive_tlp_count_ == 0u) {
zhongyi1b2f7832019-06-14 13:31:34 -07001380 if (unacked_packets().HasUnackedStreamData()) {
1381 // Enable TLPR if there are pending data packets.
1382 return std::max(min_tlp_timeout_, srtt * 0.5);
1383 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001384 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001385 if (!unacked_packets_.HasMultipleInFlightPackets()) {
1386 // This expression really should be using the delayed ack time, but in TCP
1387 // MinRTO was traditionally set to 2x the delayed ack timer and this
1388 // expression assumed QUIC did the same.
1389 return std::max(2 * srtt, 1.5 * srtt + (min_rto_timeout_ * 0.5));
1390 }
1391 return std::max(min_tlp_timeout_, 2 * srtt);
1392}
1393
fayang1640cc22020-03-21 14:11:02 -07001394const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001395 QuicTime::Delta retransmission_delay = QuicTime::Delta::Zero();
1396 if (rtt_stats_.smoothed_rtt().IsZero()) {
1397 // We are in the initial state, use default timeout values.
1398 retransmission_delay =
1399 QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs);
1400 } else {
1401 retransmission_delay =
1402 rtt_stats_.smoothed_rtt() + 4 * rtt_stats_.mean_deviation();
1403 if (retransmission_delay < min_rto_timeout_) {
1404 retransmission_delay = min_rto_timeout_;
1405 }
1406 }
1407
1408 // Calculate exponential back off.
1409 retransmission_delay =
1410 retransmission_delay *
fayang1640cc22020-03-21 14:11:02 -07001411 (1 << std::min<size_t>(consecutive_rto_count_, kMaxRetransmissions));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001412
1413 if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) {
1414 return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs);
1415 }
1416 return retransmission_delay;
1417}
1418
fayange1d2a272020-06-26 10:18:41 -07001419const QuicTime::Delta QuicSentPacketManager::GetProbeTimeoutDelay(
1420 PacketNumberSpace space) const {
vasilvvf8035162021-02-01 14:49:14 -08001421 QUICHE_DCHECK(pto_enabled_);
fayangce0a3162019-08-15 09:05:36 -07001422 if (rtt_stats_.smoothed_rtt().IsZero()) {
fayang6c7313c2020-04-23 12:10:35 -07001423 // Respect kMinHandshakeTimeoutMs to avoid a potential amplification attack.
QUICHE team7939a6e2021-03-16 19:47:54 -07001424 QUIC_BUG_IF(quic_bug_12552_6, rtt_stats_.initial_rtt().IsZero());
fayangbc9f56f2020-06-19 03:49:22 -07001425 return std::max(
1426 pto_multiplier_without_rtt_samples_ * rtt_stats_.initial_rtt(),
1427 QuicTime::Delta::FromMilliseconds(kMinHandshakeTimeoutMs)) *
fayang6c7313c2020-04-23 12:10:35 -07001428 (1 << consecutive_pto_count_);
fayangce0a3162019-08-15 09:05:36 -07001429 }
fayang76467152020-09-14 10:36:14 -07001430 if (enable_half_rtt_tail_loss_probe_ && consecutive_pto_count_ == 0 &&
fayang23206ea2020-07-29 08:29:05 -07001431 handshake_finished_) {
fayang23206ea2020-07-29 08:29:05 -07001432 return std::max(min_tlp_timeout_, rtt_stats_.smoothed_rtt() * 0.5);
1433 }
fayangc2fd6102020-03-02 17:27:38 -08001434 const QuicTime::Delta rtt_var = use_standard_deviation_for_pto_
1435 ? rtt_stats_.GetStandardOrMeanDeviation()
1436 : rtt_stats_.mean_deviation();
fayang4aa22402020-01-07 11:36:07 -08001437 QuicTime::Delta pto_delay =
fayangce0a3162019-08-15 09:05:36 -07001438 rtt_stats_.smoothed_rtt() +
fayangc2fd6102020-03-02 17:27:38 -08001439 std::max(pto_rttvar_multiplier_ * rtt_var, kAlarmGranularity) +
fayange1d2a272020-06-26 10:18:41 -07001440 (ShouldAddMaxAckDelay(space) ? peer_max_ack_delay_
1441 : QuicTime::Delta::Zero());
fayang4aa22402020-01-07 11:36:07 -08001442 pto_delay =
1443 pto_delay * (1 << (consecutive_pto_count_ -
1444 std::min(consecutive_pto_count_,
1445 pto_exponential_backoff_start_point_)));
1446 if (consecutive_pto_count_ < num_tlp_timeout_ptos_) {
1447 // Make first n PTOs similar to TLPs.
1448 if (pto_delay > 2 * rtt_stats_.smoothed_rtt()) {
1449 QUIC_CODE_COUNT(quic_delayed_pto);
1450 pto_delay = std::max(kAlarmGranularity, 2 * rtt_stats_.smoothed_rtt());
1451 } else {
1452 QUIC_CODE_COUNT(quic_faster_pto);
1453 }
1454 }
1455 return pto_delay;
fayangce0a3162019-08-15 09:05:36 -07001456}
1457
wub967ba572019-04-01 09:27:52 -07001458QuicTime::Delta QuicSentPacketManager::GetSlowStartDuration() const {
wubbe29b9e2019-11-24 06:56:04 -08001459 if (send_algorithm_->GetCongestionControlType() == kBBR ||
1460 send_algorithm_->GetCongestionControlType() == kBBRv2) {
1461 return stats_->slowstart_duration.GetTotalElapsedTime(
1462 clock_->ApproximateNow());
wub967ba572019-04-01 09:27:52 -07001463 }
wubbe29b9e2019-11-24 06:56:04 -08001464 return QuicTime::Delta::Infinite();
wub967ba572019-04-01 09:27:52 -07001465}
1466
vasilvvc48c8712019-03-11 13:38:16 -07001467std::string QuicSentPacketManager::GetDebugState() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001468 return send_algorithm_->GetDebugState();
1469}
1470
QUICHE teama6ef0a62019-03-07 20:34:33 -05001471void QuicSentPacketManager::SetSendAlgorithm(
1472 CongestionControlType congestion_control_type) {
wub32a9f8a2020-03-16 09:01:35 -07001473 if (send_algorithm_ &&
1474 send_algorithm_->GetCongestionControlType() == congestion_control_type) {
1475 return;
wub18773d62020-01-28 14:14:06 -08001476 }
wub32a9f8a2020-03-16 09:01:35 -07001477
QUICHE teama6ef0a62019-03-07 20:34:33 -05001478 SetSendAlgorithm(SendAlgorithmInterface::Create(
QUICHE team73957f12019-04-18 16:21:52 -07001479 clock_, &rtt_stats_, &unacked_packets_, congestion_control_type, random_,
wub0abcd8f2020-03-30 16:24:50 -07001480 stats_, initial_congestion_window_, send_algorithm_.get()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001481}
1482
1483void QuicSentPacketManager::SetSendAlgorithm(
1484 SendAlgorithmInterface* send_algorithm) {
1485 send_algorithm_.reset(send_algorithm);
1486 pacing_sender_.set_sender(send_algorithm);
1487}
1488
danzhb11d12d2021-01-12 10:39:32 -08001489std::unique_ptr<SendAlgorithmInterface>
1490QuicSentPacketManager::OnConnectionMigration(bool reset_send_algorithm) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001491 consecutive_rto_count_ = 0;
1492 consecutive_tlp_count_ = 0;
fayangce0a3162019-08-15 09:05:36 -07001493 consecutive_pto_count_ = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001494 rtt_stats_.OnConnectionMigration();
danzhb11d12d2021-01-12 10:39:32 -08001495 if (!reset_send_algorithm) {
1496 send_algorithm_->OnConnectionMigration();
1497 return nullptr;
1498 }
1499
1500 std::unique_ptr<SendAlgorithmInterface> old_send_algorithm =
1501 std::move(send_algorithm_);
1502 SetSendAlgorithm(old_send_algorithm->GetCongestionControlType());
1503 // Treat all in flight packets sent to the old peer address as lost and
1504 // retransmit them.
1505 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
1506 for (auto it = unacked_packets_.begin(); it != unacked_packets_.end();
1507 ++it, ++packet_number) {
1508 if (it->in_flight) {
1509 // Proactively retransmit any packet which is in flight on the old path.
1510 // As a result, these packets will not contribute to congestion control.
1511 unacked_packets_.RemoveFromInFlight(packet_number);
1512 // Retransmitting these packets with PATH_CHANGE_RETRANSMISSION will mark
1513 // them as useless, thus not contributing to RTT stats.
danzha6906502021-01-25 09:10:59 -08001514 if (unacked_packets_.HasRetransmittableFrames(packet_number)) {
1515 MarkForRetransmission(packet_number, PATH_RETRANSMISSION);
vasilvvf8035162021-02-01 14:49:14 -08001516 QUICHE_DCHECK_EQ(it->state, NOT_CONTRIBUTING_RTT);
danzha6906502021-01-25 09:10:59 -08001517 }
danzhb11d12d2021-01-12 10:39:32 -08001518 }
danzha6906502021-01-25 09:10:59 -08001519 it->state = NOT_CONTRIBUTING_RTT;
danzhb11d12d2021-01-12 10:39:32 -08001520 }
1521 return old_send_algorithm;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001522}
1523
1524void QuicSentPacketManager::OnAckFrameStart(QuicPacketNumber largest_acked,
1525 QuicTime::Delta ack_delay_time,
1526 QuicTime ack_receive_time) {
vasilvvf8035162021-02-01 14:49:14 -08001527 QUICHE_DCHECK(packets_acked_.empty());
1528 QUICHE_DCHECK_LE(largest_acked, unacked_packets_.largest_sent_packet());
wub81c9b662020-02-14 09:08:07 -08001529 if (ack_delay_time > peer_max_ack_delay()) {
wub8ee29a02019-12-12 13:06:48 -08001530 ack_delay_time = peer_max_ack_delay();
1531 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001532 rtt_updated_ =
1533 MaybeUpdateRTT(largest_acked, ack_delay_time, ack_receive_time);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001534 last_ack_frame_.ack_delay_time = ack_delay_time;
1535 acked_packets_iter_ = last_ack_frame_.packets.rbegin();
1536}
1537
1538void QuicSentPacketManager::OnAckRange(QuicPacketNumber start,
1539 QuicPacketNumber end) {
1540 if (!last_ack_frame_.largest_acked.IsInitialized() ||
1541 end > last_ack_frame_.largest_acked + 1) {
1542 // Largest acked increases.
1543 unacked_packets_.IncreaseLargestAcked(end - 1);
1544 last_ack_frame_.largest_acked = end - 1;
1545 }
1546 // Drop ack ranges which ack packets below least_unacked.
1547 QuicPacketNumber least_unacked = unacked_packets_.GetLeastUnacked();
1548 if (least_unacked.IsInitialized() && end <= least_unacked) {
1549 return;
1550 }
1551 start = std::max(start, least_unacked);
1552 do {
1553 QuicPacketNumber newly_acked_start = start;
1554 if (acked_packets_iter_ != last_ack_frame_.packets.rend()) {
1555 newly_acked_start = std::max(start, acked_packets_iter_->max());
1556 }
1557 for (QuicPacketNumber acked = end - 1; acked >= newly_acked_start;
1558 --acked) {
1559 // Check if end is above the current range. If so add newly acked packets
1560 // in descending order.
1561 packets_acked_.push_back(AckedPacket(acked, 0, QuicTime::Zero()));
1562 if (acked == FirstSendingPacketNumber()) {
1563 break;
1564 }
1565 }
1566 if (acked_packets_iter_ == last_ack_frame_.packets.rend() ||
1567 start > acked_packets_iter_->min()) {
1568 // Finish adding all newly acked packets.
1569 return;
1570 }
1571 end = std::min(end, acked_packets_iter_->min());
1572 ++acked_packets_iter_;
1573 } while (start < end);
1574}
1575
1576void QuicSentPacketManager::OnAckTimestamp(QuicPacketNumber packet_number,
1577 QuicTime timestamp) {
1578 last_ack_frame_.received_packet_times.push_back({packet_number, timestamp});
1579 for (AckedPacket& packet : packets_acked_) {
1580 if (packet.packet_number == packet_number) {
1581 packet.receive_timestamp = timestamp;
1582 return;
1583 }
1584 }
1585}
1586
fayang3eb82212019-04-16 12:05:46 -07001587AckResult QuicSentPacketManager::OnAckFrameEnd(
1588 QuicTime ack_receive_time,
fayangf8e918b2019-07-16 13:03:16 -07001589 QuicPacketNumber ack_packet_number,
fayang3eb82212019-04-16 12:05:46 -07001590 EncryptionLevel ack_decrypted_level) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001591 QuicByteCount prior_bytes_in_flight = unacked_packets_.bytes_in_flight();
1592 // Reverse packets_acked_ so that it is in ascending order.
wubc0a1df42019-11-15 08:49:59 -08001593 std::reverse(packets_acked_.begin(), packets_acked_.end());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001594 for (AckedPacket& acked_packet : packets_acked_) {
1595 QuicTransmissionInfo* info =
1596 unacked_packets_.GetMutableTransmissionInfo(acked_packet.packet_number);
1597 if (!QuicUtils::IsAckable(info->state)) {
1598 if (info->state == ACKED) {
QUICHE team7939a6e2021-03-16 19:47:54 -07001599 QUIC_BUG(quic_bug_10750_5)
QUICHE team8e6da712021-03-08 10:59:32 -08001600 << "Trying to ack an already acked packet: "
1601 << acked_packet.packet_number
1602 << ", last_ack_frame_: " << last_ack_frame_
1603 << ", least_unacked: " << unacked_packets_.GetLeastUnacked()
1604 << ", packets_acked_: " << packets_acked_;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001605 } else {
QUICHE team7939a6e2021-03-16 19:47:54 -07001606 QUIC_PEER_BUG(quic_peer_bug_10750_6)
QUICHE team8e6da712021-03-08 10:59:32 -08001607 << "Received " << ack_decrypted_level
1608 << " ack for unackable packet: " << acked_packet.packet_number
1609 << " with state: "
1610 << QuicUtils::SentPacketStateToString(info->state);
fayang3eb82212019-04-16 12:05:46 -07001611 if (supports_multiple_packet_number_spaces()) {
1612 if (info->state == NEVER_SENT) {
1613 return UNSENT_PACKETS_ACKED;
1614 }
1615 return UNACKABLE_PACKETS_ACKED;
1616 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001617 }
1618 continue;
1619 }
renjietangb4ebb1d2020-05-27 18:15:51 -07001620 QUIC_DVLOG(1) << ENDPOINT << "Got an " << ack_decrypted_level
fayang19d2d5b2019-09-11 14:22:03 -07001621 << " ack for packet " << acked_packet.packet_number
1622 << " , state: "
1623 << QuicUtils::SentPacketStateToString(info->state);
fayang3eb82212019-04-16 12:05:46 -07001624 const PacketNumberSpace packet_number_space =
fayangbf3d2862019-06-20 14:13:44 -07001625 unacked_packets_.GetPacketNumberSpace(info->encryption_level);
fayang3eb82212019-04-16 12:05:46 -07001626 if (supports_multiple_packet_number_spaces() &&
1627 QuicUtils::GetPacketNumberSpace(ack_decrypted_level) !=
1628 packet_number_space) {
1629 return PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE;
1630 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001631 last_ack_frame_.packets.Add(acked_packet.packet_number);
fayang53ddf442020-07-16 12:18:44 -07001632 if (info->encryption_level == ENCRYPTION_HANDSHAKE) {
1633 handshake_packet_acked_ = true;
fayangf2e0d902020-09-25 14:47:19 -07001634 } else if (info->encryption_level == ENCRYPTION_ZERO_RTT) {
1635 zero_rtt_packet_acked_ = true;
1636 } else if (info->encryption_level == ENCRYPTION_FORWARD_SECURE) {
fayang2f2915d2020-01-24 06:47:15 -08001637 one_rtt_packet_acked_ = true;
1638 }
QUICHE teamc264e362019-03-19 14:21:06 -07001639 largest_packet_peer_knows_is_acked_.UpdateMax(info->largest_acked);
QUICHE teamc279cec2019-03-22 06:51:48 -07001640 if (supports_multiple_packet_number_spaces()) {
fayang3eb82212019-04-16 12:05:46 -07001641 largest_packets_peer_knows_is_acked_[packet_number_space].UpdateMax(
1642 info->largest_acked);
QUICHE teamc279cec2019-03-22 06:51:48 -07001643 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001644 // If data is associated with the most recent transmission of this
1645 // packet, then inform the caller.
1646 if (info->in_flight) {
1647 acked_packet.bytes_acked = info->bytes_sent;
1648 } else {
1649 // Unackable packets are skipped earlier.
1650 largest_newly_acked_ = acked_packet.packet_number;
1651 }
fayangbf3d2862019-06-20 14:13:44 -07001652 unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
1653 packet_number_space, acked_packet.packet_number);
fayang19d2d5b2019-09-11 14:22:03 -07001654 MarkPacketHandled(acked_packet.packet_number, info, ack_receive_time,
QUICHE team9467db02019-05-30 09:38:45 -07001655 last_ack_frame_.ack_delay_time,
1656 acked_packet.receive_timestamp);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001657 }
1658 const bool acked_new_packet = !packets_acked_.empty();
vasilvv923b6d22020-03-23 11:17:58 -07001659 PostProcessNewlyAckedPackets(ack_packet_number, ack_decrypted_level,
1660 last_ack_frame_, ack_receive_time, rtt_updated_,
fayang3eb82212019-04-16 12:05:46 -07001661 prior_bytes_in_flight);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001662
fayang3eb82212019-04-16 12:05:46 -07001663 return acked_new_packet ? PACKETS_NEWLY_ACKED : NO_PACKETS_NEWLY_ACKED;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001664}
1665
1666void QuicSentPacketManager::SetDebugDelegate(DebugDelegate* debug_delegate) {
1667 debug_delegate_ = debug_delegate;
1668}
1669
1670void QuicSentPacketManager::OnApplicationLimited() {
1671 if (using_pacing_) {
1672 pacing_sender_.OnApplicationLimited();
1673 }
1674 send_algorithm_->OnApplicationLimited(unacked_packets_.bytes_in_flight());
1675 if (debug_delegate_ != nullptr) {
1676 debug_delegate_->OnApplicationLimited();
1677 }
1678}
1679
wubed245d22020-05-07 10:46:00 -07001680NextReleaseTimeResult QuicSentPacketManager::GetNextReleaseTime() const {
1681 if (!using_pacing_) {
1682 return {QuicTime::Zero(), false};
1683 }
1684
1685 return pacing_sender_.GetNextReleaseTime();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001686}
1687
1688void QuicSentPacketManager::SetInitialRtt(QuicTime::Delta rtt) {
1689 const QuicTime::Delta min_rtt =
1690 QuicTime::Delta::FromMicroseconds(kMinInitialRoundTripTimeUs);
fayangde9ad9f2020-09-16 10:27:16 -07001691 QuicTime::Delta max_rtt =
QUICHE teama6ef0a62019-03-07 20:34:33 -05001692 QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs);
1693 rtt_stats_.set_initial_rtt(std::max(min_rtt, std::min(max_rtt, rtt)));
1694}
1695
QUICHE teamc279cec2019-03-22 06:51:48 -07001696void QuicSentPacketManager::EnableMultiplePacketNumberSpacesSupport() {
fayang18ff23b2020-01-28 09:19:00 -08001697 EnableIetfPtoAndLossDetection();
QUICHE teamc279cec2019-03-22 06:51:48 -07001698 unacked_packets_.EnableMultiplePacketNumberSpacesSupport();
1699}
1700
1701QuicPacketNumber QuicSentPacketManager::GetLargestAckedPacket(
1702 EncryptionLevel decrypted_packet_level) const {
vasilvvf8035162021-02-01 14:49:14 -08001703 QUICHE_DCHECK(supports_multiple_packet_number_spaces());
QUICHE teamc279cec2019-03-22 06:51:48 -07001704 return unacked_packets_.GetLargestAckedOfPacketNumberSpace(
1705 QuicUtils::GetPacketNumberSpace(decrypted_packet_level));
1706}
1707
dschinazi101d2eb2020-07-06 19:42:34 -07001708QuicPacketNumber QuicSentPacketManager::GetLeastPacketAwaitedByPeer(
1709 EncryptionLevel encryption_level) const {
dschinazi101d2eb2020-07-06 19:42:34 -07001710 QuicPacketNumber largest_acked;
1711 if (supports_multiple_packet_number_spaces()) {
1712 largest_acked = GetLargestAckedPacket(encryption_level);
1713 } else {
1714 largest_acked = GetLargestObserved();
1715 }
1716 if (!largest_acked.IsInitialized()) {
1717 // If no packets have been acked, return the first sent packet to ensure
1718 // we use a large enough packet number length.
1719 return FirstSendingPacketNumber();
1720 }
1721 QuicPacketNumber least_awaited = largest_acked + 1;
1722 QuicPacketNumber least_unacked = GetLeastUnacked();
1723 if (least_unacked.IsInitialized() && least_unacked < least_awaited) {
1724 least_awaited = least_unacked;
1725 }
1726 return least_awaited;
1727}
1728
QUICHE teamc279cec2019-03-22 06:51:48 -07001729QuicPacketNumber QuicSentPacketManager::GetLargestPacketPeerKnowsIsAcked(
1730 EncryptionLevel decrypted_packet_level) const {
vasilvvf8035162021-02-01 14:49:14 -08001731 QUICHE_DCHECK(supports_multiple_packet_number_spaces());
QUICHE teamc279cec2019-03-22 06:51:48 -07001732 return largest_packets_peer_knows_is_acked_[QuicUtils::GetPacketNumberSpace(
1733 decrypted_packet_level)];
1734}
1735
fayang1640cc22020-03-21 14:11:02 -07001736QuicTime::Delta
1737QuicSentPacketManager::GetNConsecutiveRetransmissionTimeoutDelay(
1738 int num_timeouts) const {
1739 QuicTime::Delta total_delay = QuicTime::Delta::Zero();
1740 const QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
1741 int num_tlps =
1742 std::min(num_timeouts, static_cast<int>(max_tail_loss_probes_));
1743 num_timeouts -= num_tlps;
1744 if (num_tlps > 0) {
1745 if (enable_half_rtt_tail_loss_probe_ &&
1746 unacked_packets().HasUnackedStreamData()) {
1747 total_delay = total_delay + std::max(min_tlp_timeout_, srtt * 0.5);
1748 --num_tlps;
1749 }
1750 if (num_tlps > 0) {
1751 const QuicTime::Delta tlp_delay =
1752 std::max(2 * srtt, unacked_packets_.HasMultipleInFlightPackets()
1753 ? min_tlp_timeout_
1754 : (1.5 * srtt + (min_rto_timeout_ * 0.5)));
1755 total_delay = total_delay + num_tlps * tlp_delay;
1756 }
1757 }
1758 if (num_timeouts == 0) {
1759 return total_delay;
1760 }
1761
1762 const QuicTime::Delta retransmission_delay =
1763 rtt_stats_.smoothed_rtt().IsZero()
1764 ? QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs)
1765 : std::max(srtt + 4 * rtt_stats_.mean_deviation(), min_rto_timeout_);
1766 total_delay = total_delay + ((1 << num_timeouts) - 1) * retransmission_delay;
1767 return total_delay;
1768}
1769
fayang53ddf442020-07-16 12:18:44 -07001770bool QuicSentPacketManager::PeerCompletedAddressValidation() const {
1771 if (unacked_packets_.perspective() == Perspective::IS_SERVER ||
1772 !handshake_mode_disabled_) {
1773 return true;
1774 }
1775
1776 // To avoid handshake deadlock due to anti-amplification limit, client needs
1777 // to set PTO timer until server successfully processed any HANDSHAKE packet.
1778 return handshake_finished_ || handshake_packet_acked_;
1779}
1780
fayang001c8282020-07-29 12:39:29 -07001781bool QuicSentPacketManager::IsLessThanThreePTOs(QuicTime::Delta timeout) const {
fayangc7f8b472020-08-19 16:26:15 -07001782 return timeout < 3 * GetPtoDelay();
1783}
1784
1785QuicTime::Delta QuicSentPacketManager::GetPtoDelay() const {
1786 return pto_enabled_ ? GetProbeTimeoutDelay(APPLICATION_DATA)
1787 : GetRetransmissionDelay();
fayang001c8282020-07-29 12:39:29 -07001788}
1789
haoyuewang5b0f14f2020-09-18 14:31:54 -07001790void QuicSentPacketManager::OnAckFrequencyFrameSent(
1791 const QuicAckFrequencyFrame& ack_frequency_frame) {
1792 in_use_sent_ack_delays_.emplace_back(ack_frequency_frame.max_ack_delay,
1793 ack_frequency_frame.sequence_number);
1794 if (ack_frequency_frame.max_ack_delay > peer_max_ack_delay_) {
1795 peer_max_ack_delay_ = ack_frequency_frame.max_ack_delay;
1796 }
1797}
1798
1799void QuicSentPacketManager::OnAckFrequencyFrameAcked(
1800 const QuicAckFrequencyFrame& ack_frequency_frame) {
1801 int stale_entry_count = 0;
1802 for (auto it = in_use_sent_ack_delays_.cbegin();
1803 it != in_use_sent_ack_delays_.cend(); ++it) {
1804 if (it->second < ack_frequency_frame.sequence_number) {
1805 ++stale_entry_count;
1806 } else {
1807 break;
1808 }
1809 }
1810 if (stale_entry_count > 0) {
1811 in_use_sent_ack_delays_.pop_front_n(stale_entry_count);
1812 }
1813 if (in_use_sent_ack_delays_.empty()) {
QUICHE team7939a6e2021-03-16 19:47:54 -07001814 QUIC_BUG(quic_bug_10750_7) << "in_use_sent_ack_delays_ is empty.";
haoyuewang5b0f14f2020-09-18 14:31:54 -07001815 return;
1816 }
1817 peer_max_ack_delay_ = std::max_element(in_use_sent_ack_delays_.cbegin(),
1818 in_use_sent_ack_delays_.cend())
1819 ->first;
1820}
1821
QUICHE teama6ef0a62019-03-07 20:34:33 -05001822#undef ENDPOINT // undef for jumbo builds
1823} // namespace quic