blob: 43f530e0f83ea2a9da4dde8060cf76a1f31092a1 [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
50// Returns true if retransmissions the specified type leave the data in flight.
51inline bool RetransmissionLeavesBytesInFlight(
52 TransmissionType transmission_type) {
53 // Both TLP and the new RTO leave the packets in flight and let the loss
54 // detection decide if packets are lost.
55 return transmission_type == TLP_RETRANSMISSION ||
56 transmission_type == PROBING_RETRANSMISSION ||
57 transmission_type == RTO_RETRANSMISSION;
58}
59
60// Returns true of retransmissions of the specified type should retransmit
61// the frames directly (as opposed to resulting in a loss notification).
62inline bool ShouldForceRetransmission(TransmissionType transmission_type) {
63 return transmission_type == HANDSHAKE_RETRANSMISSION ||
64 transmission_type == TLP_RETRANSMISSION ||
65 transmission_type == PROBING_RETRANSMISSION ||
66 transmission_type == RTO_RETRANSMISSION;
67}
68
fayang4ba55982019-05-13 05:53:22 -070069// If pacing rate is accurate, > 2 burst token is not likely to help first ACK
70// to arrive earlier, and overly large burst token could cause incast packet
71// losses.
72static const uint32_t kConservativeUnpacedBurst = 2;
73
QUICHE teama6ef0a62019-03-07 20:34:33 -050074} // namespace
75
76#define ENDPOINT \
77 (unacked_packets_.perspective() == Perspective::IS_SERVER ? "Server: " \
78 : "Client: ")
79
80QuicSentPacketManager::QuicSentPacketManager(
81 Perspective perspective,
82 const QuicClock* clock,
QUICHE team73957f12019-04-18 16:21:52 -070083 QuicRandom* random,
QUICHE teama6ef0a62019-03-07 20:34:33 -050084 QuicConnectionStats* stats,
85 CongestionControlType congestion_control_type,
86 LossDetectionType loss_type)
87 : unacked_packets_(perspective),
88 clock_(clock),
QUICHE team73957f12019-04-18 16:21:52 -070089 random_(random),
QUICHE teama6ef0a62019-03-07 20:34:33 -050090 stats_(stats),
91 debug_delegate_(nullptr),
92 network_change_visitor_(nullptr),
93 initial_congestion_window_(kInitialCongestionWindow),
wub37ec5962019-04-03 09:02:51 -070094 loss_algorithm_(GetInitialLossAlgorithm()),
QUICHE teama6ef0a62019-03-07 20:34:33 -050095 uber_loss_algorithm_(loss_type),
96 consecutive_rto_count_(0),
97 consecutive_tlp_count_(0),
98 consecutive_crypto_retransmission_count_(0),
99 pending_timer_transmission_count_(0),
100 max_tail_loss_probes_(kDefaultMaxTailLossProbes),
101 max_rto_packets_(kMaxRetransmissionsOnTimeout),
102 enable_half_rtt_tail_loss_probe_(false),
103 using_pacing_(false),
104 use_new_rto_(false),
105 conservative_handshake_retransmits_(false),
106 min_tlp_timeout_(
107 QuicTime::Delta::FromMilliseconds(kMinTailLossProbeTimeoutMs)),
108 min_rto_timeout_(
109 QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs)),
110 ietf_style_tlp_(false),
111 ietf_style_2x_tlp_(false),
112 largest_mtu_acked_(0),
113 handshake_confirmed_(false),
fkastenholz59c653b2019-07-15 09:55:53 -0700114 peer_max_ack_delay_(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500115 QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)),
116 rtt_updated_(false),
QUICHE team9929cc42019-03-13 08:17:43 -0700117 acked_packets_iter_(last_ack_frame_.packets.rbegin()),
ianswett898306b2019-04-23 11:05:57 -0700118 loss_removes_from_inflight_(
zhongyi1b2f7832019-06-14 13:31:34 -0700119 GetQuicReloadableFlag(quic_loss_removes_from_inflight)),
120 ignore_tlpr_if_no_pending_stream_data_(
fayanga29eb242019-07-16 12:25:38 -0700121 GetQuicReloadableFlag(quic_ignore_tlpr_if_no_pending_stream_data)),
fayangd3016832019-08-08 07:24:45 -0700122 fix_rto_retransmission_(false) {
ianswett898306b2019-04-23 11:05:57 -0700123 if (loss_removes_from_inflight_) {
124 QUIC_RELOADABLE_FLAG_COUNT(quic_loss_removes_from_inflight);
125 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500126 SetSendAlgorithm(congestion_control_type);
127}
128
wub37ec5962019-04-03 09:02:51 -0700129LossDetectionInterface* QuicSentPacketManager::GetInitialLossAlgorithm() {
fayangbf3d2862019-06-20 14:13:44 -0700130 return &uber_loss_algorithm_;
wub37ec5962019-04-03 09:02:51 -0700131}
132
QUICHE teama6ef0a62019-03-07 20:34:33 -0500133QuicSentPacketManager::~QuicSentPacketManager() {}
134
135void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
136 const Perspective perspective = unacked_packets_.perspective();
137 if (config.HasReceivedInitialRoundTripTimeUs() &&
138 config.ReceivedInitialRoundTripTimeUs() > 0) {
139 if (!config.HasClientSentConnectionOption(kNRTT, perspective)) {
140 SetInitialRtt(QuicTime::Delta::FromMicroseconds(
141 config.ReceivedInitialRoundTripTimeUs()));
142 }
143 } else if (config.HasInitialRoundTripTimeUsToSend() &&
144 config.GetInitialRoundTripTimeUsToSend() > 0) {
145 SetInitialRtt(QuicTime::Delta::FromMicroseconds(
146 config.GetInitialRoundTripTimeUsToSend()));
147 }
ianswett43eefae2019-08-02 12:27:15 -0700148 if (config.HasReceivedMaxAckDelayMs()) {
149 peer_max_ack_delay_ =
150 QuicTime::Delta::FromMilliseconds(config.ReceivedMaxAckDelayMs());
151 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500152 if (config.HasClientSentConnectionOption(kMAD0, perspective)) {
153 rtt_stats_.set_ignore_max_ack_delay(true);
154 }
155 if (config.HasClientSentConnectionOption(kMAD1, perspective)) {
ianswett43eefae2019-08-02 12:27:15 -0700156 rtt_stats_.set_initial_max_ack_delay(peer_max_ack_delay_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500157 }
ianswettdcc474e2019-08-06 08:22:38 -0700158 if (GetQuicReloadableFlag(quic_sent_packet_manager_cleanup)) {
159 QUIC_RELOADABLE_FLAG_COUNT(quic_sent_packet_manager_cleanup);
160 if (config.HasClientSentConnectionOption(kMAD2, perspective)) {
161 // Set the minimum to the alarm granularity.
162 min_tlp_timeout_ = QuicTime::Delta::FromMilliseconds(1);
163 }
164 if (config.HasClientSentConnectionOption(kMAD3, perspective)) {
165 // Set the minimum to the alarm granularity.
166 min_rto_timeout_ = QuicTime::Delta::FromMilliseconds(1);
167 }
168 } else {
169 if (config.HasClientSentConnectionOption(kMAD2, perspective)) {
170 min_tlp_timeout_ = QuicTime::Delta::Zero();
171 }
172 if (config.HasClientSentConnectionOption(kMAD3, perspective)) {
173 min_rto_timeout_ = QuicTime::Delta::Zero();
174 }
175 if (config.HasClientSentConnectionOption(kMAD4, perspective)) {
176 ietf_style_tlp_ = true;
177 }
178 if (config.HasClientSentConnectionOption(kMAD5, perspective)) {
179 ietf_style_2x_tlp_ = true;
180 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500181 }
182
183 // Configure congestion control.
184 if (config.HasClientRequestedIndependentOption(kTBBR, perspective)) {
185 SetSendAlgorithm(kBBR);
186 }
wuba9a43cb2019-07-17 15:22:42 -0700187 if (GetQuicReloadableFlag(quic_allow_client_enabled_bbr_v2) &&
188 config.HasClientRequestedIndependentOption(kB2ON, perspective)) {
189 QUIC_RELOADABLE_FLAG_COUNT(quic_allow_client_enabled_bbr_v2);
190 SetSendAlgorithm(kBBRv2);
191 }
192
QUICHE teama6ef0a62019-03-07 20:34:33 -0500193 if (config.HasClientRequestedIndependentOption(kRENO, perspective)) {
194 SetSendAlgorithm(kRenoBytes);
195 } else if (config.HasClientRequestedIndependentOption(kBYTE, perspective) ||
196 (GetQuicReloadableFlag(quic_default_to_bbr) &&
197 config.HasClientRequestedIndependentOption(kQBIC, perspective))) {
198 SetSendAlgorithm(kCubicBytes);
199 } else if (GetQuicReloadableFlag(quic_enable_pcc3) &&
200 config.HasClientRequestedIndependentOption(kTPCC, perspective)) {
201 SetSendAlgorithm(kPCC);
202 }
wuba9a43cb2019-07-17 15:22:42 -0700203
QUICHE teama6ef0a62019-03-07 20:34:33 -0500204 // Initial window.
205 if (GetQuicReloadableFlag(quic_unified_iw_options)) {
206 if (config.HasClientRequestedIndependentOption(kIW03, perspective)) {
207 initial_congestion_window_ = 3;
208 send_algorithm_->SetInitialCongestionWindowInPackets(3);
209 }
210 if (config.HasClientRequestedIndependentOption(kIW10, perspective)) {
211 initial_congestion_window_ = 10;
212 send_algorithm_->SetInitialCongestionWindowInPackets(10);
213 }
214 if (config.HasClientRequestedIndependentOption(kIW20, perspective)) {
215 initial_congestion_window_ = 20;
216 send_algorithm_->SetInitialCongestionWindowInPackets(20);
217 }
218 if (config.HasClientRequestedIndependentOption(kIW50, perspective)) {
219 initial_congestion_window_ = 50;
220 send_algorithm_->SetInitialCongestionWindowInPackets(50);
221 }
222 }
223
danzh88e3e052019-06-13 11:47:18 -0700224 using_pacing_ = !GetQuicFlag(FLAGS_quic_disable_pacing_for_perf_tests);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500225
QUICHE teama6ef0a62019-03-07 20:34:33 -0500226 if (config.HasClientSentConnectionOption(kNTLP, perspective)) {
227 max_tail_loss_probes_ = 0;
228 }
229 if (config.HasClientSentConnectionOption(k1TLP, perspective)) {
230 max_tail_loss_probes_ = 1;
231 }
232 if (config.HasClientSentConnectionOption(k1RTO, perspective)) {
233 max_rto_packets_ = 1;
234 }
235 if (config.HasClientSentConnectionOption(kTLPR, perspective)) {
236 enable_half_rtt_tail_loss_probe_ = true;
237 }
238 if (config.HasClientSentConnectionOption(kNRTO, perspective)) {
239 use_new_rto_ = true;
240 }
241 // Configure loss detection.
242 if (config.HasClientRequestedIndependentOption(kTIME, perspective)) {
fayangbf3d2862019-06-20 14:13:44 -0700243 uber_loss_algorithm_.SetLossDetectionType(kTime);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500244 }
245 if (config.HasClientRequestedIndependentOption(kATIM, perspective)) {
fayangbf3d2862019-06-20 14:13:44 -0700246 uber_loss_algorithm_.SetLossDetectionType(kAdaptiveTime);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500247 }
248 if (config.HasClientRequestedIndependentOption(kLFAK, perspective)) {
fayangbf3d2862019-06-20 14:13:44 -0700249 uber_loss_algorithm_.SetLossDetectionType(kLazyFack);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500250 }
251 if (config.HasClientSentConnectionOption(kCONH, perspective)) {
252 conservative_handshake_retransmits_ = true;
253 }
254 send_algorithm_->SetFromConfig(config, perspective);
255
256 if (network_change_visitor_ != nullptr) {
257 network_change_visitor_->OnCongestionChange();
258 }
259}
260
261void QuicSentPacketManager::ResumeConnectionState(
262 const CachedNetworkParameters& cached_network_params,
263 bool max_bandwidth_resumption) {
264 QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(
265 max_bandwidth_resumption
266 ? cached_network_params.max_bandwidth_estimate_bytes_per_second()
267 : cached_network_params.bandwidth_estimate_bytes_per_second());
268 QuicTime::Delta rtt =
269 QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms());
fayangf1b99dc2019-05-14 06:29:18 -0700270 AdjustNetworkParameters(bandwidth, rtt, /*allow_cwnd_to_decrease=*/false);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500271}
272
fayangf1b99dc2019-05-14 06:29:18 -0700273void QuicSentPacketManager::AdjustNetworkParameters(
274 QuicBandwidth bandwidth,
275 QuicTime::Delta rtt,
276 bool allow_cwnd_to_decrease) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500277 if (!rtt.IsZero()) {
278 SetInitialRtt(rtt);
279 }
fayangbe83ecd2019-04-26 13:58:09 -0700280 const QuicByteCount old_cwnd = send_algorithm_->GetCongestionWindow();
fayang6c2d64f2019-05-20 17:12:05 -0700281 if (GetQuicReloadableFlag(quic_conservative_bursts) && using_pacing_ &&
282 !bandwidth.IsZero()) {
fayang4ba55982019-05-13 05:53:22 -0700283 QUIC_RELOADABLE_FLAG_COUNT(quic_conservative_bursts);
284 pacing_sender_.SetBurstTokens(kConservativeUnpacedBurst);
285 }
fayangf1b99dc2019-05-14 06:29:18 -0700286 send_algorithm_->AdjustNetworkParameters(bandwidth, rtt,
287 allow_cwnd_to_decrease);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500288 if (debug_delegate_ != nullptr) {
fayangbe83ecd2019-04-26 13:58:09 -0700289 debug_delegate_->OnAdjustNetworkParameters(
fayangef9c8f92019-04-29 13:35:13 -0700290 bandwidth, rtt.IsZero() ? rtt_stats_.SmoothedOrInitialRtt() : rtt,
291 old_cwnd, send_algorithm_->GetCongestionWindow());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500292 }
293}
294
295void QuicSentPacketManager::SetHandshakeConfirmed() {
296 handshake_confirmed_ = true;
fayangbf3d2862019-06-20 14:13:44 -0700297 NeuterHandshakePackets();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500298}
299
fayang3eb82212019-04-16 12:05:46 -0700300void QuicSentPacketManager::PostProcessNewlyAckedPackets(
fayangf8e918b2019-07-16 13:03:16 -0700301 QuicPacketNumber ack_packet_number,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500302 const QuicAckFrame& ack_frame,
303 QuicTime ack_receive_time,
304 bool rtt_updated,
305 QuicByteCount prior_bytes_in_flight) {
306 if (session_decides_what_to_write()) {
307 unacked_packets_.NotifyAggregatedStreamFrameAcked(
308 last_ack_frame_.ack_delay_time);
309 }
310 InvokeLossDetection(ack_receive_time);
311 // Ignore losses in RTO mode.
312 if (consecutive_rto_count_ > 0 && !use_new_rto_) {
313 packets_lost_.clear();
314 }
315 MaybeInvokeCongestionEvent(rtt_updated, prior_bytes_in_flight,
316 ack_receive_time);
317 unacked_packets_.RemoveObsoletePackets();
318
319 sustained_bandwidth_recorder_.RecordEstimate(
320 send_algorithm_->InRecovery(), send_algorithm_->InSlowStart(),
321 send_algorithm_->BandwidthEstimate(), ack_receive_time, clock_->WallNow(),
322 rtt_stats_.smoothed_rtt());
323
324 // Anytime we are making forward progress and have a new RTT estimate, reset
325 // the backoff counters.
326 if (rtt_updated) {
327 if (consecutive_rto_count_ > 0) {
328 // If the ack acknowledges data sent prior to the RTO,
329 // the RTO was spurious.
330 if (LargestAcked(ack_frame) < first_rto_transmission_) {
331 // Replace SRTT with latest_rtt and increase the variance to prevent
332 // a spurious RTO from happening again.
333 rtt_stats_.ExpireSmoothedMetrics();
334 } else {
335 if (!use_new_rto_) {
336 send_algorithm_->OnRetransmissionTimeout(true);
337 }
338 }
339 }
340 // Reset all retransmit counters any time a new packet is acked.
341 consecutive_rto_count_ = 0;
342 consecutive_tlp_count_ = 0;
343 consecutive_crypto_retransmission_count_ = 0;
344 }
345
346 if (debug_delegate_ != nullptr) {
fayangf8e918b2019-07-16 13:03:16 -0700347 debug_delegate_->OnIncomingAck(ack_packet_number, ack_frame,
348 ack_receive_time, LargestAcked(ack_frame),
349 rtt_updated, GetLeastUnacked());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500350 }
351 // Remove packets below least unacked from all_packets_acked_ and
352 // last_ack_frame_.
353 last_ack_frame_.packets.RemoveUpTo(unacked_packets_.GetLeastUnacked());
354 last_ack_frame_.received_packet_times.clear();
355}
356
357void QuicSentPacketManager::MaybeInvokeCongestionEvent(
358 bool rtt_updated,
359 QuicByteCount prior_in_flight,
360 QuicTime event_time) {
361 if (!rtt_updated && packets_acked_.empty() && packets_lost_.empty()) {
362 return;
363 }
364 if (using_pacing_) {
365 pacing_sender_.OnCongestionEvent(rtt_updated, prior_in_flight, event_time,
366 packets_acked_, packets_lost_);
367 } else {
368 send_algorithm_->OnCongestionEvent(rtt_updated, prior_in_flight, event_time,
369 packets_acked_, packets_lost_);
370 }
371 packets_acked_.clear();
372 packets_lost_.clear();
373 if (network_change_visitor_ != nullptr) {
374 network_change_visitor_->OnCongestionChange();
375 }
376}
377
378void QuicSentPacketManager::RetransmitUnackedPackets(
379 TransmissionType retransmission_type) {
380 DCHECK(retransmission_type == ALL_UNACKED_RETRANSMISSION ||
381 retransmission_type == ALL_INITIAL_RETRANSMISSION);
382 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
ianswett898306b2019-04-23 11:05:57 -0700383 for (QuicUnackedPacketMap::iterator it = unacked_packets_.begin();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500384 it != unacked_packets_.end(); ++it, ++packet_number) {
385 if ((retransmission_type == ALL_UNACKED_RETRANSMISSION ||
ianswett898306b2019-04-23 11:05:57 -0700386 it->encryption_level == ENCRYPTION_ZERO_RTT)) {
387 if (loss_removes_from_inflight_ && it->in_flight) {
388 // Remove 0-RTT packets and packets of the wrong version from flight,
389 // because neither can be processed by the peer.
390 unacked_packets_.RemoveFromInFlight(&*it);
391 }
392 if (unacked_packets_.HasRetransmittableFrames(*it)) {
393 MarkForRetransmission(packet_number, retransmission_type);
394 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500395 }
396 }
ianswett898306b2019-04-23 11:05:57 -0700397 if (retransmission_type == ALL_UNACKED_RETRANSMISSION &&
398 unacked_packets_.bytes_in_flight() > 0) {
399 QUIC_BUG << "RetransmitUnackedPackets should remove all packets from flight"
400 << ", bytes_in_flight:" << unacked_packets_.bytes_in_flight();
401 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500402}
403
404void QuicSentPacketManager::NeuterUnencryptedPackets() {
405 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
406 if (session_decides_what_to_write()) {
407 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
408 it != unacked_packets_.end(); ++it, ++packet_number) {
409 if (!it->retransmittable_frames.empty() &&
QUICHE team6987b4a2019-03-15 16:23:04 -0700410 it->encryption_level == ENCRYPTION_INITIAL) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500411 // Once the connection swithes to forward secure, no unencrypted packets
412 // will be sent. The data has been abandoned in the cryto stream. Remove
413 // it from in flight.
414 unacked_packets_.RemoveFromInFlight(packet_number);
415 }
416 }
417 return;
418 }
419 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
420 it != unacked_packets_.end(); ++it, ++packet_number) {
ianswett898306b2019-04-23 11:05:57 -0700421 if (it->encryption_level == ENCRYPTION_INITIAL) {
422 if (loss_removes_from_inflight_ ||
423 unacked_packets_.HasRetransmittableFrames(*it)) {
424 // Once you're forward secure, no unencrypted packets will be sent,
425 // crypto or otherwise. Unencrypted packets are neutered and abandoned,
426 // to ensure they are not retransmitted or considered lost from a
427 // congestion control perspective.
428 pending_retransmissions_.erase(packet_number);
429 unacked_packets_.RemoveFromInFlight(packet_number);
430 unacked_packets_.RemoveRetransmittability(packet_number);
431 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500432 }
433 }
434}
435
436void QuicSentPacketManager::NeuterHandshakePackets() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500437 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
438 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
439 it != unacked_packets_.end(); ++it, ++packet_number) {
440 if (session_decides_what_to_write()) {
441 if (!it->retransmittable_frames.empty() &&
442 unacked_packets_.GetPacketNumberSpace(it->encryption_level) ==
443 HANDSHAKE_DATA) {
444 unacked_packets_.RemoveFromInFlight(packet_number);
445 }
446 continue;
447 }
448 if (unacked_packets_.GetPacketNumberSpace(it->encryption_level) ==
449 HANDSHAKE_DATA &&
450 unacked_packets_.HasRetransmittableFrames(*it)) {
451 pending_retransmissions_.erase(packet_number);
452 unacked_packets_.RemoveFromInFlight(packet_number);
453 unacked_packets_.RemoveRetransmittability(packet_number);
454 }
455 }
456}
457
458void QuicSentPacketManager::MarkForRetransmission(
459 QuicPacketNumber packet_number,
460 TransmissionType transmission_type) {
461 QuicTransmissionInfo* transmission_info =
462 unacked_packets_.GetMutableTransmissionInfo(packet_number);
463 // When session decides what to write, a previous RTO retransmission may cause
464 // connection close; packets without retransmittable frames can be marked for
465 // loss retransmissions.
466 QUIC_BUG_IF((transmission_type != LOSS_RETRANSMISSION &&
467 (!session_decides_what_to_write() ||
468 transmission_type != RTO_RETRANSMISSION)) &&
469 !unacked_packets_.HasRetransmittableFrames(*transmission_info))
470 << "transmission_type: "
471 << QuicUtils::TransmissionTypeToString(transmission_type);
472 // Handshake packets should never be sent as probing retransmissions.
473 DCHECK(!transmission_info->has_crypto_handshake ||
474 transmission_type != PROBING_RETRANSMISSION);
ianswett898306b2019-04-23 11:05:57 -0700475 if (!loss_removes_from_inflight_ &&
476 !RetransmissionLeavesBytesInFlight(transmission_type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500477 unacked_packets_.RemoveFromInFlight(transmission_info);
478 }
479
480 if (!session_decides_what_to_write()) {
481 if (!unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
482 return;
483 }
484 if (!QuicContainsKey(pending_retransmissions_, packet_number)) {
485 pending_retransmissions_[packet_number] = transmission_type;
486 }
487 return;
488 }
489
490 HandleRetransmission(transmission_type, transmission_info);
491
492 // Update packet state according to transmission type.
493 transmission_info->state =
494 QuicUtils::RetransmissionTypeToPacketState(transmission_type);
495}
496
497void QuicSentPacketManager::HandleRetransmission(
498 TransmissionType transmission_type,
499 QuicTransmissionInfo* transmission_info) {
500 DCHECK(session_decides_what_to_write());
501 if (ShouldForceRetransmission(transmission_type)) {
502 // TODO(fayang): Consider to make RTO and PROBING retransmission
503 // strategies be configurable by applications. Today, TLP, RTO and PROBING
504 // retransmissions are handled similarly, i.e., always retranmist the
505 // oldest outstanding data. This is not ideal in general because different
506 // applications may want different strategies. For example, some
507 // applications may want to use higher priority stream data for bandwidth
508 // probing, and some applications want to consider RTO is an indication of
509 // loss, etc.
510 unacked_packets_.RetransmitFrames(*transmission_info, transmission_type);
511 return;
512 }
513
514 unacked_packets_.NotifyFramesLost(*transmission_info, transmission_type);
515 if (transmission_info->retransmittable_frames.empty()) {
516 return;
517 }
518
519 if (transmission_type == LOSS_RETRANSMISSION) {
520 // Record the first packet sent after loss, which allows to wait 1
521 // more RTT before giving up on this lost packet.
522 transmission_info->retransmission =
523 unacked_packets_.largest_sent_packet() + 1;
524 } else {
525 // Clear the recorded first packet sent after loss when version or
526 // encryption changes.
527 transmission_info->retransmission.Clear();
528 }
529}
530
531void QuicSentPacketManager::RecordOneSpuriousRetransmission(
532 const QuicTransmissionInfo& info) {
533 stats_->bytes_spuriously_retransmitted += info.bytes_sent;
534 ++stats_->packets_spuriously_retransmitted;
535 if (debug_delegate_ != nullptr) {
536 debug_delegate_->OnSpuriousPacketRetransmission(info.transmission_type,
537 info.bytes_sent);
538 }
539}
540
541void QuicSentPacketManager::RecordSpuriousRetransmissions(
542 const QuicTransmissionInfo& info,
543 QuicPacketNumber acked_packet_number) {
544 if (session_decides_what_to_write()) {
545 RecordOneSpuriousRetransmission(info);
546 if (info.transmission_type == LOSS_RETRANSMISSION) {
547 // Only inform the loss detection of spurious retransmits it caused.
548 loss_algorithm_->SpuriousRetransmitDetected(
549 unacked_packets_, clock_->Now(), rtt_stats_, acked_packet_number);
550 }
551 return;
552 }
553 QuicPacketNumber retransmission = info.retransmission;
554 while (retransmission.IsInitialized()) {
555 const QuicTransmissionInfo& retransmit_info =
556 unacked_packets_.GetTransmissionInfo(retransmission);
557 retransmission = retransmit_info.retransmission;
558 RecordOneSpuriousRetransmission(retransmit_info);
559 }
560 // Only inform the loss detection of spurious retransmits it caused.
561 if (unacked_packets_.GetTransmissionInfo(info.retransmission)
562 .transmission_type == LOSS_RETRANSMISSION) {
563 loss_algorithm_->SpuriousRetransmitDetected(
564 unacked_packets_, clock_->Now(), rtt_stats_, info.retransmission);
565 }
566}
567
568QuicPendingRetransmission QuicSentPacketManager::NextPendingRetransmission() {
569 QUIC_BUG_IF(pending_retransmissions_.empty())
570 << "Unexpected call to NextPendingRetransmission() with empty pending "
571 << "retransmission list. Corrupted memory usage imminent.";
572 QUIC_BUG_IF(session_decides_what_to_write())
573 << "Unexpected call to NextPendingRetransmission() when session handles "
574 "retransmissions";
575 QuicPacketNumber packet_number = pending_retransmissions_.begin()->first;
576 TransmissionType transmission_type = pending_retransmissions_.begin()->second;
577 if (unacked_packets_.HasPendingCryptoPackets()) {
578 // Ensure crypto packets are retransmitted before other packets.
579 for (const auto& pair : pending_retransmissions_) {
580 if (HasCryptoHandshake(
581 unacked_packets_.GetTransmissionInfo(pair.first))) {
582 packet_number = pair.first;
583 transmission_type = pair.second;
584 break;
585 }
586 }
587 }
588 DCHECK(unacked_packets_.IsUnacked(packet_number)) << packet_number;
589 const QuicTransmissionInfo& transmission_info =
590 unacked_packets_.GetTransmissionInfo(packet_number);
591 DCHECK(unacked_packets_.HasRetransmittableFrames(transmission_info));
592
593 return QuicPendingRetransmission(packet_number, transmission_type,
594 transmission_info);
595}
596
597QuicPacketNumber QuicSentPacketManager::GetNewestRetransmission(
598 QuicPacketNumber packet_number,
599 const QuicTransmissionInfo& transmission_info) const {
600 if (session_decides_what_to_write()) {
601 return packet_number;
602 }
603 QuicPacketNumber retransmission = transmission_info.retransmission;
604 while (retransmission.IsInitialized()) {
605 packet_number = retransmission;
606 retransmission =
607 unacked_packets_.GetTransmissionInfo(retransmission).retransmission;
608 }
609 return packet_number;
610}
611
612void QuicSentPacketManager::MarkPacketHandled(QuicPacketNumber packet_number,
613 QuicTransmissionInfo* info,
QUICHE team9467db02019-05-30 09:38:45 -0700614 QuicTime::Delta ack_delay_time,
615 QuicTime receive_timestamp) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500616 QuicPacketNumber newest_transmission =
617 GetNewestRetransmission(packet_number, *info);
618 // Remove the most recent packet, if it is pending retransmission.
619 pending_retransmissions_.erase(newest_transmission);
620
621 if (newest_transmission == packet_number) {
622 // Try to aggregate acked stream frames if acked packet is not a
623 // retransmission.
624 const bool fast_path = session_decides_what_to_write() &&
625 info->transmission_type == NOT_RETRANSMISSION;
626 if (fast_path) {
QUICHE team9467db02019-05-30 09:38:45 -0700627 unacked_packets_.MaybeAggregateAckedStreamFrame(*info, ack_delay_time,
628 receive_timestamp);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500629 } else {
630 if (session_decides_what_to_write()) {
631 unacked_packets_.NotifyAggregatedStreamFrameAcked(ack_delay_time);
632 }
QUICHE team9467db02019-05-30 09:38:45 -0700633 const bool new_data_acked = unacked_packets_.NotifyFramesAcked(
634 *info, ack_delay_time, receive_timestamp);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500635 if (session_decides_what_to_write() && !new_data_acked &&
636 info->transmission_type != NOT_RETRANSMISSION) {
637 // Record as a spurious retransmission if this packet is a
638 // retransmission and no new data gets acked.
639 QUIC_DVLOG(1) << "Detect spurious retransmitted packet "
640 << packet_number << " transmission type: "
641 << QuicUtils::TransmissionTypeToString(
642 info->transmission_type);
643 RecordSpuriousRetransmissions(*info, packet_number);
644 }
645 }
646 } else {
647 DCHECK(!session_decides_what_to_write());
648 RecordSpuriousRetransmissions(*info, packet_number);
649 // Remove the most recent packet from flight if it's a crypto handshake
650 // packet, since they won't be acked now that one has been processed.
651 // Other crypto handshake packets won't be in flight, only the newest
652 // transmission of a crypto packet is in flight at once.
653 // TODO(ianswett): Instead of handling all crypto packets special,
654 // only handle nullptr encrypted packets in a special way.
655 const QuicTransmissionInfo& newest_transmission_info =
656 unacked_packets_.GetTransmissionInfo(newest_transmission);
QUICHE team9467db02019-05-30 09:38:45 -0700657 unacked_packets_.NotifyFramesAcked(newest_transmission_info, ack_delay_time,
658 receive_timestamp);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500659 if (HasCryptoHandshake(newest_transmission_info)) {
660 unacked_packets_.RemoveFromInFlight(newest_transmission);
661 }
662 }
663
664 if (network_change_visitor_ != nullptr &&
665 info->bytes_sent > largest_mtu_acked_) {
666 largest_mtu_acked_ = info->bytes_sent;
667 network_change_visitor_->OnPathMtuIncreased(largest_mtu_acked_);
668 }
669 unacked_packets_.RemoveFromInFlight(info);
670 unacked_packets_.RemoveRetransmittability(info);
671 info->state = ACKED;
672}
673
674bool QuicSentPacketManager::OnPacketSent(
675 SerializedPacket* serialized_packet,
676 QuicPacketNumber original_packet_number,
677 QuicTime sent_time,
678 TransmissionType transmission_type,
679 HasRetransmittableData has_retransmittable_data) {
680 QuicPacketNumber packet_number = serialized_packet->packet_number;
681 DCHECK_LE(FirstSendingPacketNumber(), packet_number);
682 DCHECK(!unacked_packets_.IsUnacked(packet_number));
683 QUIC_BUG_IF(serialized_packet->encrypted_length == 0)
684 << "Cannot send empty packets.";
685
686 if (original_packet_number.IsInitialized()) {
687 pending_retransmissions_.erase(original_packet_number);
688 }
689
690 if (pending_timer_transmission_count_ > 0) {
691 --pending_timer_transmission_count_;
692 }
693
694 bool in_flight = has_retransmittable_data == HAS_RETRANSMITTABLE_DATA;
695 if (using_pacing_) {
696 pacing_sender_.OnPacketSent(
697 sent_time, unacked_packets_.bytes_in_flight(), packet_number,
698 serialized_packet->encrypted_length, has_retransmittable_data);
699 } else {
700 send_algorithm_->OnPacketSent(
701 sent_time, unacked_packets_.bytes_in_flight(), packet_number,
702 serialized_packet->encrypted_length, has_retransmittable_data);
703 }
704
705 unacked_packets_.AddSentPacket(serialized_packet, original_packet_number,
706 transmission_type, sent_time, in_flight);
707 // Reset the retransmission timer anytime a pending packet is sent.
708 return in_flight;
709}
710
711void QuicSentPacketManager::OnRetransmissionTimeout() {
712 DCHECK(unacked_packets_.HasInFlightPackets());
713 DCHECK_EQ(0u, pending_timer_transmission_count_);
714 // Handshake retransmission, timer based loss detection, TLP, and RTO are
715 // implemented with a single alarm. The handshake alarm is set when the
716 // handshake has not completed, the loss alarm is set when the loss detection
717 // algorithm says to, and the TLP and RTO alarms are set after that.
718 // The TLP alarm is always set to run for under an RTO.
719 switch (GetRetransmissionMode()) {
720 case HANDSHAKE_MODE:
721 ++stats_->crypto_retransmit_count;
722 RetransmitCryptoPackets();
723 return;
724 case LOSS_MODE: {
725 ++stats_->loss_timeout_count;
726 QuicByteCount prior_in_flight = unacked_packets_.bytes_in_flight();
727 const QuicTime now = clock_->Now();
728 InvokeLossDetection(now);
729 MaybeInvokeCongestionEvent(false, prior_in_flight, now);
730 return;
731 }
732 case TLP_MODE:
733 ++stats_->tlp_count;
734 ++consecutive_tlp_count_;
735 pending_timer_transmission_count_ = 1;
736 // TLPs prefer sending new data instead of retransmitting data, so
737 // give the connection a chance to write before completing the TLP.
738 return;
739 case RTO_MODE:
740 ++stats_->rto_count;
741 RetransmitRtoPackets();
742 return;
743 }
744}
745
746void QuicSentPacketManager::RetransmitCryptoPackets() {
747 DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode());
748 ++consecutive_crypto_retransmission_count_;
749 bool packet_retransmitted = false;
750 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
751 std::vector<QuicPacketNumber> crypto_retransmissions;
752 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
753 it != unacked_packets_.end(); ++it, ++packet_number) {
754 // Only retransmit frames which are in flight, and therefore have been sent.
755 if (!it->in_flight ||
756 (session_decides_what_to_write() && it->state != OUTSTANDING) ||
757 !it->has_crypto_handshake ||
758 !unacked_packets_.HasRetransmittableFrames(*it)) {
759 continue;
760 }
761 packet_retransmitted = true;
762 if (session_decides_what_to_write()) {
763 crypto_retransmissions.push_back(packet_number);
764 } else {
765 MarkForRetransmission(packet_number, HANDSHAKE_RETRANSMISSION);
766 }
767 ++pending_timer_transmission_count_;
768 }
769 DCHECK(packet_retransmitted) << "No crypto packets found to retransmit.";
770 if (session_decides_what_to_write()) {
771 for (QuicPacketNumber retransmission : crypto_retransmissions) {
772 MarkForRetransmission(retransmission, HANDSHAKE_RETRANSMISSION);
773 }
774 }
775}
776
777bool QuicSentPacketManager::MaybeRetransmitTailLossProbe() {
778 if (pending_timer_transmission_count_ == 0) {
779 return false;
780 }
781 if (!MaybeRetransmitOldestPacket(TLP_RETRANSMISSION)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500782 return false;
783 }
784 return true;
785}
786
787bool QuicSentPacketManager::MaybeRetransmitOldestPacket(TransmissionType type) {
788 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
789 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
790 it != unacked_packets_.end(); ++it, ++packet_number) {
791 // Only retransmit frames which are in flight, and therefore have been sent.
792 if (!it->in_flight ||
793 (session_decides_what_to_write() && it->state != OUTSTANDING) ||
794 !unacked_packets_.HasRetransmittableFrames(*it)) {
795 continue;
796 }
797 MarkForRetransmission(packet_number, type);
798 return true;
799 }
800 QUIC_DVLOG(1)
801 << "No retransmittable packets, so RetransmitOldestPacket failed.";
802 return false;
803}
804
805void QuicSentPacketManager::RetransmitRtoPackets() {
806 QUIC_BUG_IF(pending_timer_transmission_count_ > 0)
807 << "Retransmissions already queued:" << pending_timer_transmission_count_;
808 // Mark two packets for retransmission.
809 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
810 std::vector<QuicPacketNumber> retransmissions;
811 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
812 it != unacked_packets_.end(); ++it, ++packet_number) {
813 if ((!session_decides_what_to_write() || it->state == OUTSTANDING) &&
814 unacked_packets_.HasRetransmittableFrames(*it) &&
815 pending_timer_transmission_count_ < max_rto_packets_) {
816 if (session_decides_what_to_write()) {
817 retransmissions.push_back(packet_number);
818 } else {
819 MarkForRetransmission(packet_number, RTO_RETRANSMISSION);
820 }
821 ++pending_timer_transmission_count_;
822 }
823 // Abandon non-retransmittable data that's in flight to ensure it doesn't
824 // fill up the congestion window.
825 bool has_retransmissions = it->retransmission.IsInitialized();
826 if (session_decides_what_to_write()) {
827 has_retransmissions = it->state != OUTSTANDING;
828 }
fayanga29eb242019-07-16 12:25:38 -0700829 if (!fix_rto_retransmission_ && it->in_flight && !has_retransmissions &&
QUICHE teama6ef0a62019-03-07 20:34:33 -0500830 !unacked_packets_.HasRetransmittableFrames(*it)) {
831 // Log only for non-retransmittable data.
832 // Retransmittable data is marked as lost during loss detection, and will
833 // be logged later.
834 unacked_packets_.RemoveFromInFlight(packet_number);
835 if (debug_delegate_ != nullptr) {
836 debug_delegate_->OnPacketLoss(packet_number, RTO_RETRANSMISSION,
837 clock_->Now());
838 }
839 }
840 }
841 if (pending_timer_transmission_count_ > 0) {
842 if (consecutive_rto_count_ == 0) {
843 first_rto_transmission_ = unacked_packets_.largest_sent_packet() + 1;
844 }
845 ++consecutive_rto_count_;
846 }
847 if (session_decides_what_to_write()) {
848 for (QuicPacketNumber retransmission : retransmissions) {
849 MarkForRetransmission(retransmission, RTO_RETRANSMISSION);
850 }
fayanga29eb242019-07-16 12:25:38 -0700851 if (fix_rto_retransmission_ && retransmissions.empty()) {
852 QUIC_BUG_IF(pending_timer_transmission_count_ != 0);
853 // No packets to be RTO retransmitted, raise up a credit to allow
854 // connection to send.
855 QUIC_CODE_COUNT(no_packets_to_be_rto_retransmitted);
856 pending_timer_transmission_count_ = 1;
857 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500858 }
859}
860
861QuicSentPacketManager::RetransmissionTimeoutMode
862QuicSentPacketManager::GetRetransmissionMode() const {
863 DCHECK(unacked_packets_.HasInFlightPackets());
864 if (!handshake_confirmed_ && unacked_packets_.HasPendingCryptoPackets()) {
865 return HANDSHAKE_MODE;
866 }
867 if (loss_algorithm_->GetLossTimeout() != QuicTime::Zero()) {
868 return LOSS_MODE;
869 }
870 if (consecutive_tlp_count_ < max_tail_loss_probes_) {
ianswett7ddb34f2019-07-15 12:17:43 -0700871 if (unacked_packets_.HasUnackedRetransmittableFrames()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500872 return TLP_MODE;
873 }
874 }
875 return RTO_MODE;
876}
877
878void QuicSentPacketManager::InvokeLossDetection(QuicTime time) {
879 if (!packets_acked_.empty()) {
880 DCHECK_LE(packets_acked_.front().packet_number,
881 packets_acked_.back().packet_number);
882 largest_newly_acked_ = packets_acked_.back().packet_number;
883 }
884 loss_algorithm_->DetectLosses(unacked_packets_, time, rtt_stats_,
885 largest_newly_acked_, packets_acked_,
886 &packets_lost_);
887 for (const LostPacket& packet : packets_lost_) {
888 ++stats_->packets_lost;
889 if (debug_delegate_ != nullptr) {
890 debug_delegate_->OnPacketLoss(packet.packet_number, LOSS_RETRANSMISSION,
891 time);
892 }
893
ianswett898306b2019-04-23 11:05:57 -0700894 if (loss_removes_from_inflight_) {
895 unacked_packets_.RemoveFromInFlight(packet.packet_number);
896 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500897 MarkForRetransmission(packet.packet_number, LOSS_RETRANSMISSION);
898 }
899}
900
901bool QuicSentPacketManager::MaybeUpdateRTT(QuicPacketNumber largest_acked,
902 QuicTime::Delta ack_delay_time,
903 QuicTime ack_receive_time) {
904 // We rely on ack_delay_time to compute an RTT estimate, so we
905 // only update rtt when the largest observed gets acked.
906 if (!unacked_packets_.IsUnacked(largest_acked)) {
907 return false;
908 }
909 // We calculate the RTT based on the highest ACKed packet number, the lower
910 // packet numbers will include the ACK aggregation delay.
911 const QuicTransmissionInfo& transmission_info =
912 unacked_packets_.GetTransmissionInfo(largest_acked);
913 // Ensure the packet has a valid sent time.
914 if (transmission_info.sent_time == QuicTime::Zero()) {
915 QUIC_BUG << "Acked packet has zero sent time, largest_acked:"
916 << largest_acked;
917 return false;
918 }
919 if (transmission_info.sent_time > ack_receive_time) {
920 QUIC_CODE_COUNT(quic_receive_acked_before_sending);
921 }
922
923 QuicTime::Delta send_delta = ack_receive_time - transmission_info.sent_time;
924 rtt_stats_.UpdateRtt(send_delta, ack_delay_time, ack_receive_time);
925
926 return true;
927}
928
929QuicTime::Delta QuicSentPacketManager::TimeUntilSend(QuicTime now) const {
930 // The TLP logic is entirely contained within QuicSentPacketManager, so the
931 // send algorithm does not need to be consulted.
932 if (pending_timer_transmission_count_ > 0) {
933 return QuicTime::Delta::Zero();
934 }
935
936 if (using_pacing_) {
937 return pacing_sender_.TimeUntilSend(now,
938 unacked_packets_.bytes_in_flight());
939 }
940
941 return send_algorithm_->CanSend(unacked_packets_.bytes_in_flight())
942 ? QuicTime::Delta::Zero()
943 : QuicTime::Delta::Infinite();
944}
945
946const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
947 // Don't set the timer if there is nothing to retransmit or we've already
948 // queued a tlp transmission and it hasn't been sent yet.
949 if (!unacked_packets_.HasInFlightPackets() ||
950 pending_timer_transmission_count_ > 0) {
951 return QuicTime::Zero();
952 }
ianswett7ddb34f2019-07-15 12:17:43 -0700953 if (!unacked_packets_.HasUnackedRetransmittableFrames()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500954 return QuicTime::Zero();
955 }
956 switch (GetRetransmissionMode()) {
957 case HANDSHAKE_MODE:
958 return unacked_packets_.GetLastCryptoPacketSentTime() +
959 GetCryptoRetransmissionDelay();
960 case LOSS_MODE:
961 return loss_algorithm_->GetLossTimeout();
962 case TLP_MODE: {
963 // TODO(ianswett): When CWND is available, it would be preferable to
964 // set the timer based on the earliest retransmittable packet.
965 // Base the updated timer on the send time of the last packet.
966 const QuicTime sent_time = unacked_packets_.GetLastPacketSentTime();
967 const QuicTime tlp_time = sent_time + GetTailLossProbeDelay();
968 // Ensure the TLP timer never gets set to a time in the past.
969 return std::max(clock_->ApproximateNow(), tlp_time);
970 }
971 case RTO_MODE: {
972 // The RTO is based on the first outstanding packet.
973 const QuicTime sent_time = unacked_packets_.GetLastPacketSentTime();
974 QuicTime rto_time = sent_time + GetRetransmissionDelay();
975 // Wait for TLP packets to be acked before an RTO fires.
976 QuicTime tlp_time =
977 unacked_packets_.GetLastPacketSentTime() + GetTailLossProbeDelay();
978 return std::max(tlp_time, rto_time);
979 }
980 }
981 DCHECK(false);
982 return QuicTime::Zero();
983}
984
985const QuicTime::Delta QuicSentPacketManager::GetPathDegradingDelay() const {
986 QuicTime::Delta delay = QuicTime::Delta::Zero();
987 for (size_t i = 0; i < max_tail_loss_probes_; ++i) {
988 delay = delay + GetTailLossProbeDelay(i);
989 }
990 for (size_t i = 0; i < kNumRetransmissionDelaysForPathDegradingDelay; ++i) {
991 delay = delay + GetRetransmissionDelay(i);
992 }
993 return delay;
994}
995
996const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay()
997 const {
998 // This is equivalent to the TailLossProbeDelay, but slightly more aggressive
999 // because crypto handshake messages don't incur a delayed ack time.
1000 QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
1001 int64_t delay_ms;
1002 if (conservative_handshake_retransmits_) {
1003 // Using the delayed ack time directly could cause conservative handshake
1004 // retransmissions to actually be more aggressive than the default.
fkastenholz59c653b2019-07-15 09:55:53 -07001005 delay_ms = std::max(peer_max_ack_delay_.ToMilliseconds(),
QUICHE teama6ef0a62019-03-07 20:34:33 -05001006 static_cast<int64_t>(2 * srtt.ToMilliseconds()));
1007 } else {
1008 delay_ms = std::max(kMinHandshakeTimeoutMs,
1009 static_cast<int64_t>(1.5 * srtt.ToMilliseconds()));
1010 }
1011 return QuicTime::Delta::FromMilliseconds(
1012 delay_ms << consecutive_crypto_retransmission_count_);
1013}
1014
1015const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay(
1016 size_t consecutive_tlp_count) const {
1017 QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
1018 if (enable_half_rtt_tail_loss_probe_ && consecutive_tlp_count == 0u) {
zhongyi1b2f7832019-06-14 13:31:34 -07001019 if (!ignore_tlpr_if_no_pending_stream_data_ ||
1020 !session_decides_what_to_write()) {
1021 return std::max(min_tlp_timeout_, srtt * 0.5);
1022 }
1023 QUIC_RELOADABLE_FLAG_COUNT_N(quic_ignore_tlpr_if_no_pending_stream_data, 1,
1024 5);
1025 if (unacked_packets().HasUnackedStreamData()) {
1026 // Enable TLPR if there are pending data packets.
1027 return std::max(min_tlp_timeout_, srtt * 0.5);
1028 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001029 }
1030 if (ietf_style_tlp_) {
1031 return std::max(min_tlp_timeout_, 1.5 * srtt + rtt_stats_.max_ack_delay());
1032 }
1033 if (ietf_style_2x_tlp_) {
1034 return std::max(min_tlp_timeout_, 2 * srtt + rtt_stats_.max_ack_delay());
1035 }
1036 if (!unacked_packets_.HasMultipleInFlightPackets()) {
1037 // This expression really should be using the delayed ack time, but in TCP
1038 // MinRTO was traditionally set to 2x the delayed ack timer and this
1039 // expression assumed QUIC did the same.
1040 return std::max(2 * srtt, 1.5 * srtt + (min_rto_timeout_ * 0.5));
1041 }
1042 return std::max(min_tlp_timeout_, 2 * srtt);
1043}
1044
1045const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay(
1046 size_t consecutive_rto_count) const {
1047 QuicTime::Delta retransmission_delay = QuicTime::Delta::Zero();
1048 if (rtt_stats_.smoothed_rtt().IsZero()) {
1049 // We are in the initial state, use default timeout values.
1050 retransmission_delay =
1051 QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs);
1052 } else {
1053 retransmission_delay =
1054 rtt_stats_.smoothed_rtt() + 4 * rtt_stats_.mean_deviation();
1055 if (retransmission_delay < min_rto_timeout_) {
1056 retransmission_delay = min_rto_timeout_;
1057 }
1058 }
1059
1060 // Calculate exponential back off.
1061 retransmission_delay =
1062 retransmission_delay *
1063 (1 << std::min<size_t>(consecutive_rto_count, kMaxRetransmissions));
1064
1065 if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) {
1066 return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs);
1067 }
1068 return retransmission_delay;
1069}
1070
wub967ba572019-04-01 09:27:52 -07001071QuicTime::Delta QuicSentPacketManager::GetSlowStartDuration() const {
1072 if (send_algorithm_->GetCongestionControlType() != kBBR) {
1073 return QuicTime::Delta::Infinite();
1074 }
1075
1076 if (!send_algorithm_->InSlowStart()) {
1077 return stats_->slowstart_duration;
1078 }
1079
1080 return clock_->ApproximateNow() - stats_->slowstart_start_time +
1081 stats_->slowstart_duration;
1082}
1083
vasilvvc48c8712019-03-11 13:38:16 -07001084std::string QuicSentPacketManager::GetDebugState() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001085 return send_algorithm_->GetDebugState();
1086}
1087
1088void QuicSentPacketManager::CancelRetransmissionsForStream(
1089 QuicStreamId stream_id) {
1090 if (session_decides_what_to_write()) {
1091 return;
1092 }
1093 unacked_packets_.CancelRetransmissionsForStream(stream_id);
1094 auto it = pending_retransmissions_.begin();
1095 while (it != pending_retransmissions_.end()) {
1096 if (unacked_packets_.HasRetransmittableFrames(it->first)) {
1097 ++it;
1098 continue;
1099 }
1100 it = pending_retransmissions_.erase(it);
1101 }
1102}
1103
1104void QuicSentPacketManager::SetSendAlgorithm(
1105 CongestionControlType congestion_control_type) {
1106 SetSendAlgorithm(SendAlgorithmInterface::Create(
QUICHE team73957f12019-04-18 16:21:52 -07001107 clock_, &rtt_stats_, &unacked_packets_, congestion_control_type, random_,
1108 stats_, initial_congestion_window_));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001109}
1110
1111void QuicSentPacketManager::SetSendAlgorithm(
1112 SendAlgorithmInterface* send_algorithm) {
1113 send_algorithm_.reset(send_algorithm);
1114 pacing_sender_.set_sender(send_algorithm);
1115}
1116
1117void QuicSentPacketManager::OnConnectionMigration(AddressChangeType type) {
1118 if (type == PORT_CHANGE || type == IPV4_SUBNET_CHANGE) {
1119 // Rtt and cwnd do not need to be reset when the peer address change is
1120 // considered to be caused by NATs.
1121 return;
1122 }
1123 consecutive_rto_count_ = 0;
1124 consecutive_tlp_count_ = 0;
1125 rtt_stats_.OnConnectionMigration();
1126 send_algorithm_->OnConnectionMigration();
1127}
1128
1129void QuicSentPacketManager::OnAckFrameStart(QuicPacketNumber largest_acked,
1130 QuicTime::Delta ack_delay_time,
1131 QuicTime ack_receive_time) {
1132 DCHECK(packets_acked_.empty());
1133 DCHECK_LE(largest_acked, unacked_packets_.largest_sent_packet());
1134 rtt_updated_ =
1135 MaybeUpdateRTT(largest_acked, ack_delay_time, ack_receive_time);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001136 last_ack_frame_.ack_delay_time = ack_delay_time;
1137 acked_packets_iter_ = last_ack_frame_.packets.rbegin();
1138}
1139
1140void QuicSentPacketManager::OnAckRange(QuicPacketNumber start,
1141 QuicPacketNumber end) {
1142 if (!last_ack_frame_.largest_acked.IsInitialized() ||
1143 end > last_ack_frame_.largest_acked + 1) {
1144 // Largest acked increases.
1145 unacked_packets_.IncreaseLargestAcked(end - 1);
1146 last_ack_frame_.largest_acked = end - 1;
1147 }
1148 // Drop ack ranges which ack packets below least_unacked.
1149 QuicPacketNumber least_unacked = unacked_packets_.GetLeastUnacked();
1150 if (least_unacked.IsInitialized() && end <= least_unacked) {
1151 return;
1152 }
1153 start = std::max(start, least_unacked);
1154 do {
1155 QuicPacketNumber newly_acked_start = start;
1156 if (acked_packets_iter_ != last_ack_frame_.packets.rend()) {
1157 newly_acked_start = std::max(start, acked_packets_iter_->max());
1158 }
1159 for (QuicPacketNumber acked = end - 1; acked >= newly_acked_start;
1160 --acked) {
1161 // Check if end is above the current range. If so add newly acked packets
1162 // in descending order.
1163 packets_acked_.push_back(AckedPacket(acked, 0, QuicTime::Zero()));
1164 if (acked == FirstSendingPacketNumber()) {
1165 break;
1166 }
1167 }
1168 if (acked_packets_iter_ == last_ack_frame_.packets.rend() ||
1169 start > acked_packets_iter_->min()) {
1170 // Finish adding all newly acked packets.
1171 return;
1172 }
1173 end = std::min(end, acked_packets_iter_->min());
1174 ++acked_packets_iter_;
1175 } while (start < end);
1176}
1177
1178void QuicSentPacketManager::OnAckTimestamp(QuicPacketNumber packet_number,
1179 QuicTime timestamp) {
1180 last_ack_frame_.received_packet_times.push_back({packet_number, timestamp});
1181 for (AckedPacket& packet : packets_acked_) {
1182 if (packet.packet_number == packet_number) {
1183 packet.receive_timestamp = timestamp;
1184 return;
1185 }
1186 }
1187}
1188
fayang3eb82212019-04-16 12:05:46 -07001189AckResult QuicSentPacketManager::OnAckFrameEnd(
1190 QuicTime ack_receive_time,
fayangf8e918b2019-07-16 13:03:16 -07001191 QuicPacketNumber ack_packet_number,
fayang3eb82212019-04-16 12:05:46 -07001192 EncryptionLevel ack_decrypted_level) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001193 QuicByteCount prior_bytes_in_flight = unacked_packets_.bytes_in_flight();
1194 // Reverse packets_acked_ so that it is in ascending order.
1195 reverse(packets_acked_.begin(), packets_acked_.end());
1196 for (AckedPacket& acked_packet : packets_acked_) {
1197 QuicTransmissionInfo* info =
1198 unacked_packets_.GetMutableTransmissionInfo(acked_packet.packet_number);
1199 if (!QuicUtils::IsAckable(info->state)) {
1200 if (info->state == ACKED) {
1201 QUIC_BUG << "Trying to ack an already acked packet: "
1202 << acked_packet.packet_number
1203 << ", last_ack_frame_: " << last_ack_frame_
1204 << ", least_unacked: " << unacked_packets_.GetLeastUnacked()
1205 << ", packets_acked_: " << packets_acked_;
1206 } else {
fayang3eb82212019-04-16 12:05:46 -07001207 QUIC_PEER_BUG << "Received "
1208 << QuicUtils::EncryptionLevelToString(ack_decrypted_level)
1209 << " ack for unackable packet: "
QUICHE teama6ef0a62019-03-07 20:34:33 -05001210 << acked_packet.packet_number << " with state: "
1211 << QuicUtils::SentPacketStateToString(info->state);
fayang3eb82212019-04-16 12:05:46 -07001212 if (supports_multiple_packet_number_spaces()) {
1213 if (info->state == NEVER_SENT) {
1214 return UNSENT_PACKETS_ACKED;
1215 }
1216 return UNACKABLE_PACKETS_ACKED;
1217 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001218 }
1219 continue;
1220 }
fayang3eb82212019-04-16 12:05:46 -07001221 QUIC_DVLOG(1) << ENDPOINT << "Got an "
1222 << QuicUtils::EncryptionLevelToString(ack_decrypted_level)
1223 << " ack for packet " << acked_packet.packet_number;
1224 const PacketNumberSpace packet_number_space =
fayangbf3d2862019-06-20 14:13:44 -07001225 unacked_packets_.GetPacketNumberSpace(info->encryption_level);
fayang3eb82212019-04-16 12:05:46 -07001226 if (supports_multiple_packet_number_spaces() &&
1227 QuicUtils::GetPacketNumberSpace(ack_decrypted_level) !=
1228 packet_number_space) {
1229 return PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE;
1230 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001231 last_ack_frame_.packets.Add(acked_packet.packet_number);
QUICHE teamc264e362019-03-19 14:21:06 -07001232 largest_packet_peer_knows_is_acked_.UpdateMax(info->largest_acked);
QUICHE teamc279cec2019-03-22 06:51:48 -07001233 if (supports_multiple_packet_number_spaces()) {
fayang3eb82212019-04-16 12:05:46 -07001234 largest_packets_peer_knows_is_acked_[packet_number_space].UpdateMax(
1235 info->largest_acked);
QUICHE teamc279cec2019-03-22 06:51:48 -07001236 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001237 // If data is associated with the most recent transmission of this
1238 // packet, then inform the caller.
1239 if (info->in_flight) {
1240 acked_packet.bytes_acked = info->bytes_sent;
1241 } else {
1242 // Unackable packets are skipped earlier.
1243 largest_newly_acked_ = acked_packet.packet_number;
1244 }
fayangbf3d2862019-06-20 14:13:44 -07001245 unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
1246 packet_number_space, acked_packet.packet_number);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001247 MarkPacketHandled(acked_packet.packet_number, info,
QUICHE team9467db02019-05-30 09:38:45 -07001248 last_ack_frame_.ack_delay_time,
1249 acked_packet.receive_timestamp);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001250 }
1251 const bool acked_new_packet = !packets_acked_.empty();
fayangf8e918b2019-07-16 13:03:16 -07001252 PostProcessNewlyAckedPackets(ack_packet_number, last_ack_frame_,
1253 ack_receive_time, rtt_updated_,
fayang3eb82212019-04-16 12:05:46 -07001254 prior_bytes_in_flight);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001255
fayang3eb82212019-04-16 12:05:46 -07001256 return acked_new_packet ? PACKETS_NEWLY_ACKED : NO_PACKETS_NEWLY_ACKED;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001257}
1258
1259void QuicSentPacketManager::SetDebugDelegate(DebugDelegate* debug_delegate) {
1260 debug_delegate_ = debug_delegate;
1261}
1262
1263void QuicSentPacketManager::OnApplicationLimited() {
1264 if (using_pacing_) {
1265 pacing_sender_.OnApplicationLimited();
1266 }
1267 send_algorithm_->OnApplicationLimited(unacked_packets_.bytes_in_flight());
1268 if (debug_delegate_ != nullptr) {
1269 debug_delegate_->OnApplicationLimited();
1270 }
1271}
1272
1273QuicTime QuicSentPacketManager::GetNextReleaseTime() const {
1274 return using_pacing_ ? pacing_sender_.ideal_next_packet_send_time()
1275 : QuicTime::Zero();
1276}
1277
1278void QuicSentPacketManager::SetInitialRtt(QuicTime::Delta rtt) {
1279 const QuicTime::Delta min_rtt =
1280 QuicTime::Delta::FromMicroseconds(kMinInitialRoundTripTimeUs);
1281 const QuicTime::Delta max_rtt =
1282 QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs);
1283 rtt_stats_.set_initial_rtt(std::max(min_rtt, std::min(max_rtt, rtt)));
1284}
1285
fayangd3016832019-08-08 07:24:45 -07001286void QuicSentPacketManager::SetSessionDecideWhatToWrite(
1287 bool session_decides_what_to_write) {
1288 if (GetQuicReloadableFlag(quic_fix_rto_retransmission2) &&
1289 session_decides_what_to_write) {
1290 fix_rto_retransmission_ = true;
1291 QUIC_RELOADABLE_FLAG_COUNT(quic_fix_rto_retransmission2);
1292 }
1293 unacked_packets_.SetSessionDecideWhatToWrite(session_decides_what_to_write);
1294}
1295
QUICHE teamc279cec2019-03-22 06:51:48 -07001296void QuicSentPacketManager::EnableMultiplePacketNumberSpacesSupport() {
1297 unacked_packets_.EnableMultiplePacketNumberSpacesSupport();
1298}
1299
1300QuicPacketNumber QuicSentPacketManager::GetLargestAckedPacket(
1301 EncryptionLevel decrypted_packet_level) const {
1302 DCHECK(supports_multiple_packet_number_spaces());
1303 return unacked_packets_.GetLargestAckedOfPacketNumberSpace(
1304 QuicUtils::GetPacketNumberSpace(decrypted_packet_level));
1305}
1306
1307QuicPacketNumber QuicSentPacketManager::GetLargestSentPacket(
1308 EncryptionLevel decrypted_packet_level) const {
1309 DCHECK(supports_multiple_packet_number_spaces());
1310 return unacked_packets_.GetLargestSentPacketOfPacketNumberSpace(
1311 decrypted_packet_level);
1312}
1313
1314QuicPacketNumber QuicSentPacketManager::GetLargestPacketPeerKnowsIsAcked(
1315 EncryptionLevel decrypted_packet_level) const {
1316 DCHECK(supports_multiple_packet_number_spaces());
1317 return largest_packets_peer_knows_is_acked_[QuicUtils::GetPacketNumberSpace(
1318 decrypted_packet_level)];
1319}
1320
QUICHE teama6ef0a62019-03-07 20:34:33 -05001321#undef ENDPOINT // undef for jumbo builds
1322} // namespace quic