blob: 132eb0af9def6c9989bcb4beb12dbd9182e198dd [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
5#include "net/third_party/quiche/src/quic/core/quic_sent_packet_manager.h"
6
7#include <algorithm>
vasilvv872e7a32019-03-12 16:42:44 -07008#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -05009
10#include "net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.h"
11#include "net/third_party/quiche/src/quic/core/congestion_control/pacing_sender.h"
12#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
dschinazi56fb53e2019-06-21 15:30:04 -070013#include "net/third_party/quiche/src/quic/core/proto/cached_network_parameters_proto.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050014#include "net/third_party/quiche/src/quic/core/quic_connection_stats.h"
15#include "net/third_party/quiche/src/quic/core/quic_pending_retransmission.h"
wub967ba572019-04-01 09:27:52 -070016#include "net/third_party/quiche/src/quic/core/quic_types.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050017#include "net/third_party/quiche/src/quic/core/quic_utils.h"
18#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
19#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
20#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
21#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
22#include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050023
24namespace quic {
25
26namespace {
27static const int64_t kDefaultRetransmissionTimeMs = 500;
28static const int64_t kMaxRetransmissionTimeMs = 60000;
29// Maximum number of exponential backoffs used for RTO timeouts.
30static const size_t kMaxRetransmissions = 10;
31// Maximum number of packets retransmitted upon an RTO.
32static const size_t kMaxRetransmissionsOnTimeout = 2;
33// The path degrading delay is the sum of this number of consecutive RTO delays.
34const size_t kNumRetransmissionDelaysForPathDegradingDelay = 2;
35
36// Ensure the handshake timer isnt't faster than 10ms.
37// This limits the tenth retransmitted packet to 10s after the initial CHLO.
38static const int64_t kMinHandshakeTimeoutMs = 10;
39
40// Sends up to two tail loss probes before firing an RTO,
41// per draft RFC draft-dukkipati-tcpm-tcp-loss-probe.
42static const size_t kDefaultMaxTailLossProbes = 2;
43
44inline bool HasCryptoHandshake(const QuicTransmissionInfo& transmission_info) {
45 DCHECK(!transmission_info.has_crypto_handshake ||
46 !transmission_info.retransmittable_frames.empty());
47 return transmission_info.has_crypto_handshake;
48}
49
QUICHE teama6ef0a62019-03-07 20:34:33 -050050// Returns true of retransmissions of the specified type should retransmit
51// the frames directly (as opposed to resulting in a loss notification).
52inline bool ShouldForceRetransmission(TransmissionType transmission_type) {
53 return transmission_type == HANDSHAKE_RETRANSMISSION ||
54 transmission_type == TLP_RETRANSMISSION ||
55 transmission_type == PROBING_RETRANSMISSION ||
56 transmission_type == RTO_RETRANSMISSION;
57}
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
fayangd6b31432019-09-18 06:26:59 -070070QuicSentPacketManager::ScopedCreditGrantor::ScopedCreditGrantor(
71 QuicSentPacketManager* manager)
72 : manager_(manager), credits_granted_(false) {
73 if (!GetQuicReloadableFlag(quic_grant_enough_credits)) {
74 return;
75 }
76 QUIC_RELOADABLE_FLAG_COUNT(quic_grant_enough_credits);
77 if (manager_->pending_timer_transmission_count() > 1) {
78 // There are enough credits to retransmit one packet.
79 return;
80 }
81 // Grant 2 credits because a single packet can be transmitted as 2 (if packet
82 // number length changes).
83 manager_->set_pending_timer_transmission_count(2);
84 credits_granted_ = true;
85}
86
87QuicSentPacketManager::ScopedCreditGrantor::~ScopedCreditGrantor() {
88 if (!credits_granted_) {
89 // Do not clear credits if there is no credit granted.
90 return;
91 }
92 manager_->set_pending_timer_transmission_count(0);
93}
94
QUICHE teama6ef0a62019-03-07 20:34:33 -050095QuicSentPacketManager::QuicSentPacketManager(
96 Perspective perspective,
97 const QuicClock* clock,
QUICHE team73957f12019-04-18 16:21:52 -070098 QuicRandom* random,
QUICHE teama6ef0a62019-03-07 20:34:33 -050099 QuicConnectionStats* stats,
100 CongestionControlType congestion_control_type,
101 LossDetectionType loss_type)
102 : unacked_packets_(perspective),
103 clock_(clock),
QUICHE team73957f12019-04-18 16:21:52 -0700104 random_(random),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500105 stats_(stats),
106 debug_delegate_(nullptr),
107 network_change_visitor_(nullptr),
108 initial_congestion_window_(kInitialCongestionWindow),
wub37ec5962019-04-03 09:02:51 -0700109 loss_algorithm_(GetInitialLossAlgorithm()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500110 uber_loss_algorithm_(loss_type),
111 consecutive_rto_count_(0),
112 consecutive_tlp_count_(0),
113 consecutive_crypto_retransmission_count_(0),
114 pending_timer_transmission_count_(0),
115 max_tail_loss_probes_(kDefaultMaxTailLossProbes),
116 max_rto_packets_(kMaxRetransmissionsOnTimeout),
117 enable_half_rtt_tail_loss_probe_(false),
118 using_pacing_(false),
119 use_new_rto_(false),
120 conservative_handshake_retransmits_(false),
121 min_tlp_timeout_(
122 QuicTime::Delta::FromMilliseconds(kMinTailLossProbeTimeoutMs)),
123 min_rto_timeout_(
124 QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs)),
125 ietf_style_tlp_(false),
126 ietf_style_2x_tlp_(false),
127 largest_mtu_acked_(0),
128 handshake_confirmed_(false),
fkastenholz59c653b2019-07-15 09:55:53 -0700129 peer_max_ack_delay_(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500130 QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)),
131 rtt_updated_(false),
QUICHE team9929cc42019-03-13 08:17:43 -0700132 acked_packets_iter_(last_ack_frame_.packets.rbegin()),
fayang62f867a2019-08-22 12:05:01 -0700133 pto_enabled_(false),
fayangce0a3162019-08-15 09:05:36 -0700134 max_probe_packets_per_pto_(2),
135 consecutive_pto_count_(0),
fayang5f135052019-08-22 17:59:40 -0700136 fix_rto_retransmission_(false),
fayang19d2d5b2019-09-11 14:22:03 -0700137 handshake_mode_disabled_(false),
138 detect_spurious_losses_(
139 GetQuicReloadableFlag(quic_detect_spurious_loss)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500140 SetSendAlgorithm(congestion_control_type);
141}
142
wub37ec5962019-04-03 09:02:51 -0700143LossDetectionInterface* QuicSentPacketManager::GetInitialLossAlgorithm() {
fayangbf3d2862019-06-20 14:13:44 -0700144 return &uber_loss_algorithm_;
wub37ec5962019-04-03 09:02:51 -0700145}
146
QUICHE teama6ef0a62019-03-07 20:34:33 -0500147QuicSentPacketManager::~QuicSentPacketManager() {}
148
149void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
150 const Perspective perspective = unacked_packets_.perspective();
151 if (config.HasReceivedInitialRoundTripTimeUs() &&
152 config.ReceivedInitialRoundTripTimeUs() > 0) {
153 if (!config.HasClientSentConnectionOption(kNRTT, perspective)) {
154 SetInitialRtt(QuicTime::Delta::FromMicroseconds(
155 config.ReceivedInitialRoundTripTimeUs()));
156 }
157 } else if (config.HasInitialRoundTripTimeUsToSend() &&
158 config.GetInitialRoundTripTimeUsToSend() > 0) {
159 SetInitialRtt(QuicTime::Delta::FromMicroseconds(
160 config.GetInitialRoundTripTimeUsToSend()));
161 }
ianswett43eefae2019-08-02 12:27:15 -0700162 if (config.HasReceivedMaxAckDelayMs()) {
163 peer_max_ack_delay_ =
164 QuicTime::Delta::FromMilliseconds(config.ReceivedMaxAckDelayMs());
165 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500166 if (config.HasClientSentConnectionOption(kMAD0, perspective)) {
167 rtt_stats_.set_ignore_max_ack_delay(true);
168 }
169 if (config.HasClientSentConnectionOption(kMAD1, perspective)) {
ianswett43eefae2019-08-02 12:27:15 -0700170 rtt_stats_.set_initial_max_ack_delay(peer_max_ack_delay_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500171 }
ianswettdcc474e2019-08-06 08:22:38 -0700172 if (GetQuicReloadableFlag(quic_sent_packet_manager_cleanup)) {
173 QUIC_RELOADABLE_FLAG_COUNT(quic_sent_packet_manager_cleanup);
174 if (config.HasClientSentConnectionOption(kMAD2, perspective)) {
175 // Set the minimum to the alarm granularity.
176 min_tlp_timeout_ = QuicTime::Delta::FromMilliseconds(1);
177 }
178 if (config.HasClientSentConnectionOption(kMAD3, perspective)) {
179 // Set the minimum to the alarm granularity.
180 min_rto_timeout_ = QuicTime::Delta::FromMilliseconds(1);
181 }
182 } else {
183 if (config.HasClientSentConnectionOption(kMAD2, perspective)) {
184 min_tlp_timeout_ = QuicTime::Delta::Zero();
185 }
186 if (config.HasClientSentConnectionOption(kMAD3, perspective)) {
187 min_rto_timeout_ = QuicTime::Delta::Zero();
188 }
189 if (config.HasClientSentConnectionOption(kMAD4, perspective)) {
190 ietf_style_tlp_ = true;
191 }
192 if (config.HasClientSentConnectionOption(kMAD5, perspective)) {
193 ietf_style_2x_tlp_ = true;
194 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500195 }
196
fayangce0a3162019-08-15 09:05:36 -0700197 if (GetQuicReloadableFlag(quic_enable_pto) && fix_rto_retransmission_) {
198 if (config.HasClientSentConnectionOption(k2PTO, perspective)) {
fayang62f867a2019-08-22 12:05:01 -0700199 pto_enabled_ = true;
fayangce0a3162019-08-15 09:05:36 -0700200 QUIC_RELOADABLE_FLAG_COUNT_N(quic_enable_pto, 2, 4);
201 }
202 if (config.HasClientSentConnectionOption(k1PTO, perspective)) {
fayang62f867a2019-08-22 12:05:01 -0700203 pto_enabled_ = true;
fayangce0a3162019-08-15 09:05:36 -0700204 max_probe_packets_per_pto_ = 1;
205 QUIC_RELOADABLE_FLAG_COUNT_N(quic_enable_pto, 1, 4);
206 }
207 }
208
QUICHE teama6ef0a62019-03-07 20:34:33 -0500209 // Configure congestion control.
210 if (config.HasClientRequestedIndependentOption(kTBBR, perspective)) {
211 SetSendAlgorithm(kBBR);
212 }
wuba9a43cb2019-07-17 15:22:42 -0700213 if (GetQuicReloadableFlag(quic_allow_client_enabled_bbr_v2) &&
214 config.HasClientRequestedIndependentOption(kB2ON, perspective)) {
215 QUIC_RELOADABLE_FLAG_COUNT(quic_allow_client_enabled_bbr_v2);
216 SetSendAlgorithm(kBBRv2);
217 }
218
QUICHE teama6ef0a62019-03-07 20:34:33 -0500219 if (config.HasClientRequestedIndependentOption(kRENO, perspective)) {
220 SetSendAlgorithm(kRenoBytes);
221 } else if (config.HasClientRequestedIndependentOption(kBYTE, perspective) ||
222 (GetQuicReloadableFlag(quic_default_to_bbr) &&
223 config.HasClientRequestedIndependentOption(kQBIC, perspective))) {
224 SetSendAlgorithm(kCubicBytes);
225 } else if (GetQuicReloadableFlag(quic_enable_pcc3) &&
226 config.HasClientRequestedIndependentOption(kTPCC, perspective)) {
227 SetSendAlgorithm(kPCC);
228 }
wuba9a43cb2019-07-17 15:22:42 -0700229
QUICHE teama6ef0a62019-03-07 20:34:33 -0500230 // Initial window.
231 if (GetQuicReloadableFlag(quic_unified_iw_options)) {
232 if (config.HasClientRequestedIndependentOption(kIW03, perspective)) {
233 initial_congestion_window_ = 3;
234 send_algorithm_->SetInitialCongestionWindowInPackets(3);
235 }
236 if (config.HasClientRequestedIndependentOption(kIW10, perspective)) {
237 initial_congestion_window_ = 10;
238 send_algorithm_->SetInitialCongestionWindowInPackets(10);
239 }
240 if (config.HasClientRequestedIndependentOption(kIW20, perspective)) {
241 initial_congestion_window_ = 20;
242 send_algorithm_->SetInitialCongestionWindowInPackets(20);
243 }
244 if (config.HasClientRequestedIndependentOption(kIW50, perspective)) {
245 initial_congestion_window_ = 50;
246 send_algorithm_->SetInitialCongestionWindowInPackets(50);
247 }
248 }
249
danzh88e3e052019-06-13 11:47:18 -0700250 using_pacing_ = !GetQuicFlag(FLAGS_quic_disable_pacing_for_perf_tests);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500251
QUICHE teama6ef0a62019-03-07 20:34:33 -0500252 if (config.HasClientSentConnectionOption(kNTLP, perspective)) {
253 max_tail_loss_probes_ = 0;
254 }
255 if (config.HasClientSentConnectionOption(k1TLP, perspective)) {
256 max_tail_loss_probes_ = 1;
257 }
258 if (config.HasClientSentConnectionOption(k1RTO, perspective)) {
259 max_rto_packets_ = 1;
260 }
261 if (config.HasClientSentConnectionOption(kTLPR, perspective)) {
262 enable_half_rtt_tail_loss_probe_ = true;
263 }
264 if (config.HasClientSentConnectionOption(kNRTO, perspective)) {
265 use_new_rto_ = true;
266 }
267 // Configure loss detection.
268 if (config.HasClientRequestedIndependentOption(kTIME, perspective)) {
fayangbf3d2862019-06-20 14:13:44 -0700269 uber_loss_algorithm_.SetLossDetectionType(kTime);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500270 }
271 if (config.HasClientRequestedIndependentOption(kATIM, perspective)) {
fayangbf3d2862019-06-20 14:13:44 -0700272 uber_loss_algorithm_.SetLossDetectionType(kAdaptiveTime);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500273 }
274 if (config.HasClientRequestedIndependentOption(kLFAK, perspective)) {
fayangbf3d2862019-06-20 14:13:44 -0700275 uber_loss_algorithm_.SetLossDetectionType(kLazyFack);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500276 }
fayangb0c7b4b2019-09-12 06:45:24 -0700277 if (GetQuicReloadableFlag(quic_enable_ietf_loss_detection)) {
278 if (config.HasClientRequestedIndependentOption(kILD0, perspective)) {
279 QUIC_RELOADABLE_FLAG_COUNT_N(quic_enable_ietf_loss_detection, 1, 4);
280 uber_loss_algorithm_.SetLossDetectionType(kIetfLossDetection);
281 }
282 if (config.HasClientRequestedIndependentOption(kILD1, perspective)) {
283 QUIC_RELOADABLE_FLAG_COUNT_N(quic_enable_ietf_loss_detection, 2, 4);
284 uber_loss_algorithm_.SetLossDetectionType(kIetfLossDetection);
285 uber_loss_algorithm_.SetReorderingShift(kDefaultLossDelayShift);
286 }
287 if (GetQuicReloadableFlag(quic_detect_spurious_loss)) {
288 if (config.HasClientRequestedIndependentOption(kILD2, perspective)) {
289 QUIC_RELOADABLE_FLAG_COUNT_N(quic_enable_ietf_loss_detection, 3, 4);
290 uber_loss_algorithm_.SetLossDetectionType(kIetfLossDetection);
291 uber_loss_algorithm_.EnableAdaptiveReorderingThreshold();
292 }
293 if (config.HasClientRequestedIndependentOption(kILD3, perspective)) {
294 QUIC_RELOADABLE_FLAG_COUNT_N(quic_enable_ietf_loss_detection, 4, 4);
295 uber_loss_algorithm_.SetLossDetectionType(kIetfLossDetection);
296 uber_loss_algorithm_.SetReorderingShift(kDefaultLossDelayShift);
297 uber_loss_algorithm_.EnableAdaptiveReorderingThreshold();
298 }
299 }
300 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500301 if (config.HasClientSentConnectionOption(kCONH, perspective)) {
302 conservative_handshake_retransmits_ = true;
303 }
304 send_algorithm_->SetFromConfig(config, perspective);
305
306 if (network_change_visitor_ != nullptr) {
307 network_change_visitor_->OnCongestionChange();
308 }
309}
310
311void QuicSentPacketManager::ResumeConnectionState(
312 const CachedNetworkParameters& cached_network_params,
313 bool max_bandwidth_resumption) {
314 QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(
315 max_bandwidth_resumption
316 ? cached_network_params.max_bandwidth_estimate_bytes_per_second()
317 : cached_network_params.bandwidth_estimate_bytes_per_second());
318 QuicTime::Delta rtt =
319 QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms());
fayangf1b99dc2019-05-14 06:29:18 -0700320 AdjustNetworkParameters(bandwidth, rtt, /*allow_cwnd_to_decrease=*/false);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500321}
322
fayangf1b99dc2019-05-14 06:29:18 -0700323void QuicSentPacketManager::AdjustNetworkParameters(
324 QuicBandwidth bandwidth,
325 QuicTime::Delta rtt,
326 bool allow_cwnd_to_decrease) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500327 if (!rtt.IsZero()) {
328 SetInitialRtt(rtt);
329 }
fayangbe83ecd2019-04-26 13:58:09 -0700330 const QuicByteCount old_cwnd = send_algorithm_->GetCongestionWindow();
fayang6c2d64f2019-05-20 17:12:05 -0700331 if (GetQuicReloadableFlag(quic_conservative_bursts) && using_pacing_ &&
332 !bandwidth.IsZero()) {
fayang4ba55982019-05-13 05:53:22 -0700333 QUIC_RELOADABLE_FLAG_COUNT(quic_conservative_bursts);
334 pacing_sender_.SetBurstTokens(kConservativeUnpacedBurst);
335 }
fayangf1b99dc2019-05-14 06:29:18 -0700336 send_algorithm_->AdjustNetworkParameters(bandwidth, rtt,
337 allow_cwnd_to_decrease);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500338 if (debug_delegate_ != nullptr) {
fayangbe83ecd2019-04-26 13:58:09 -0700339 debug_delegate_->OnAdjustNetworkParameters(
fayangef9c8f92019-04-29 13:35:13 -0700340 bandwidth, rtt.IsZero() ? rtt_stats_.SmoothedOrInitialRtt() : rtt,
341 old_cwnd, send_algorithm_->GetCongestionWindow());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500342 }
343}
344
345void QuicSentPacketManager::SetHandshakeConfirmed() {
346 handshake_confirmed_ = true;
fayangbf3d2862019-06-20 14:13:44 -0700347 NeuterHandshakePackets();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500348}
349
fayang3eb82212019-04-16 12:05:46 -0700350void QuicSentPacketManager::PostProcessNewlyAckedPackets(
fayangf8e918b2019-07-16 13:03:16 -0700351 QuicPacketNumber ack_packet_number,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500352 const QuicAckFrame& ack_frame,
353 QuicTime ack_receive_time,
354 bool rtt_updated,
355 QuicByteCount prior_bytes_in_flight) {
356 if (session_decides_what_to_write()) {
357 unacked_packets_.NotifyAggregatedStreamFrameAcked(
358 last_ack_frame_.ack_delay_time);
359 }
360 InvokeLossDetection(ack_receive_time);
361 // Ignore losses in RTO mode.
362 if (consecutive_rto_count_ > 0 && !use_new_rto_) {
363 packets_lost_.clear();
364 }
365 MaybeInvokeCongestionEvent(rtt_updated, prior_bytes_in_flight,
366 ack_receive_time);
367 unacked_packets_.RemoveObsoletePackets();
368
369 sustained_bandwidth_recorder_.RecordEstimate(
370 send_algorithm_->InRecovery(), send_algorithm_->InSlowStart(),
371 send_algorithm_->BandwidthEstimate(), ack_receive_time, clock_->WallNow(),
372 rtt_stats_.smoothed_rtt());
373
374 // Anytime we are making forward progress and have a new RTT estimate, reset
375 // the backoff counters.
376 if (rtt_updated) {
377 if (consecutive_rto_count_ > 0) {
378 // If the ack acknowledges data sent prior to the RTO,
379 // the RTO was spurious.
380 if (LargestAcked(ack_frame) < first_rto_transmission_) {
381 // Replace SRTT with latest_rtt and increase the variance to prevent
382 // a spurious RTO from happening again.
383 rtt_stats_.ExpireSmoothedMetrics();
384 } else {
385 if (!use_new_rto_) {
386 send_algorithm_->OnRetransmissionTimeout(true);
387 }
388 }
389 }
390 // Reset all retransmit counters any time a new packet is acked.
391 consecutive_rto_count_ = 0;
392 consecutive_tlp_count_ = 0;
fayangce0a3162019-08-15 09:05:36 -0700393 consecutive_pto_count_ = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500394 consecutive_crypto_retransmission_count_ = 0;
395 }
396
397 if (debug_delegate_ != nullptr) {
fayangf8e918b2019-07-16 13:03:16 -0700398 debug_delegate_->OnIncomingAck(ack_packet_number, ack_frame,
399 ack_receive_time, LargestAcked(ack_frame),
400 rtt_updated, GetLeastUnacked());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500401 }
402 // Remove packets below least unacked from all_packets_acked_ and
403 // last_ack_frame_.
404 last_ack_frame_.packets.RemoveUpTo(unacked_packets_.GetLeastUnacked());
405 last_ack_frame_.received_packet_times.clear();
406}
407
408void QuicSentPacketManager::MaybeInvokeCongestionEvent(
409 bool rtt_updated,
410 QuicByteCount prior_in_flight,
411 QuicTime event_time) {
412 if (!rtt_updated && packets_acked_.empty() && packets_lost_.empty()) {
413 return;
414 }
415 if (using_pacing_) {
416 pacing_sender_.OnCongestionEvent(rtt_updated, prior_in_flight, event_time,
417 packets_acked_, packets_lost_);
418 } else {
419 send_algorithm_->OnCongestionEvent(rtt_updated, prior_in_flight, event_time,
420 packets_acked_, packets_lost_);
421 }
422 packets_acked_.clear();
423 packets_lost_.clear();
424 if (network_change_visitor_ != nullptr) {
425 network_change_visitor_->OnCongestionChange();
426 }
427}
428
429void QuicSentPacketManager::RetransmitUnackedPackets(
430 TransmissionType retransmission_type) {
431 DCHECK(retransmission_type == ALL_UNACKED_RETRANSMISSION ||
432 retransmission_type == ALL_INITIAL_RETRANSMISSION);
433 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
ianswett898306b2019-04-23 11:05:57 -0700434 for (QuicUnackedPacketMap::iterator it = unacked_packets_.begin();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500435 it != unacked_packets_.end(); ++it, ++packet_number) {
436 if ((retransmission_type == ALL_UNACKED_RETRANSMISSION ||
ianswett898306b2019-04-23 11:05:57 -0700437 it->encryption_level == ENCRYPTION_ZERO_RTT)) {
ianswett04004652019-09-03 18:46:57 -0700438 if (it->in_flight) {
ianswett898306b2019-04-23 11:05:57 -0700439 // Remove 0-RTT packets and packets of the wrong version from flight,
440 // because neither can be processed by the peer.
441 unacked_packets_.RemoveFromInFlight(&*it);
442 }
443 if (unacked_packets_.HasRetransmittableFrames(*it)) {
444 MarkForRetransmission(packet_number, retransmission_type);
445 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500446 }
447 }
ianswett898306b2019-04-23 11:05:57 -0700448 if (retransmission_type == ALL_UNACKED_RETRANSMISSION &&
449 unacked_packets_.bytes_in_flight() > 0) {
450 QUIC_BUG << "RetransmitUnackedPackets should remove all packets from flight"
451 << ", bytes_in_flight:" << unacked_packets_.bytes_in_flight();
452 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500453}
454
455void QuicSentPacketManager::NeuterUnencryptedPackets() {
456 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
457 if (session_decides_what_to_write()) {
458 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
459 it != unacked_packets_.end(); ++it, ++packet_number) {
460 if (!it->retransmittable_frames.empty() &&
QUICHE team6987b4a2019-03-15 16:23:04 -0700461 it->encryption_level == ENCRYPTION_INITIAL) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500462 // Once the connection swithes to forward secure, no unencrypted packets
463 // will be sent. The data has been abandoned in the cryto stream. Remove
464 // it from in flight.
465 unacked_packets_.RemoveFromInFlight(packet_number);
466 }
467 }
468 return;
469 }
470 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
471 it != unacked_packets_.end(); ++it, ++packet_number) {
ianswett898306b2019-04-23 11:05:57 -0700472 if (it->encryption_level == ENCRYPTION_INITIAL) {
ianswett04004652019-09-03 18:46:57 -0700473 // Once you're forward secure, no unencrypted packets will be sent,
474 // crypto or otherwise. Unencrypted packets are neutered and abandoned,
475 // to ensure they are not retransmitted or considered lost from a
476 // congestion control perspective.
477 pending_retransmissions_.erase(packet_number);
478 unacked_packets_.RemoveFromInFlight(packet_number);
479 unacked_packets_.RemoveRetransmittability(packet_number);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500480 }
481 }
482}
483
484void QuicSentPacketManager::NeuterHandshakePackets() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500485 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
486 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
487 it != unacked_packets_.end(); ++it, ++packet_number) {
488 if (session_decides_what_to_write()) {
489 if (!it->retransmittable_frames.empty() &&
490 unacked_packets_.GetPacketNumberSpace(it->encryption_level) ==
491 HANDSHAKE_DATA) {
492 unacked_packets_.RemoveFromInFlight(packet_number);
493 }
494 continue;
495 }
496 if (unacked_packets_.GetPacketNumberSpace(it->encryption_level) ==
497 HANDSHAKE_DATA &&
498 unacked_packets_.HasRetransmittableFrames(*it)) {
499 pending_retransmissions_.erase(packet_number);
500 unacked_packets_.RemoveFromInFlight(packet_number);
501 unacked_packets_.RemoveRetransmittability(packet_number);
502 }
503 }
504}
505
506void QuicSentPacketManager::MarkForRetransmission(
507 QuicPacketNumber packet_number,
508 TransmissionType transmission_type) {
509 QuicTransmissionInfo* transmission_info =
510 unacked_packets_.GetMutableTransmissionInfo(packet_number);
511 // When session decides what to write, a previous RTO retransmission may cause
512 // connection close; packets without retransmittable frames can be marked for
513 // loss retransmissions.
514 QUIC_BUG_IF((transmission_type != LOSS_RETRANSMISSION &&
515 (!session_decides_what_to_write() ||
516 transmission_type != RTO_RETRANSMISSION)) &&
517 !unacked_packets_.HasRetransmittableFrames(*transmission_info))
518 << "transmission_type: "
519 << QuicUtils::TransmissionTypeToString(transmission_type);
520 // Handshake packets should never be sent as probing retransmissions.
fayang62f867a2019-08-22 12:05:01 -0700521 DCHECK(pto_enabled_ || !transmission_info->has_crypto_handshake ||
QUICHE teama6ef0a62019-03-07 20:34:33 -0500522 transmission_type != PROBING_RETRANSMISSION);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500523 if (!session_decides_what_to_write()) {
524 if (!unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
525 return;
526 }
527 if (!QuicContainsKey(pending_retransmissions_, packet_number)) {
528 pending_retransmissions_[packet_number] = transmission_type;
529 }
530 return;
531 }
532
533 HandleRetransmission(transmission_type, transmission_info);
534
535 // Update packet state according to transmission type.
536 transmission_info->state =
537 QuicUtils::RetransmissionTypeToPacketState(transmission_type);
538}
539
540void QuicSentPacketManager::HandleRetransmission(
541 TransmissionType transmission_type,
542 QuicTransmissionInfo* transmission_info) {
543 DCHECK(session_decides_what_to_write());
544 if (ShouldForceRetransmission(transmission_type)) {
545 // TODO(fayang): Consider to make RTO and PROBING retransmission
546 // strategies be configurable by applications. Today, TLP, RTO and PROBING
547 // retransmissions are handled similarly, i.e., always retranmist the
548 // oldest outstanding data. This is not ideal in general because different
549 // applications may want different strategies. For example, some
550 // applications may want to use higher priority stream data for bandwidth
551 // probing, and some applications want to consider RTO is an indication of
552 // loss, etc.
fayangd6b31432019-09-18 06:26:59 -0700553 ScopedCreditGrantor grantor(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500554 unacked_packets_.RetransmitFrames(*transmission_info, transmission_type);
555 return;
556 }
557
558 unacked_packets_.NotifyFramesLost(*transmission_info, transmission_type);
559 if (transmission_info->retransmittable_frames.empty()) {
560 return;
561 }
562
563 if (transmission_type == LOSS_RETRANSMISSION) {
564 // Record the first packet sent after loss, which allows to wait 1
565 // more RTT before giving up on this lost packet.
566 transmission_info->retransmission =
567 unacked_packets_.largest_sent_packet() + 1;
568 } else {
569 // Clear the recorded first packet sent after loss when version or
570 // encryption changes.
571 transmission_info->retransmission.Clear();
572 }
573}
574
575void QuicSentPacketManager::RecordOneSpuriousRetransmission(
576 const QuicTransmissionInfo& info) {
577 stats_->bytes_spuriously_retransmitted += info.bytes_sent;
578 ++stats_->packets_spuriously_retransmitted;
579 if (debug_delegate_ != nullptr) {
580 debug_delegate_->OnSpuriousPacketRetransmission(info.transmission_type,
581 info.bytes_sent);
582 }
583}
584
585void QuicSentPacketManager::RecordSpuriousRetransmissions(
586 const QuicTransmissionInfo& info,
587 QuicPacketNumber acked_packet_number) {
588 if (session_decides_what_to_write()) {
589 RecordOneSpuriousRetransmission(info);
fayang19d2d5b2019-09-11 14:22:03 -0700590 if (!detect_spurious_losses_ &&
591 info.transmission_type == LOSS_RETRANSMISSION) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500592 // Only inform the loss detection of spurious retransmits it caused.
593 loss_algorithm_->SpuriousRetransmitDetected(
594 unacked_packets_, clock_->Now(), rtt_stats_, acked_packet_number);
595 }
596 return;
597 }
598 QuicPacketNumber retransmission = info.retransmission;
599 while (retransmission.IsInitialized()) {
600 const QuicTransmissionInfo& retransmit_info =
601 unacked_packets_.GetTransmissionInfo(retransmission);
602 retransmission = retransmit_info.retransmission;
603 RecordOneSpuriousRetransmission(retransmit_info);
604 }
605 // Only inform the loss detection of spurious retransmits it caused.
606 if (unacked_packets_.GetTransmissionInfo(info.retransmission)
607 .transmission_type == LOSS_RETRANSMISSION) {
608 loss_algorithm_->SpuriousRetransmitDetected(
609 unacked_packets_, clock_->Now(), rtt_stats_, info.retransmission);
610 }
611}
612
613QuicPendingRetransmission QuicSentPacketManager::NextPendingRetransmission() {
614 QUIC_BUG_IF(pending_retransmissions_.empty())
615 << "Unexpected call to NextPendingRetransmission() with empty pending "
616 << "retransmission list. Corrupted memory usage imminent.";
617 QUIC_BUG_IF(session_decides_what_to_write())
618 << "Unexpected call to NextPendingRetransmission() when session handles "
619 "retransmissions";
620 QuicPacketNumber packet_number = pending_retransmissions_.begin()->first;
621 TransmissionType transmission_type = pending_retransmissions_.begin()->second;
622 if (unacked_packets_.HasPendingCryptoPackets()) {
623 // Ensure crypto packets are retransmitted before other packets.
624 for (const auto& pair : pending_retransmissions_) {
625 if (HasCryptoHandshake(
626 unacked_packets_.GetTransmissionInfo(pair.first))) {
627 packet_number = pair.first;
628 transmission_type = pair.second;
629 break;
630 }
631 }
632 }
633 DCHECK(unacked_packets_.IsUnacked(packet_number)) << packet_number;
634 const QuicTransmissionInfo& transmission_info =
635 unacked_packets_.GetTransmissionInfo(packet_number);
636 DCHECK(unacked_packets_.HasRetransmittableFrames(transmission_info));
637
638 return QuicPendingRetransmission(packet_number, transmission_type,
639 transmission_info);
640}
641
642QuicPacketNumber QuicSentPacketManager::GetNewestRetransmission(
643 QuicPacketNumber packet_number,
644 const QuicTransmissionInfo& transmission_info) const {
645 if (session_decides_what_to_write()) {
646 return packet_number;
647 }
648 QuicPacketNumber retransmission = transmission_info.retransmission;
649 while (retransmission.IsInitialized()) {
650 packet_number = retransmission;
651 retransmission =
652 unacked_packets_.GetTransmissionInfo(retransmission).retransmission;
653 }
654 return packet_number;
655}
656
657void QuicSentPacketManager::MarkPacketHandled(QuicPacketNumber packet_number,
658 QuicTransmissionInfo* info,
fayang19d2d5b2019-09-11 14:22:03 -0700659 QuicTime ack_receive_time,
QUICHE team9467db02019-05-30 09:38:45 -0700660 QuicTime::Delta ack_delay_time,
661 QuicTime receive_timestamp) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500662 QuicPacketNumber newest_transmission =
663 GetNewestRetransmission(packet_number, *info);
664 // Remove the most recent packet, if it is pending retransmission.
665 pending_retransmissions_.erase(newest_transmission);
666
667 if (newest_transmission == packet_number) {
668 // Try to aggregate acked stream frames if acked packet is not a
669 // retransmission.
670 const bool fast_path = session_decides_what_to_write() &&
671 info->transmission_type == NOT_RETRANSMISSION;
672 if (fast_path) {
QUICHE team9467db02019-05-30 09:38:45 -0700673 unacked_packets_.MaybeAggregateAckedStreamFrame(*info, ack_delay_time,
674 receive_timestamp);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500675 } else {
676 if (session_decides_what_to_write()) {
677 unacked_packets_.NotifyAggregatedStreamFrameAcked(ack_delay_time);
678 }
QUICHE team9467db02019-05-30 09:38:45 -0700679 const bool new_data_acked = unacked_packets_.NotifyFramesAcked(
680 *info, ack_delay_time, receive_timestamp);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500681 if (session_decides_what_to_write() && !new_data_acked &&
682 info->transmission_type != NOT_RETRANSMISSION) {
683 // Record as a spurious retransmission if this packet is a
684 // retransmission and no new data gets acked.
685 QUIC_DVLOG(1) << "Detect spurious retransmitted packet "
686 << packet_number << " transmission type: "
687 << QuicUtils::TransmissionTypeToString(
688 info->transmission_type);
689 RecordSpuriousRetransmissions(*info, packet_number);
690 }
691 }
fayang19d2d5b2019-09-11 14:22:03 -0700692 if (detect_spurious_losses_ && session_decides_what_to_write() &&
693 info->state == LOST) {
694 // Record as a spurious loss as a packet previously declared lost gets
695 // acked.
696 QUIC_RELOADABLE_FLAG_COUNT(quic_detect_spurious_loss);
697 const PacketNumberSpace packet_number_space =
698 unacked_packets_.GetPacketNumberSpace(info->encryption_level);
699 const QuicPacketNumber previous_largest_acked =
700 supports_multiple_packet_number_spaces()
701 ? unacked_packets_.GetLargestAckedOfPacketNumberSpace(
702 packet_number_space)
703 : unacked_packets_.largest_acked();
704 QUIC_DVLOG(1) << "Packet " << packet_number
705 << " was detected lost spuriously, "
706 "previous_largest_acked: "
707 << previous_largest_acked;
708 loss_algorithm_->SpuriousLossDetected(unacked_packets_, rtt_stats_,
709 ack_receive_time, packet_number,
710 previous_largest_acked);
711 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500712 } else {
713 DCHECK(!session_decides_what_to_write());
714 RecordSpuriousRetransmissions(*info, packet_number);
715 // Remove the most recent packet from flight if it's a crypto handshake
716 // packet, since they won't be acked now that one has been processed.
717 // Other crypto handshake packets won't be in flight, only the newest
718 // transmission of a crypto packet is in flight at once.
719 // TODO(ianswett): Instead of handling all crypto packets special,
ianswett479fea32019-09-04 02:51:01 -0700720 // only handle null encrypted packets in a special way.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500721 const QuicTransmissionInfo& newest_transmission_info =
722 unacked_packets_.GetTransmissionInfo(newest_transmission);
QUICHE team9467db02019-05-30 09:38:45 -0700723 unacked_packets_.NotifyFramesAcked(newest_transmission_info, ack_delay_time,
724 receive_timestamp);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500725 if (HasCryptoHandshake(newest_transmission_info)) {
726 unacked_packets_.RemoveFromInFlight(newest_transmission);
727 }
728 }
729
730 if (network_change_visitor_ != nullptr &&
731 info->bytes_sent > largest_mtu_acked_) {
732 largest_mtu_acked_ = info->bytes_sent;
733 network_change_visitor_->OnPathMtuIncreased(largest_mtu_acked_);
734 }
735 unacked_packets_.RemoveFromInFlight(info);
736 unacked_packets_.RemoveRetransmittability(info);
737 info->state = ACKED;
738}
739
740bool QuicSentPacketManager::OnPacketSent(
741 SerializedPacket* serialized_packet,
742 QuicPacketNumber original_packet_number,
743 QuicTime sent_time,
744 TransmissionType transmission_type,
745 HasRetransmittableData has_retransmittable_data) {
746 QuicPacketNumber packet_number = serialized_packet->packet_number;
747 DCHECK_LE(FirstSendingPacketNumber(), packet_number);
748 DCHECK(!unacked_packets_.IsUnacked(packet_number));
749 QUIC_BUG_IF(serialized_packet->encrypted_length == 0)
750 << "Cannot send empty packets.";
751
752 if (original_packet_number.IsInitialized()) {
753 pending_retransmissions_.erase(original_packet_number);
754 }
755
756 if (pending_timer_transmission_count_ > 0) {
757 --pending_timer_transmission_count_;
758 }
759
760 bool in_flight = has_retransmittable_data == HAS_RETRANSMITTABLE_DATA;
761 if (using_pacing_) {
762 pacing_sender_.OnPacketSent(
763 sent_time, unacked_packets_.bytes_in_flight(), packet_number,
764 serialized_packet->encrypted_length, has_retransmittable_data);
765 } else {
766 send_algorithm_->OnPacketSent(
767 sent_time, unacked_packets_.bytes_in_flight(), packet_number,
768 serialized_packet->encrypted_length, has_retransmittable_data);
769 }
770
771 unacked_packets_.AddSentPacket(serialized_packet, original_packet_number,
772 transmission_type, sent_time, in_flight);
773 // Reset the retransmission timer anytime a pending packet is sent.
774 return in_flight;
775}
776
fayang67f82272019-08-14 16:08:45 -0700777QuicSentPacketManager::RetransmissionTimeoutMode
778QuicSentPacketManager::OnRetransmissionTimeout() {
fayang5f135052019-08-22 17:59:40 -0700779 DCHECK(unacked_packets_.HasInFlightPackets() ||
780 (handshake_mode_disabled_ && !handshake_confirmed_));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500781 DCHECK_EQ(0u, pending_timer_transmission_count_);
782 // Handshake retransmission, timer based loss detection, TLP, and RTO are
783 // implemented with a single alarm. The handshake alarm is set when the
784 // handshake has not completed, the loss alarm is set when the loss detection
785 // algorithm says to, and the TLP and RTO alarms are set after that.
786 // The TLP alarm is always set to run for under an RTO.
787 switch (GetRetransmissionMode()) {
788 case HANDSHAKE_MODE:
fayang5f135052019-08-22 17:59:40 -0700789 DCHECK(!handshake_mode_disabled_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500790 ++stats_->crypto_retransmit_count;
791 RetransmitCryptoPackets();
fayang67f82272019-08-14 16:08:45 -0700792 return HANDSHAKE_MODE;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500793 case LOSS_MODE: {
794 ++stats_->loss_timeout_count;
795 QuicByteCount prior_in_flight = unacked_packets_.bytes_in_flight();
796 const QuicTime now = clock_->Now();
797 InvokeLossDetection(now);
798 MaybeInvokeCongestionEvent(false, prior_in_flight, now);
fayang67f82272019-08-14 16:08:45 -0700799 return LOSS_MODE;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500800 }
801 case TLP_MODE:
802 ++stats_->tlp_count;
803 ++consecutive_tlp_count_;
804 pending_timer_transmission_count_ = 1;
805 // TLPs prefer sending new data instead of retransmitting data, so
806 // give the connection a chance to write before completing the TLP.
fayang67f82272019-08-14 16:08:45 -0700807 return TLP_MODE;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500808 case RTO_MODE:
809 ++stats_->rto_count;
810 RetransmitRtoPackets();
fayang67f82272019-08-14 16:08:45 -0700811 return RTO_MODE;
fayangce0a3162019-08-15 09:05:36 -0700812 case PTO_MODE:
813 QUIC_DVLOG(1) << ENDPOINT << "PTO mode";
814 ++stats_->pto_count;
815 ++consecutive_pto_count_;
816 pending_timer_transmission_count_ = max_probe_packets_per_pto_;
817 return PTO_MODE;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500818 }
819}
820
821void QuicSentPacketManager::RetransmitCryptoPackets() {
822 DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode());
823 ++consecutive_crypto_retransmission_count_;
824 bool packet_retransmitted = false;
825 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
826 std::vector<QuicPacketNumber> crypto_retransmissions;
827 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
828 it != unacked_packets_.end(); ++it, ++packet_number) {
829 // Only retransmit frames which are in flight, and therefore have been sent.
830 if (!it->in_flight ||
831 (session_decides_what_to_write() && it->state != OUTSTANDING) ||
832 !it->has_crypto_handshake ||
833 !unacked_packets_.HasRetransmittableFrames(*it)) {
834 continue;
835 }
836 packet_retransmitted = true;
837 if (session_decides_what_to_write()) {
838 crypto_retransmissions.push_back(packet_number);
839 } else {
840 MarkForRetransmission(packet_number, HANDSHAKE_RETRANSMISSION);
841 }
842 ++pending_timer_transmission_count_;
843 }
844 DCHECK(packet_retransmitted) << "No crypto packets found to retransmit.";
845 if (session_decides_what_to_write()) {
846 for (QuicPacketNumber retransmission : crypto_retransmissions) {
847 MarkForRetransmission(retransmission, HANDSHAKE_RETRANSMISSION);
848 }
849 }
850}
851
852bool QuicSentPacketManager::MaybeRetransmitTailLossProbe() {
fayang62f867a2019-08-22 12:05:01 -0700853 DCHECK(!pto_enabled_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500854 if (pending_timer_transmission_count_ == 0) {
855 return false;
856 }
857 if (!MaybeRetransmitOldestPacket(TLP_RETRANSMISSION)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500858 return false;
859 }
860 return true;
861}
862
863bool QuicSentPacketManager::MaybeRetransmitOldestPacket(TransmissionType type) {
864 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
865 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
866 it != unacked_packets_.end(); ++it, ++packet_number) {
867 // Only retransmit frames which are in flight, and therefore have been sent.
868 if (!it->in_flight ||
869 (session_decides_what_to_write() && it->state != OUTSTANDING) ||
870 !unacked_packets_.HasRetransmittableFrames(*it)) {
871 continue;
872 }
873 MarkForRetransmission(packet_number, type);
874 return true;
875 }
876 QUIC_DVLOG(1)
877 << "No retransmittable packets, so RetransmitOldestPacket failed.";
878 return false;
879}
880
881void QuicSentPacketManager::RetransmitRtoPackets() {
fayang62f867a2019-08-22 12:05:01 -0700882 DCHECK(!pto_enabled_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500883 QUIC_BUG_IF(pending_timer_transmission_count_ > 0)
884 << "Retransmissions already queued:" << pending_timer_transmission_count_;
885 // Mark two packets for retransmission.
886 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
887 std::vector<QuicPacketNumber> retransmissions;
888 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
889 it != unacked_packets_.end(); ++it, ++packet_number) {
890 if ((!session_decides_what_to_write() || it->state == OUTSTANDING) &&
891 unacked_packets_.HasRetransmittableFrames(*it) &&
892 pending_timer_transmission_count_ < max_rto_packets_) {
893 if (session_decides_what_to_write()) {
894 retransmissions.push_back(packet_number);
895 } else {
896 MarkForRetransmission(packet_number, RTO_RETRANSMISSION);
897 }
898 ++pending_timer_transmission_count_;
899 }
900 // Abandon non-retransmittable data that's in flight to ensure it doesn't
901 // fill up the congestion window.
902 bool has_retransmissions = it->retransmission.IsInitialized();
903 if (session_decides_what_to_write()) {
904 has_retransmissions = it->state != OUTSTANDING;
905 }
fayanga29eb242019-07-16 12:25:38 -0700906 if (!fix_rto_retransmission_ && it->in_flight && !has_retransmissions &&
QUICHE teama6ef0a62019-03-07 20:34:33 -0500907 !unacked_packets_.HasRetransmittableFrames(*it)) {
908 // Log only for non-retransmittable data.
909 // Retransmittable data is marked as lost during loss detection, and will
910 // be logged later.
911 unacked_packets_.RemoveFromInFlight(packet_number);
912 if (debug_delegate_ != nullptr) {
913 debug_delegate_->OnPacketLoss(packet_number, RTO_RETRANSMISSION,
914 clock_->Now());
915 }
916 }
917 }
918 if (pending_timer_transmission_count_ > 0) {
919 if (consecutive_rto_count_ == 0) {
920 first_rto_transmission_ = unacked_packets_.largest_sent_packet() + 1;
921 }
922 ++consecutive_rto_count_;
923 }
924 if (session_decides_what_to_write()) {
925 for (QuicPacketNumber retransmission : retransmissions) {
926 MarkForRetransmission(retransmission, RTO_RETRANSMISSION);
927 }
fayanga29eb242019-07-16 12:25:38 -0700928 if (fix_rto_retransmission_ && retransmissions.empty()) {
929 QUIC_BUG_IF(pending_timer_transmission_count_ != 0);
930 // No packets to be RTO retransmitted, raise up a credit to allow
931 // connection to send.
932 QUIC_CODE_COUNT(no_packets_to_be_rto_retransmitted);
933 pending_timer_transmission_count_ = 1;
934 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500935 }
936}
937
fayangce0a3162019-08-15 09:05:36 -0700938void QuicSentPacketManager::MaybeSendProbePackets() {
939 if (pending_timer_transmission_count_ == 0) {
940 return;
941 }
942 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
943 std::vector<QuicPacketNumber> probing_packets;
944 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
945 it != unacked_packets_.end(); ++it, ++packet_number) {
946 if (it->state == OUTSTANDING &&
947 unacked_packets_.HasRetransmittableFrames(*it)) {
948 probing_packets.push_back(packet_number);
949 if (probing_packets.size() == pending_timer_transmission_count_) {
950 break;
951 }
952 }
953 }
954
955 for (QuicPacketNumber retransmission : probing_packets) {
956 QUIC_DVLOG(1) << ENDPOINT << "Marking " << retransmission
957 << " for probing retransmission";
958 MarkForRetransmission(retransmission, PROBING_RETRANSMISSION);
959 }
960 // It is possible that there is not enough outstanding data for probing.
961}
962
963void QuicSentPacketManager::AdjustPendingTimerTransmissions() {
964 if (pending_timer_transmission_count_ < max_probe_packets_per_pto_) {
965 // There are packets sent already, clear credit.
966 pending_timer_transmission_count_ = 0;
967 return;
968 }
969 // No packet gets sent, leave 1 credit to allow data to be write eventually.
970 pending_timer_transmission_count_ = 1;
971}
972
fayang08a6c952019-09-18 14:29:45 -0700973void QuicSentPacketManager::EnableIetfPtoAndLossDetection() {
fayang5f135052019-08-22 17:59:40 -0700974 DCHECK(session_decides_what_to_write());
975 fix_rto_retransmission_ = true;
976 pto_enabled_ = true;
977 handshake_mode_disabled_ = true;
fayang08a6c952019-09-18 14:29:45 -0700978 uber_loss_algorithm_.SetLossDetectionType(kIetfLossDetection);
fayang5f135052019-08-22 17:59:40 -0700979}
980
QUICHE teama6ef0a62019-03-07 20:34:33 -0500981QuicSentPacketManager::RetransmissionTimeoutMode
982QuicSentPacketManager::GetRetransmissionMode() const {
fayang5f135052019-08-22 17:59:40 -0700983 DCHECK(unacked_packets_.HasInFlightPackets() ||
984 (handshake_mode_disabled_ && !handshake_confirmed_));
985 if (!handshake_mode_disabled_ && !handshake_confirmed_ &&
986 unacked_packets_.HasPendingCryptoPackets()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500987 return HANDSHAKE_MODE;
988 }
989 if (loss_algorithm_->GetLossTimeout() != QuicTime::Zero()) {
990 return LOSS_MODE;
991 }
fayang62f867a2019-08-22 12:05:01 -0700992 if (pto_enabled_) {
fayangce0a3162019-08-15 09:05:36 -0700993 return PTO_MODE;
994 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500995 if (consecutive_tlp_count_ < max_tail_loss_probes_) {
ianswett7ddb34f2019-07-15 12:17:43 -0700996 if (unacked_packets_.HasUnackedRetransmittableFrames()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500997 return TLP_MODE;
998 }
999 }
1000 return RTO_MODE;
1001}
1002
1003void QuicSentPacketManager::InvokeLossDetection(QuicTime time) {
1004 if (!packets_acked_.empty()) {
1005 DCHECK_LE(packets_acked_.front().packet_number,
1006 packets_acked_.back().packet_number);
1007 largest_newly_acked_ = packets_acked_.back().packet_number;
1008 }
1009 loss_algorithm_->DetectLosses(unacked_packets_, time, rtt_stats_,
1010 largest_newly_acked_, packets_acked_,
1011 &packets_lost_);
1012 for (const LostPacket& packet : packets_lost_) {
1013 ++stats_->packets_lost;
1014 if (debug_delegate_ != nullptr) {
1015 debug_delegate_->OnPacketLoss(packet.packet_number, LOSS_RETRANSMISSION,
1016 time);
1017 }
ianswett04004652019-09-03 18:46:57 -07001018 unacked_packets_.RemoveFromInFlight(packet.packet_number);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001019 MarkForRetransmission(packet.packet_number, LOSS_RETRANSMISSION);
1020 }
1021}
1022
1023bool QuicSentPacketManager::MaybeUpdateRTT(QuicPacketNumber largest_acked,
1024 QuicTime::Delta ack_delay_time,
1025 QuicTime ack_receive_time) {
1026 // We rely on ack_delay_time to compute an RTT estimate, so we
1027 // only update rtt when the largest observed gets acked.
1028 if (!unacked_packets_.IsUnacked(largest_acked)) {
1029 return false;
1030 }
1031 // We calculate the RTT based on the highest ACKed packet number, the lower
1032 // packet numbers will include the ACK aggregation delay.
1033 const QuicTransmissionInfo& transmission_info =
1034 unacked_packets_.GetTransmissionInfo(largest_acked);
1035 // Ensure the packet has a valid sent time.
1036 if (transmission_info.sent_time == QuicTime::Zero()) {
1037 QUIC_BUG << "Acked packet has zero sent time, largest_acked:"
1038 << largest_acked;
1039 return false;
1040 }
1041 if (transmission_info.sent_time > ack_receive_time) {
1042 QUIC_CODE_COUNT(quic_receive_acked_before_sending);
1043 }
1044
1045 QuicTime::Delta send_delta = ack_receive_time - transmission_info.sent_time;
1046 rtt_stats_.UpdateRtt(send_delta, ack_delay_time, ack_receive_time);
1047
1048 return true;
1049}
1050
1051QuicTime::Delta QuicSentPacketManager::TimeUntilSend(QuicTime now) const {
1052 // The TLP logic is entirely contained within QuicSentPacketManager, so the
1053 // send algorithm does not need to be consulted.
1054 if (pending_timer_transmission_count_ > 0) {
1055 return QuicTime::Delta::Zero();
1056 }
1057
1058 if (using_pacing_) {
1059 return pacing_sender_.TimeUntilSend(now,
1060 unacked_packets_.bytes_in_flight());
1061 }
1062
1063 return send_algorithm_->CanSend(unacked_packets_.bytes_in_flight())
1064 ? QuicTime::Delta::Zero()
1065 : QuicTime::Delta::Infinite();
1066}
1067
1068const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
fayang5f135052019-08-22 17:59:40 -07001069 if (!unacked_packets_.HasInFlightPackets() &&
1070 (!handshake_mode_disabled_ || handshake_confirmed_ ||
1071 unacked_packets_.perspective() == Perspective::IS_SERVER)) {
1072 // Do not set the timer if there is nothing in flight. However, to avoid
1073 // handshake deadlock due to anti-amplification limit, client needs to set
1074 // PTO timer when the handshake is not confirmed even there is nothing in
1075 // flight.
1076 return QuicTime::Zero();
1077 }
1078 if (pending_timer_transmission_count_ > 0) {
1079 // Do not set the timer if there is any credit left.
QUICHE teama6ef0a62019-03-07 20:34:33 -05001080 return QuicTime::Zero();
1081 }
fayang67f82272019-08-14 16:08:45 -07001082 if (!fix_rto_retransmission_ &&
1083 !unacked_packets_.HasUnackedRetransmittableFrames()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001084 return QuicTime::Zero();
1085 }
1086 switch (GetRetransmissionMode()) {
1087 case HANDSHAKE_MODE:
1088 return unacked_packets_.GetLastCryptoPacketSentTime() +
1089 GetCryptoRetransmissionDelay();
1090 case LOSS_MODE:
1091 return loss_algorithm_->GetLossTimeout();
1092 case TLP_MODE: {
fayang62f867a2019-08-22 12:05:01 -07001093 DCHECK(!pto_enabled_);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001094 // TODO(ianswett): When CWND is available, it would be preferable to
1095 // set the timer based on the earliest retransmittable packet.
1096 // Base the updated timer on the send time of the last packet.
ianswett479fea32019-09-04 02:51:01 -07001097 const QuicTime sent_time =
1098 unacked_packets_.GetLastInFlightPacketSentTime();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001099 const QuicTime tlp_time = sent_time + GetTailLossProbeDelay();
1100 // Ensure the TLP timer never gets set to a time in the past.
1101 return std::max(clock_->ApproximateNow(), tlp_time);
1102 }
1103 case RTO_MODE: {
fayang62f867a2019-08-22 12:05:01 -07001104 DCHECK(!pto_enabled_);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001105 // The RTO is based on the first outstanding packet.
ianswett479fea32019-09-04 02:51:01 -07001106 const QuicTime sent_time =
1107 unacked_packets_.GetLastInFlightPacketSentTime();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001108 QuicTime rto_time = sent_time + GetRetransmissionDelay();
1109 // Wait for TLP packets to be acked before an RTO fires.
ianswett479fea32019-09-04 02:51:01 -07001110 QuicTime tlp_time = sent_time + GetTailLossProbeDelay();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001111 return std::max(tlp_time, rto_time);
1112 }
fayangce0a3162019-08-15 09:05:36 -07001113 case PTO_MODE: {
ianswett479fea32019-09-04 02:51:01 -07001114 if (!unacked_packets().simple_inflight_time() &&
1115 handshake_mode_disabled_ && !handshake_confirmed_ &&
fayang5f135052019-08-22 17:59:40 -07001116 !unacked_packets_.HasInFlightPackets()) {
1117 DCHECK_EQ(Perspective::IS_CLIENT, unacked_packets_.perspective());
1118 return std::max(clock_->ApproximateNow(),
1119 unacked_packets_.GetLastCryptoPacketSentTime() +
1120 GetProbeTimeoutDelay());
1121 }
fayangce0a3162019-08-15 09:05:36 -07001122 // Ensure PTO never gets set to a time in the past.
ianswett479fea32019-09-04 02:51:01 -07001123 return std::max(clock_->ApproximateNow(),
1124 unacked_packets_.GetLastInFlightPacketSentTime() +
1125 GetProbeTimeoutDelay());
fayangce0a3162019-08-15 09:05:36 -07001126 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001127 }
1128 DCHECK(false);
1129 return QuicTime::Zero();
1130}
1131
1132const QuicTime::Delta QuicSentPacketManager::GetPathDegradingDelay() const {
1133 QuicTime::Delta delay = QuicTime::Delta::Zero();
1134 for (size_t i = 0; i < max_tail_loss_probes_; ++i) {
1135 delay = delay + GetTailLossProbeDelay(i);
1136 }
1137 for (size_t i = 0; i < kNumRetransmissionDelaysForPathDegradingDelay; ++i) {
1138 delay = delay + GetRetransmissionDelay(i);
1139 }
1140 return delay;
1141}
1142
1143const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay()
1144 const {
1145 // This is equivalent to the TailLossProbeDelay, but slightly more aggressive
1146 // because crypto handshake messages don't incur a delayed ack time.
1147 QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
1148 int64_t delay_ms;
1149 if (conservative_handshake_retransmits_) {
1150 // Using the delayed ack time directly could cause conservative handshake
1151 // retransmissions to actually be more aggressive than the default.
fkastenholz59c653b2019-07-15 09:55:53 -07001152 delay_ms = std::max(peer_max_ack_delay_.ToMilliseconds(),
QUICHE teama6ef0a62019-03-07 20:34:33 -05001153 static_cast<int64_t>(2 * srtt.ToMilliseconds()));
1154 } else {
1155 delay_ms = std::max(kMinHandshakeTimeoutMs,
1156 static_cast<int64_t>(1.5 * srtt.ToMilliseconds()));
1157 }
1158 return QuicTime::Delta::FromMilliseconds(
1159 delay_ms << consecutive_crypto_retransmission_count_);
1160}
1161
1162const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay(
1163 size_t consecutive_tlp_count) const {
1164 QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
1165 if (enable_half_rtt_tail_loss_probe_ && consecutive_tlp_count == 0u) {
zhongyi9fa2be32019-09-10 12:39:01 -07001166 if (!session_decides_what_to_write()) {
zhongyi1b2f7832019-06-14 13:31:34 -07001167 return std::max(min_tlp_timeout_, srtt * 0.5);
1168 }
zhongyi1b2f7832019-06-14 13:31:34 -07001169 if (unacked_packets().HasUnackedStreamData()) {
1170 // Enable TLPR if there are pending data packets.
1171 return std::max(min_tlp_timeout_, srtt * 0.5);
1172 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001173 }
1174 if (ietf_style_tlp_) {
1175 return std::max(min_tlp_timeout_, 1.5 * srtt + rtt_stats_.max_ack_delay());
1176 }
1177 if (ietf_style_2x_tlp_) {
1178 return std::max(min_tlp_timeout_, 2 * srtt + rtt_stats_.max_ack_delay());
1179 }
1180 if (!unacked_packets_.HasMultipleInFlightPackets()) {
1181 // This expression really should be using the delayed ack time, but in TCP
1182 // MinRTO was traditionally set to 2x the delayed ack timer and this
1183 // expression assumed QUIC did the same.
1184 return std::max(2 * srtt, 1.5 * srtt + (min_rto_timeout_ * 0.5));
1185 }
1186 return std::max(min_tlp_timeout_, 2 * srtt);
1187}
1188
1189const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay(
1190 size_t consecutive_rto_count) const {
1191 QuicTime::Delta retransmission_delay = QuicTime::Delta::Zero();
1192 if (rtt_stats_.smoothed_rtt().IsZero()) {
1193 // We are in the initial state, use default timeout values.
1194 retransmission_delay =
1195 QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs);
1196 } else {
1197 retransmission_delay =
1198 rtt_stats_.smoothed_rtt() + 4 * rtt_stats_.mean_deviation();
1199 if (retransmission_delay < min_rto_timeout_) {
1200 retransmission_delay = min_rto_timeout_;
1201 }
1202 }
1203
1204 // Calculate exponential back off.
1205 retransmission_delay =
1206 retransmission_delay *
1207 (1 << std::min<size_t>(consecutive_rto_count, kMaxRetransmissions));
1208
1209 if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) {
1210 return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs);
1211 }
1212 return retransmission_delay;
1213}
1214
fayangce0a3162019-08-15 09:05:36 -07001215const QuicTime::Delta QuicSentPacketManager::GetProbeTimeoutDelay() const {
fayang62f867a2019-08-22 12:05:01 -07001216 DCHECK(pto_enabled_);
fayangce0a3162019-08-15 09:05:36 -07001217 if (rtt_stats_.smoothed_rtt().IsZero()) {
1218 if (rtt_stats_.initial_rtt().IsZero()) {
1219 return QuicTime::Delta::FromSeconds(1);
1220 }
1221 return 2 * rtt_stats_.initial_rtt();
1222 }
1223 const QuicTime::Delta pto_delay =
1224 rtt_stats_.smoothed_rtt() +
1225 std::max(4 * rtt_stats_.mean_deviation(),
1226 QuicTime::Delta::FromMilliseconds(1)) +
1227 peer_max_ack_delay_;
1228 return pto_delay * (1 << consecutive_pto_count_);
1229}
1230
wub967ba572019-04-01 09:27:52 -07001231QuicTime::Delta QuicSentPacketManager::GetSlowStartDuration() const {
1232 if (send_algorithm_->GetCongestionControlType() != kBBR) {
1233 return QuicTime::Delta::Infinite();
1234 }
1235
1236 if (!send_algorithm_->InSlowStart()) {
1237 return stats_->slowstart_duration;
1238 }
1239
1240 return clock_->ApproximateNow() - stats_->slowstart_start_time +
1241 stats_->slowstart_duration;
1242}
1243
vasilvvc48c8712019-03-11 13:38:16 -07001244std::string QuicSentPacketManager::GetDebugState() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001245 return send_algorithm_->GetDebugState();
1246}
1247
1248void QuicSentPacketManager::CancelRetransmissionsForStream(
1249 QuicStreamId stream_id) {
1250 if (session_decides_what_to_write()) {
1251 return;
1252 }
1253 unacked_packets_.CancelRetransmissionsForStream(stream_id);
1254 auto it = pending_retransmissions_.begin();
1255 while (it != pending_retransmissions_.end()) {
1256 if (unacked_packets_.HasRetransmittableFrames(it->first)) {
1257 ++it;
1258 continue;
1259 }
1260 it = pending_retransmissions_.erase(it);
1261 }
1262}
1263
1264void QuicSentPacketManager::SetSendAlgorithm(
1265 CongestionControlType congestion_control_type) {
1266 SetSendAlgorithm(SendAlgorithmInterface::Create(
QUICHE team73957f12019-04-18 16:21:52 -07001267 clock_, &rtt_stats_, &unacked_packets_, congestion_control_type, random_,
1268 stats_, initial_congestion_window_));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001269}
1270
1271void QuicSentPacketManager::SetSendAlgorithm(
1272 SendAlgorithmInterface* send_algorithm) {
1273 send_algorithm_.reset(send_algorithm);
1274 pacing_sender_.set_sender(send_algorithm);
1275}
1276
1277void QuicSentPacketManager::OnConnectionMigration(AddressChangeType type) {
1278 if (type == PORT_CHANGE || type == IPV4_SUBNET_CHANGE) {
1279 // Rtt and cwnd do not need to be reset when the peer address change is
1280 // considered to be caused by NATs.
1281 return;
1282 }
1283 consecutive_rto_count_ = 0;
1284 consecutive_tlp_count_ = 0;
fayangce0a3162019-08-15 09:05:36 -07001285 consecutive_pto_count_ = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001286 rtt_stats_.OnConnectionMigration();
1287 send_algorithm_->OnConnectionMigration();
1288}
1289
1290void QuicSentPacketManager::OnAckFrameStart(QuicPacketNumber largest_acked,
1291 QuicTime::Delta ack_delay_time,
1292 QuicTime ack_receive_time) {
1293 DCHECK(packets_acked_.empty());
1294 DCHECK_LE(largest_acked, unacked_packets_.largest_sent_packet());
1295 rtt_updated_ =
1296 MaybeUpdateRTT(largest_acked, ack_delay_time, ack_receive_time);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001297 last_ack_frame_.ack_delay_time = ack_delay_time;
1298 acked_packets_iter_ = last_ack_frame_.packets.rbegin();
1299}
1300
1301void QuicSentPacketManager::OnAckRange(QuicPacketNumber start,
1302 QuicPacketNumber end) {
1303 if (!last_ack_frame_.largest_acked.IsInitialized() ||
1304 end > last_ack_frame_.largest_acked + 1) {
1305 // Largest acked increases.
1306 unacked_packets_.IncreaseLargestAcked(end - 1);
1307 last_ack_frame_.largest_acked = end - 1;
1308 }
1309 // Drop ack ranges which ack packets below least_unacked.
1310 QuicPacketNumber least_unacked = unacked_packets_.GetLeastUnacked();
1311 if (least_unacked.IsInitialized() && end <= least_unacked) {
1312 return;
1313 }
1314 start = std::max(start, least_unacked);
1315 do {
1316 QuicPacketNumber newly_acked_start = start;
1317 if (acked_packets_iter_ != last_ack_frame_.packets.rend()) {
1318 newly_acked_start = std::max(start, acked_packets_iter_->max());
1319 }
1320 for (QuicPacketNumber acked = end - 1; acked >= newly_acked_start;
1321 --acked) {
1322 // Check if end is above the current range. If so add newly acked packets
1323 // in descending order.
1324 packets_acked_.push_back(AckedPacket(acked, 0, QuicTime::Zero()));
1325 if (acked == FirstSendingPacketNumber()) {
1326 break;
1327 }
1328 }
1329 if (acked_packets_iter_ == last_ack_frame_.packets.rend() ||
1330 start > acked_packets_iter_->min()) {
1331 // Finish adding all newly acked packets.
1332 return;
1333 }
1334 end = std::min(end, acked_packets_iter_->min());
1335 ++acked_packets_iter_;
1336 } while (start < end);
1337}
1338
1339void QuicSentPacketManager::OnAckTimestamp(QuicPacketNumber packet_number,
1340 QuicTime timestamp) {
1341 last_ack_frame_.received_packet_times.push_back({packet_number, timestamp});
1342 for (AckedPacket& packet : packets_acked_) {
1343 if (packet.packet_number == packet_number) {
1344 packet.receive_timestamp = timestamp;
1345 return;
1346 }
1347 }
1348}
1349
fayang3eb82212019-04-16 12:05:46 -07001350AckResult QuicSentPacketManager::OnAckFrameEnd(
1351 QuicTime ack_receive_time,
fayangf8e918b2019-07-16 13:03:16 -07001352 QuicPacketNumber ack_packet_number,
fayang3eb82212019-04-16 12:05:46 -07001353 EncryptionLevel ack_decrypted_level) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001354 QuicByteCount prior_bytes_in_flight = unacked_packets_.bytes_in_flight();
1355 // Reverse packets_acked_ so that it is in ascending order.
1356 reverse(packets_acked_.begin(), packets_acked_.end());
1357 for (AckedPacket& acked_packet : packets_acked_) {
1358 QuicTransmissionInfo* info =
1359 unacked_packets_.GetMutableTransmissionInfo(acked_packet.packet_number);
1360 if (!QuicUtils::IsAckable(info->state)) {
1361 if (info->state == ACKED) {
1362 QUIC_BUG << "Trying to ack an already acked packet: "
1363 << acked_packet.packet_number
1364 << ", last_ack_frame_: " << last_ack_frame_
1365 << ", least_unacked: " << unacked_packets_.GetLeastUnacked()
1366 << ", packets_acked_: " << packets_acked_;
1367 } else {
fayang3eb82212019-04-16 12:05:46 -07001368 QUIC_PEER_BUG << "Received "
1369 << QuicUtils::EncryptionLevelToString(ack_decrypted_level)
1370 << " ack for unackable packet: "
QUICHE teama6ef0a62019-03-07 20:34:33 -05001371 << acked_packet.packet_number << " with state: "
1372 << QuicUtils::SentPacketStateToString(info->state);
fayang3eb82212019-04-16 12:05:46 -07001373 if (supports_multiple_packet_number_spaces()) {
1374 if (info->state == NEVER_SENT) {
1375 return UNSENT_PACKETS_ACKED;
1376 }
1377 return UNACKABLE_PACKETS_ACKED;
1378 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001379 }
1380 continue;
1381 }
fayang3eb82212019-04-16 12:05:46 -07001382 QUIC_DVLOG(1) << ENDPOINT << "Got an "
1383 << QuicUtils::EncryptionLevelToString(ack_decrypted_level)
fayang19d2d5b2019-09-11 14:22:03 -07001384 << " ack for packet " << acked_packet.packet_number
1385 << " , state: "
1386 << QuicUtils::SentPacketStateToString(info->state);
fayang3eb82212019-04-16 12:05:46 -07001387 const PacketNumberSpace packet_number_space =
fayangbf3d2862019-06-20 14:13:44 -07001388 unacked_packets_.GetPacketNumberSpace(info->encryption_level);
fayang3eb82212019-04-16 12:05:46 -07001389 if (supports_multiple_packet_number_spaces() &&
1390 QuicUtils::GetPacketNumberSpace(ack_decrypted_level) !=
1391 packet_number_space) {
1392 return PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE;
1393 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001394 last_ack_frame_.packets.Add(acked_packet.packet_number);
QUICHE teamc264e362019-03-19 14:21:06 -07001395 largest_packet_peer_knows_is_acked_.UpdateMax(info->largest_acked);
QUICHE teamc279cec2019-03-22 06:51:48 -07001396 if (supports_multiple_packet_number_spaces()) {
fayang3eb82212019-04-16 12:05:46 -07001397 largest_packets_peer_knows_is_acked_[packet_number_space].UpdateMax(
1398 info->largest_acked);
QUICHE teamc279cec2019-03-22 06:51:48 -07001399 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001400 // If data is associated with the most recent transmission of this
1401 // packet, then inform the caller.
1402 if (info->in_flight) {
1403 acked_packet.bytes_acked = info->bytes_sent;
1404 } else {
1405 // Unackable packets are skipped earlier.
1406 largest_newly_acked_ = acked_packet.packet_number;
1407 }
fayangbf3d2862019-06-20 14:13:44 -07001408 unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
1409 packet_number_space, acked_packet.packet_number);
fayang19d2d5b2019-09-11 14:22:03 -07001410 MarkPacketHandled(acked_packet.packet_number, info, ack_receive_time,
QUICHE team9467db02019-05-30 09:38:45 -07001411 last_ack_frame_.ack_delay_time,
1412 acked_packet.receive_timestamp);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001413 }
1414 const bool acked_new_packet = !packets_acked_.empty();
fayangf8e918b2019-07-16 13:03:16 -07001415 PostProcessNewlyAckedPackets(ack_packet_number, last_ack_frame_,
1416 ack_receive_time, rtt_updated_,
fayang3eb82212019-04-16 12:05:46 -07001417 prior_bytes_in_flight);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001418
fayang3eb82212019-04-16 12:05:46 -07001419 return acked_new_packet ? PACKETS_NEWLY_ACKED : NO_PACKETS_NEWLY_ACKED;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001420}
1421
1422void QuicSentPacketManager::SetDebugDelegate(DebugDelegate* debug_delegate) {
1423 debug_delegate_ = debug_delegate;
1424}
1425
1426void QuicSentPacketManager::OnApplicationLimited() {
1427 if (using_pacing_) {
1428 pacing_sender_.OnApplicationLimited();
1429 }
1430 send_algorithm_->OnApplicationLimited(unacked_packets_.bytes_in_flight());
1431 if (debug_delegate_ != nullptr) {
1432 debug_delegate_->OnApplicationLimited();
1433 }
1434}
1435
1436QuicTime QuicSentPacketManager::GetNextReleaseTime() const {
1437 return using_pacing_ ? pacing_sender_.ideal_next_packet_send_time()
1438 : QuicTime::Zero();
1439}
1440
1441void QuicSentPacketManager::SetInitialRtt(QuicTime::Delta rtt) {
1442 const QuicTime::Delta min_rtt =
1443 QuicTime::Delta::FromMicroseconds(kMinInitialRoundTripTimeUs);
1444 const QuicTime::Delta max_rtt =
1445 QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs);
1446 rtt_stats_.set_initial_rtt(std::max(min_rtt, std::min(max_rtt, rtt)));
1447}
1448
fayangd3016832019-08-08 07:24:45 -07001449void QuicSentPacketManager::SetSessionDecideWhatToWrite(
1450 bool session_decides_what_to_write) {
fayang67f82272019-08-14 16:08:45 -07001451 if (GetQuicReloadableFlag(quic_fix_rto_retransmission3) &&
fayangd3016832019-08-08 07:24:45 -07001452 session_decides_what_to_write) {
1453 fix_rto_retransmission_ = true;
fayang67f82272019-08-14 16:08:45 -07001454 QUIC_RELOADABLE_FLAG_COUNT(quic_fix_rto_retransmission3);
fayangd3016832019-08-08 07:24:45 -07001455 }
1456 unacked_packets_.SetSessionDecideWhatToWrite(session_decides_what_to_write);
1457}
1458
QUICHE teamc279cec2019-03-22 06:51:48 -07001459void QuicSentPacketManager::EnableMultiplePacketNumberSpacesSupport() {
1460 unacked_packets_.EnableMultiplePacketNumberSpacesSupport();
1461}
1462
1463QuicPacketNumber QuicSentPacketManager::GetLargestAckedPacket(
1464 EncryptionLevel decrypted_packet_level) const {
1465 DCHECK(supports_multiple_packet_number_spaces());
1466 return unacked_packets_.GetLargestAckedOfPacketNumberSpace(
1467 QuicUtils::GetPacketNumberSpace(decrypted_packet_level));
1468}
1469
1470QuicPacketNumber QuicSentPacketManager::GetLargestSentPacket(
1471 EncryptionLevel decrypted_packet_level) const {
1472 DCHECK(supports_multiple_packet_number_spaces());
1473 return unacked_packets_.GetLargestSentPacketOfPacketNumberSpace(
1474 decrypted_packet_level);
1475}
1476
1477QuicPacketNumber QuicSentPacketManager::GetLargestPacketPeerKnowsIsAcked(
1478 EncryptionLevel decrypted_packet_level) const {
1479 DCHECK(supports_multiple_packet_number_spaces());
1480 return largest_packets_peer_knows_is_acked_[QuicUtils::GetPacketNumberSpace(
1481 decrypted_packet_level)];
1482}
1483
QUICHE teama6ef0a62019-03-07 20:34:33 -05001484#undef ENDPOINT // undef for jumbo builds
1485} // namespace quic