blob: 90771f8c748e3b353dd580e5c6d98012e3798c0c [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 local_max_ack_delay_(
115 QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)),
116 peer_max_ack_delay_(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500117 QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)),
118 rtt_updated_(false),
QUICHE team9929cc42019-03-13 08:17:43 -0700119 acked_packets_iter_(last_ack_frame_.packets.rbegin()),
ianswett898306b2019-04-23 11:05:57 -0700120 loss_removes_from_inflight_(
zhongyi1b2f7832019-06-14 13:31:34 -0700121 GetQuicReloadableFlag(quic_loss_removes_from_inflight)),
122 ignore_tlpr_if_no_pending_stream_data_(
fayanga29eb242019-07-16 12:25:38 -0700123 GetQuicReloadableFlag(quic_ignore_tlpr_if_no_pending_stream_data)),
124 fix_rto_retransmission_(
125 GetQuicReloadableFlag(quic_fix_rto_retransmission)) {
ianswett898306b2019-04-23 11:05:57 -0700126 if (loss_removes_from_inflight_) {
127 QUIC_RELOADABLE_FLAG_COUNT(quic_loss_removes_from_inflight);
128 }
fayanga29eb242019-07-16 12:25:38 -0700129 if (fix_rto_retransmission_) {
130 QUIC_RELOADABLE_FLAG_COUNT(quic_fix_rto_retransmission);
131 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500132 SetSendAlgorithm(congestion_control_type);
133}
134
wub37ec5962019-04-03 09:02:51 -0700135LossDetectionInterface* QuicSentPacketManager::GetInitialLossAlgorithm() {
fayangbf3d2862019-06-20 14:13:44 -0700136 return &uber_loss_algorithm_;
wub37ec5962019-04-03 09:02:51 -0700137}
138
QUICHE teama6ef0a62019-03-07 20:34:33 -0500139QuicSentPacketManager::~QuicSentPacketManager() {}
140
141void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
142 const Perspective perspective = unacked_packets_.perspective();
143 if (config.HasReceivedInitialRoundTripTimeUs() &&
144 config.ReceivedInitialRoundTripTimeUs() > 0) {
145 if (!config.HasClientSentConnectionOption(kNRTT, perspective)) {
146 SetInitialRtt(QuicTime::Delta::FromMicroseconds(
147 config.ReceivedInitialRoundTripTimeUs()));
148 }
149 } else if (config.HasInitialRoundTripTimeUsToSend() &&
150 config.GetInitialRoundTripTimeUsToSend() > 0) {
151 SetInitialRtt(QuicTime::Delta::FromMicroseconds(
152 config.GetInitialRoundTripTimeUsToSend()));
153 }
154 if (config.HasClientSentConnectionOption(kMAD0, perspective)) {
155 rtt_stats_.set_ignore_max_ack_delay(true);
156 }
157 if (config.HasClientSentConnectionOption(kMAD1, perspective)) {
fkastenholz59c653b2019-07-15 09:55:53 -0700158 rtt_stats_.set_initial_max_ack_delay(local_max_ack_delay_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500159 }
160 if (config.HasClientSentConnectionOption(kMAD2, perspective)) {
161 min_tlp_timeout_ = QuicTime::Delta::Zero();
162 }
163 if (config.HasClientSentConnectionOption(kMAD3, perspective)) {
164 min_rto_timeout_ = QuicTime::Delta::Zero();
165 }
166 if (config.HasClientSentConnectionOption(kMAD4, perspective)) {
167 ietf_style_tlp_ = true;
168 }
169 if (config.HasClientSentConnectionOption(kMAD5, perspective)) {
170 ietf_style_2x_tlp_ = true;
171 }
172
173 // Configure congestion control.
174 if (config.HasClientRequestedIndependentOption(kTBBR, perspective)) {
175 SetSendAlgorithm(kBBR);
176 }
wuba9a43cb2019-07-17 15:22:42 -0700177 if (GetQuicReloadableFlag(quic_allow_client_enabled_bbr_v2) &&
178 config.HasClientRequestedIndependentOption(kB2ON, perspective)) {
179 QUIC_RELOADABLE_FLAG_COUNT(quic_allow_client_enabled_bbr_v2);
180 SetSendAlgorithm(kBBRv2);
181 }
182
QUICHE teama6ef0a62019-03-07 20:34:33 -0500183 if (config.HasClientRequestedIndependentOption(kRENO, perspective)) {
184 SetSendAlgorithm(kRenoBytes);
185 } else if (config.HasClientRequestedIndependentOption(kBYTE, perspective) ||
186 (GetQuicReloadableFlag(quic_default_to_bbr) &&
187 config.HasClientRequestedIndependentOption(kQBIC, perspective))) {
188 SetSendAlgorithm(kCubicBytes);
189 } else if (GetQuicReloadableFlag(quic_enable_pcc3) &&
190 config.HasClientRequestedIndependentOption(kTPCC, perspective)) {
191 SetSendAlgorithm(kPCC);
192 }
wuba9a43cb2019-07-17 15:22:42 -0700193
QUICHE teama6ef0a62019-03-07 20:34:33 -0500194 // Initial window.
195 if (GetQuicReloadableFlag(quic_unified_iw_options)) {
196 if (config.HasClientRequestedIndependentOption(kIW03, perspective)) {
197 initial_congestion_window_ = 3;
198 send_algorithm_->SetInitialCongestionWindowInPackets(3);
199 }
200 if (config.HasClientRequestedIndependentOption(kIW10, perspective)) {
201 initial_congestion_window_ = 10;
202 send_algorithm_->SetInitialCongestionWindowInPackets(10);
203 }
204 if (config.HasClientRequestedIndependentOption(kIW20, perspective)) {
205 initial_congestion_window_ = 20;
206 send_algorithm_->SetInitialCongestionWindowInPackets(20);
207 }
208 if (config.HasClientRequestedIndependentOption(kIW50, perspective)) {
209 initial_congestion_window_ = 50;
210 send_algorithm_->SetInitialCongestionWindowInPackets(50);
211 }
212 }
213
danzh88e3e052019-06-13 11:47:18 -0700214 using_pacing_ = !GetQuicFlag(FLAGS_quic_disable_pacing_for_perf_tests);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500215
QUICHE teama6ef0a62019-03-07 20:34:33 -0500216 if (config.HasClientSentConnectionOption(kNTLP, perspective)) {
217 max_tail_loss_probes_ = 0;
218 }
219 if (config.HasClientSentConnectionOption(k1TLP, perspective)) {
220 max_tail_loss_probes_ = 1;
221 }
222 if (config.HasClientSentConnectionOption(k1RTO, perspective)) {
223 max_rto_packets_ = 1;
224 }
225 if (config.HasClientSentConnectionOption(kTLPR, perspective)) {
226 enable_half_rtt_tail_loss_probe_ = true;
227 }
228 if (config.HasClientSentConnectionOption(kNRTO, perspective)) {
229 use_new_rto_ = true;
230 }
231 // Configure loss detection.
232 if (config.HasClientRequestedIndependentOption(kTIME, perspective)) {
fayangbf3d2862019-06-20 14:13:44 -0700233 uber_loss_algorithm_.SetLossDetectionType(kTime);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500234 }
235 if (config.HasClientRequestedIndependentOption(kATIM, perspective)) {
fayangbf3d2862019-06-20 14:13:44 -0700236 uber_loss_algorithm_.SetLossDetectionType(kAdaptiveTime);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500237 }
238 if (config.HasClientRequestedIndependentOption(kLFAK, perspective)) {
fayangbf3d2862019-06-20 14:13:44 -0700239 uber_loss_algorithm_.SetLossDetectionType(kLazyFack);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500240 }
241 if (config.HasClientSentConnectionOption(kCONH, perspective)) {
242 conservative_handshake_retransmits_ = true;
243 }
244 send_algorithm_->SetFromConfig(config, perspective);
245
fkastenholz4c7303c2019-07-29 08:17:07 -0700246 if (config.HasReceivedMaxAckDelayMs()) {
247 peer_max_ack_delay_ =
248 QuicTime::Delta::FromMilliseconds(config.ReceivedMaxAckDelayMs());
249 }
250
QUICHE teama6ef0a62019-03-07 20:34:33 -0500251 if (network_change_visitor_ != nullptr) {
252 network_change_visitor_->OnCongestionChange();
253 }
254}
255
256void QuicSentPacketManager::ResumeConnectionState(
257 const CachedNetworkParameters& cached_network_params,
258 bool max_bandwidth_resumption) {
259 QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(
260 max_bandwidth_resumption
261 ? cached_network_params.max_bandwidth_estimate_bytes_per_second()
262 : cached_network_params.bandwidth_estimate_bytes_per_second());
263 QuicTime::Delta rtt =
264 QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms());
fayangf1b99dc2019-05-14 06:29:18 -0700265 AdjustNetworkParameters(bandwidth, rtt, /*allow_cwnd_to_decrease=*/false);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500266}
267
fayangf1b99dc2019-05-14 06:29:18 -0700268void QuicSentPacketManager::AdjustNetworkParameters(
269 QuicBandwidth bandwidth,
270 QuicTime::Delta rtt,
271 bool allow_cwnd_to_decrease) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500272 if (!rtt.IsZero()) {
273 SetInitialRtt(rtt);
274 }
fayangbe83ecd2019-04-26 13:58:09 -0700275 const QuicByteCount old_cwnd = send_algorithm_->GetCongestionWindow();
fayang6c2d64f2019-05-20 17:12:05 -0700276 if (GetQuicReloadableFlag(quic_conservative_bursts) && using_pacing_ &&
277 !bandwidth.IsZero()) {
fayang4ba55982019-05-13 05:53:22 -0700278 QUIC_RELOADABLE_FLAG_COUNT(quic_conservative_bursts);
279 pacing_sender_.SetBurstTokens(kConservativeUnpacedBurst);
280 }
fayangf1b99dc2019-05-14 06:29:18 -0700281 send_algorithm_->AdjustNetworkParameters(bandwidth, rtt,
282 allow_cwnd_to_decrease);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500283 if (debug_delegate_ != nullptr) {
fayangbe83ecd2019-04-26 13:58:09 -0700284 debug_delegate_->OnAdjustNetworkParameters(
fayangef9c8f92019-04-29 13:35:13 -0700285 bandwidth, rtt.IsZero() ? rtt_stats_.SmoothedOrInitialRtt() : rtt,
286 old_cwnd, send_algorithm_->GetCongestionWindow());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500287 }
288}
289
290void QuicSentPacketManager::SetHandshakeConfirmed() {
291 handshake_confirmed_ = true;
fayangbf3d2862019-06-20 14:13:44 -0700292 NeuterHandshakePackets();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500293}
294
fayang3eb82212019-04-16 12:05:46 -0700295void QuicSentPacketManager::PostProcessNewlyAckedPackets(
fayangf8e918b2019-07-16 13:03:16 -0700296 QuicPacketNumber ack_packet_number,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500297 const QuicAckFrame& ack_frame,
298 QuicTime ack_receive_time,
299 bool rtt_updated,
300 QuicByteCount prior_bytes_in_flight) {
301 if (session_decides_what_to_write()) {
302 unacked_packets_.NotifyAggregatedStreamFrameAcked(
303 last_ack_frame_.ack_delay_time);
304 }
305 InvokeLossDetection(ack_receive_time);
306 // Ignore losses in RTO mode.
307 if (consecutive_rto_count_ > 0 && !use_new_rto_) {
308 packets_lost_.clear();
309 }
310 MaybeInvokeCongestionEvent(rtt_updated, prior_bytes_in_flight,
311 ack_receive_time);
312 unacked_packets_.RemoveObsoletePackets();
313
314 sustained_bandwidth_recorder_.RecordEstimate(
315 send_algorithm_->InRecovery(), send_algorithm_->InSlowStart(),
316 send_algorithm_->BandwidthEstimate(), ack_receive_time, clock_->WallNow(),
317 rtt_stats_.smoothed_rtt());
318
319 // Anytime we are making forward progress and have a new RTT estimate, reset
320 // the backoff counters.
321 if (rtt_updated) {
322 if (consecutive_rto_count_ > 0) {
323 // If the ack acknowledges data sent prior to the RTO,
324 // the RTO was spurious.
325 if (LargestAcked(ack_frame) < first_rto_transmission_) {
326 // Replace SRTT with latest_rtt and increase the variance to prevent
327 // a spurious RTO from happening again.
328 rtt_stats_.ExpireSmoothedMetrics();
329 } else {
330 if (!use_new_rto_) {
331 send_algorithm_->OnRetransmissionTimeout(true);
332 }
333 }
334 }
335 // Reset all retransmit counters any time a new packet is acked.
336 consecutive_rto_count_ = 0;
337 consecutive_tlp_count_ = 0;
338 consecutive_crypto_retransmission_count_ = 0;
339 }
340
341 if (debug_delegate_ != nullptr) {
fayangf8e918b2019-07-16 13:03:16 -0700342 debug_delegate_->OnIncomingAck(ack_packet_number, ack_frame,
343 ack_receive_time, LargestAcked(ack_frame),
344 rtt_updated, GetLeastUnacked());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500345 }
346 // Remove packets below least unacked from all_packets_acked_ and
347 // last_ack_frame_.
348 last_ack_frame_.packets.RemoveUpTo(unacked_packets_.GetLeastUnacked());
349 last_ack_frame_.received_packet_times.clear();
350}
351
352void QuicSentPacketManager::MaybeInvokeCongestionEvent(
353 bool rtt_updated,
354 QuicByteCount prior_in_flight,
355 QuicTime event_time) {
356 if (!rtt_updated && packets_acked_.empty() && packets_lost_.empty()) {
357 return;
358 }
359 if (using_pacing_) {
360 pacing_sender_.OnCongestionEvent(rtt_updated, prior_in_flight, event_time,
361 packets_acked_, packets_lost_);
362 } else {
363 send_algorithm_->OnCongestionEvent(rtt_updated, prior_in_flight, event_time,
364 packets_acked_, packets_lost_);
365 }
366 packets_acked_.clear();
367 packets_lost_.clear();
368 if (network_change_visitor_ != nullptr) {
369 network_change_visitor_->OnCongestionChange();
370 }
371}
372
373void QuicSentPacketManager::RetransmitUnackedPackets(
374 TransmissionType retransmission_type) {
375 DCHECK(retransmission_type == ALL_UNACKED_RETRANSMISSION ||
376 retransmission_type == ALL_INITIAL_RETRANSMISSION);
377 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
ianswett898306b2019-04-23 11:05:57 -0700378 for (QuicUnackedPacketMap::iterator it = unacked_packets_.begin();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500379 it != unacked_packets_.end(); ++it, ++packet_number) {
380 if ((retransmission_type == ALL_UNACKED_RETRANSMISSION ||
ianswett898306b2019-04-23 11:05:57 -0700381 it->encryption_level == ENCRYPTION_ZERO_RTT)) {
382 if (loss_removes_from_inflight_ && it->in_flight) {
383 // Remove 0-RTT packets and packets of the wrong version from flight,
384 // because neither can be processed by the peer.
385 unacked_packets_.RemoveFromInFlight(&*it);
386 }
387 if (unacked_packets_.HasRetransmittableFrames(*it)) {
388 MarkForRetransmission(packet_number, retransmission_type);
389 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500390 }
391 }
ianswett898306b2019-04-23 11:05:57 -0700392 if (retransmission_type == ALL_UNACKED_RETRANSMISSION &&
393 unacked_packets_.bytes_in_flight() > 0) {
394 QUIC_BUG << "RetransmitUnackedPackets should remove all packets from flight"
395 << ", bytes_in_flight:" << unacked_packets_.bytes_in_flight();
396 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500397}
398
399void QuicSentPacketManager::NeuterUnencryptedPackets() {
400 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
401 if (session_decides_what_to_write()) {
402 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
403 it != unacked_packets_.end(); ++it, ++packet_number) {
404 if (!it->retransmittable_frames.empty() &&
QUICHE team6987b4a2019-03-15 16:23:04 -0700405 it->encryption_level == ENCRYPTION_INITIAL) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500406 // Once the connection swithes to forward secure, no unencrypted packets
407 // will be sent. The data has been abandoned in the cryto stream. Remove
408 // it from in flight.
409 unacked_packets_.RemoveFromInFlight(packet_number);
410 }
411 }
412 return;
413 }
414 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
415 it != unacked_packets_.end(); ++it, ++packet_number) {
ianswett898306b2019-04-23 11:05:57 -0700416 if (it->encryption_level == ENCRYPTION_INITIAL) {
417 if (loss_removes_from_inflight_ ||
418 unacked_packets_.HasRetransmittableFrames(*it)) {
419 // Once you're forward secure, no unencrypted packets will be sent,
420 // crypto or otherwise. Unencrypted packets are neutered and abandoned,
421 // to ensure they are not retransmitted or considered lost from a
422 // congestion control perspective.
423 pending_retransmissions_.erase(packet_number);
424 unacked_packets_.RemoveFromInFlight(packet_number);
425 unacked_packets_.RemoveRetransmittability(packet_number);
426 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500427 }
428 }
429}
430
431void QuicSentPacketManager::NeuterHandshakePackets() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500432 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
433 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
434 it != unacked_packets_.end(); ++it, ++packet_number) {
435 if (session_decides_what_to_write()) {
436 if (!it->retransmittable_frames.empty() &&
437 unacked_packets_.GetPacketNumberSpace(it->encryption_level) ==
438 HANDSHAKE_DATA) {
439 unacked_packets_.RemoveFromInFlight(packet_number);
440 }
441 continue;
442 }
443 if (unacked_packets_.GetPacketNumberSpace(it->encryption_level) ==
444 HANDSHAKE_DATA &&
445 unacked_packets_.HasRetransmittableFrames(*it)) {
446 pending_retransmissions_.erase(packet_number);
447 unacked_packets_.RemoveFromInFlight(packet_number);
448 unacked_packets_.RemoveRetransmittability(packet_number);
449 }
450 }
451}
452
453void QuicSentPacketManager::MarkForRetransmission(
454 QuicPacketNumber packet_number,
455 TransmissionType transmission_type) {
456 QuicTransmissionInfo* transmission_info =
457 unacked_packets_.GetMutableTransmissionInfo(packet_number);
458 // When session decides what to write, a previous RTO retransmission may cause
459 // connection close; packets without retransmittable frames can be marked for
460 // loss retransmissions.
461 QUIC_BUG_IF((transmission_type != LOSS_RETRANSMISSION &&
462 (!session_decides_what_to_write() ||
463 transmission_type != RTO_RETRANSMISSION)) &&
464 !unacked_packets_.HasRetransmittableFrames(*transmission_info))
465 << "transmission_type: "
466 << QuicUtils::TransmissionTypeToString(transmission_type);
467 // Handshake packets should never be sent as probing retransmissions.
468 DCHECK(!transmission_info->has_crypto_handshake ||
469 transmission_type != PROBING_RETRANSMISSION);
ianswett898306b2019-04-23 11:05:57 -0700470 if (!loss_removes_from_inflight_ &&
471 !RetransmissionLeavesBytesInFlight(transmission_type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500472 unacked_packets_.RemoveFromInFlight(transmission_info);
473 }
474
475 if (!session_decides_what_to_write()) {
476 if (!unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
477 return;
478 }
479 if (!QuicContainsKey(pending_retransmissions_, packet_number)) {
480 pending_retransmissions_[packet_number] = transmission_type;
481 }
482 return;
483 }
484
485 HandleRetransmission(transmission_type, transmission_info);
486
487 // Update packet state according to transmission type.
488 transmission_info->state =
489 QuicUtils::RetransmissionTypeToPacketState(transmission_type);
490}
491
492void QuicSentPacketManager::HandleRetransmission(
493 TransmissionType transmission_type,
494 QuicTransmissionInfo* transmission_info) {
495 DCHECK(session_decides_what_to_write());
496 if (ShouldForceRetransmission(transmission_type)) {
497 // TODO(fayang): Consider to make RTO and PROBING retransmission
498 // strategies be configurable by applications. Today, TLP, RTO and PROBING
499 // retransmissions are handled similarly, i.e., always retranmist the
500 // oldest outstanding data. This is not ideal in general because different
501 // applications may want different strategies. For example, some
502 // applications may want to use higher priority stream data for bandwidth
503 // probing, and some applications want to consider RTO is an indication of
504 // loss, etc.
505 unacked_packets_.RetransmitFrames(*transmission_info, transmission_type);
506 return;
507 }
508
509 unacked_packets_.NotifyFramesLost(*transmission_info, transmission_type);
510 if (transmission_info->retransmittable_frames.empty()) {
511 return;
512 }
513
514 if (transmission_type == LOSS_RETRANSMISSION) {
515 // Record the first packet sent after loss, which allows to wait 1
516 // more RTT before giving up on this lost packet.
517 transmission_info->retransmission =
518 unacked_packets_.largest_sent_packet() + 1;
519 } else {
520 // Clear the recorded first packet sent after loss when version or
521 // encryption changes.
522 transmission_info->retransmission.Clear();
523 }
524}
525
526void QuicSentPacketManager::RecordOneSpuriousRetransmission(
527 const QuicTransmissionInfo& info) {
528 stats_->bytes_spuriously_retransmitted += info.bytes_sent;
529 ++stats_->packets_spuriously_retransmitted;
530 if (debug_delegate_ != nullptr) {
531 debug_delegate_->OnSpuriousPacketRetransmission(info.transmission_type,
532 info.bytes_sent);
533 }
534}
535
536void QuicSentPacketManager::RecordSpuriousRetransmissions(
537 const QuicTransmissionInfo& info,
538 QuicPacketNumber acked_packet_number) {
539 if (session_decides_what_to_write()) {
540 RecordOneSpuriousRetransmission(info);
541 if (info.transmission_type == LOSS_RETRANSMISSION) {
542 // Only inform the loss detection of spurious retransmits it caused.
543 loss_algorithm_->SpuriousRetransmitDetected(
544 unacked_packets_, clock_->Now(), rtt_stats_, acked_packet_number);
545 }
546 return;
547 }
548 QuicPacketNumber retransmission = info.retransmission;
549 while (retransmission.IsInitialized()) {
550 const QuicTransmissionInfo& retransmit_info =
551 unacked_packets_.GetTransmissionInfo(retransmission);
552 retransmission = retransmit_info.retransmission;
553 RecordOneSpuriousRetransmission(retransmit_info);
554 }
555 // Only inform the loss detection of spurious retransmits it caused.
556 if (unacked_packets_.GetTransmissionInfo(info.retransmission)
557 .transmission_type == LOSS_RETRANSMISSION) {
558 loss_algorithm_->SpuriousRetransmitDetected(
559 unacked_packets_, clock_->Now(), rtt_stats_, info.retransmission);
560 }
561}
562
563QuicPendingRetransmission QuicSentPacketManager::NextPendingRetransmission() {
564 QUIC_BUG_IF(pending_retransmissions_.empty())
565 << "Unexpected call to NextPendingRetransmission() with empty pending "
566 << "retransmission list. Corrupted memory usage imminent.";
567 QUIC_BUG_IF(session_decides_what_to_write())
568 << "Unexpected call to NextPendingRetransmission() when session handles "
569 "retransmissions";
570 QuicPacketNumber packet_number = pending_retransmissions_.begin()->first;
571 TransmissionType transmission_type = pending_retransmissions_.begin()->second;
572 if (unacked_packets_.HasPendingCryptoPackets()) {
573 // Ensure crypto packets are retransmitted before other packets.
574 for (const auto& pair : pending_retransmissions_) {
575 if (HasCryptoHandshake(
576 unacked_packets_.GetTransmissionInfo(pair.first))) {
577 packet_number = pair.first;
578 transmission_type = pair.second;
579 break;
580 }
581 }
582 }
583 DCHECK(unacked_packets_.IsUnacked(packet_number)) << packet_number;
584 const QuicTransmissionInfo& transmission_info =
585 unacked_packets_.GetTransmissionInfo(packet_number);
586 DCHECK(unacked_packets_.HasRetransmittableFrames(transmission_info));
587
588 return QuicPendingRetransmission(packet_number, transmission_type,
589 transmission_info);
590}
591
592QuicPacketNumber QuicSentPacketManager::GetNewestRetransmission(
593 QuicPacketNumber packet_number,
594 const QuicTransmissionInfo& transmission_info) const {
595 if (session_decides_what_to_write()) {
596 return packet_number;
597 }
598 QuicPacketNumber retransmission = transmission_info.retransmission;
599 while (retransmission.IsInitialized()) {
600 packet_number = retransmission;
601 retransmission =
602 unacked_packets_.GetTransmissionInfo(retransmission).retransmission;
603 }
604 return packet_number;
605}
606
607void QuicSentPacketManager::MarkPacketHandled(QuicPacketNumber packet_number,
608 QuicTransmissionInfo* info,
QUICHE team9467db02019-05-30 09:38:45 -0700609 QuicTime::Delta ack_delay_time,
610 QuicTime receive_timestamp) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500611 QuicPacketNumber newest_transmission =
612 GetNewestRetransmission(packet_number, *info);
613 // Remove the most recent packet, if it is pending retransmission.
614 pending_retransmissions_.erase(newest_transmission);
615
616 if (newest_transmission == packet_number) {
617 // Try to aggregate acked stream frames if acked packet is not a
618 // retransmission.
619 const bool fast_path = session_decides_what_to_write() &&
620 info->transmission_type == NOT_RETRANSMISSION;
621 if (fast_path) {
QUICHE team9467db02019-05-30 09:38:45 -0700622 unacked_packets_.MaybeAggregateAckedStreamFrame(*info, ack_delay_time,
623 receive_timestamp);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500624 } else {
625 if (session_decides_what_to_write()) {
626 unacked_packets_.NotifyAggregatedStreamFrameAcked(ack_delay_time);
627 }
QUICHE team9467db02019-05-30 09:38:45 -0700628 const bool new_data_acked = unacked_packets_.NotifyFramesAcked(
629 *info, ack_delay_time, receive_timestamp);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500630 if (session_decides_what_to_write() && !new_data_acked &&
631 info->transmission_type != NOT_RETRANSMISSION) {
632 // Record as a spurious retransmission if this packet is a
633 // retransmission and no new data gets acked.
634 QUIC_DVLOG(1) << "Detect spurious retransmitted packet "
635 << packet_number << " transmission type: "
636 << QuicUtils::TransmissionTypeToString(
637 info->transmission_type);
638 RecordSpuriousRetransmissions(*info, packet_number);
639 }
640 }
641 } else {
642 DCHECK(!session_decides_what_to_write());
643 RecordSpuriousRetransmissions(*info, packet_number);
644 // Remove the most recent packet from flight if it's a crypto handshake
645 // packet, since they won't be acked now that one has been processed.
646 // Other crypto handshake packets won't be in flight, only the newest
647 // transmission of a crypto packet is in flight at once.
648 // TODO(ianswett): Instead of handling all crypto packets special,
649 // only handle nullptr encrypted packets in a special way.
650 const QuicTransmissionInfo& newest_transmission_info =
651 unacked_packets_.GetTransmissionInfo(newest_transmission);
QUICHE team9467db02019-05-30 09:38:45 -0700652 unacked_packets_.NotifyFramesAcked(newest_transmission_info, ack_delay_time,
653 receive_timestamp);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500654 if (HasCryptoHandshake(newest_transmission_info)) {
655 unacked_packets_.RemoveFromInFlight(newest_transmission);
656 }
657 }
658
659 if (network_change_visitor_ != nullptr &&
660 info->bytes_sent > largest_mtu_acked_) {
661 largest_mtu_acked_ = info->bytes_sent;
662 network_change_visitor_->OnPathMtuIncreased(largest_mtu_acked_);
663 }
664 unacked_packets_.RemoveFromInFlight(info);
665 unacked_packets_.RemoveRetransmittability(info);
666 info->state = ACKED;
667}
668
669bool QuicSentPacketManager::OnPacketSent(
670 SerializedPacket* serialized_packet,
671 QuicPacketNumber original_packet_number,
672 QuicTime sent_time,
673 TransmissionType transmission_type,
674 HasRetransmittableData has_retransmittable_data) {
675 QuicPacketNumber packet_number = serialized_packet->packet_number;
676 DCHECK_LE(FirstSendingPacketNumber(), packet_number);
677 DCHECK(!unacked_packets_.IsUnacked(packet_number));
678 QUIC_BUG_IF(serialized_packet->encrypted_length == 0)
679 << "Cannot send empty packets.";
680
681 if (original_packet_number.IsInitialized()) {
682 pending_retransmissions_.erase(original_packet_number);
683 }
684
685 if (pending_timer_transmission_count_ > 0) {
686 --pending_timer_transmission_count_;
687 }
688
689 bool in_flight = has_retransmittable_data == HAS_RETRANSMITTABLE_DATA;
690 if (using_pacing_) {
691 pacing_sender_.OnPacketSent(
692 sent_time, unacked_packets_.bytes_in_flight(), packet_number,
693 serialized_packet->encrypted_length, has_retransmittable_data);
694 } else {
695 send_algorithm_->OnPacketSent(
696 sent_time, unacked_packets_.bytes_in_flight(), packet_number,
697 serialized_packet->encrypted_length, has_retransmittable_data);
698 }
699
700 unacked_packets_.AddSentPacket(serialized_packet, original_packet_number,
701 transmission_type, sent_time, in_flight);
702 // Reset the retransmission timer anytime a pending packet is sent.
703 return in_flight;
704}
705
706void QuicSentPacketManager::OnRetransmissionTimeout() {
707 DCHECK(unacked_packets_.HasInFlightPackets());
708 DCHECK_EQ(0u, pending_timer_transmission_count_);
709 // Handshake retransmission, timer based loss detection, TLP, and RTO are
710 // implemented with a single alarm. The handshake alarm is set when the
711 // handshake has not completed, the loss alarm is set when the loss detection
712 // algorithm says to, and the TLP and RTO alarms are set after that.
713 // The TLP alarm is always set to run for under an RTO.
714 switch (GetRetransmissionMode()) {
715 case HANDSHAKE_MODE:
716 ++stats_->crypto_retransmit_count;
717 RetransmitCryptoPackets();
718 return;
719 case LOSS_MODE: {
720 ++stats_->loss_timeout_count;
721 QuicByteCount prior_in_flight = unacked_packets_.bytes_in_flight();
722 const QuicTime now = clock_->Now();
723 InvokeLossDetection(now);
724 MaybeInvokeCongestionEvent(false, prior_in_flight, now);
725 return;
726 }
727 case TLP_MODE:
728 ++stats_->tlp_count;
729 ++consecutive_tlp_count_;
730 pending_timer_transmission_count_ = 1;
731 // TLPs prefer sending new data instead of retransmitting data, so
732 // give the connection a chance to write before completing the TLP.
733 return;
734 case RTO_MODE:
735 ++stats_->rto_count;
736 RetransmitRtoPackets();
737 return;
738 }
739}
740
741void QuicSentPacketManager::RetransmitCryptoPackets() {
742 DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode());
743 ++consecutive_crypto_retransmission_count_;
744 bool packet_retransmitted = false;
745 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
746 std::vector<QuicPacketNumber> crypto_retransmissions;
747 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
748 it != unacked_packets_.end(); ++it, ++packet_number) {
749 // Only retransmit frames which are in flight, and therefore have been sent.
750 if (!it->in_flight ||
751 (session_decides_what_to_write() && it->state != OUTSTANDING) ||
752 !it->has_crypto_handshake ||
753 !unacked_packets_.HasRetransmittableFrames(*it)) {
754 continue;
755 }
756 packet_retransmitted = true;
757 if (session_decides_what_to_write()) {
758 crypto_retransmissions.push_back(packet_number);
759 } else {
760 MarkForRetransmission(packet_number, HANDSHAKE_RETRANSMISSION);
761 }
762 ++pending_timer_transmission_count_;
763 }
764 DCHECK(packet_retransmitted) << "No crypto packets found to retransmit.";
765 if (session_decides_what_to_write()) {
766 for (QuicPacketNumber retransmission : crypto_retransmissions) {
767 MarkForRetransmission(retransmission, HANDSHAKE_RETRANSMISSION);
768 }
769 }
770}
771
772bool QuicSentPacketManager::MaybeRetransmitTailLossProbe() {
773 if (pending_timer_transmission_count_ == 0) {
774 return false;
775 }
776 if (!MaybeRetransmitOldestPacket(TLP_RETRANSMISSION)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500777 return false;
778 }
779 return true;
780}
781
782bool QuicSentPacketManager::MaybeRetransmitOldestPacket(TransmissionType type) {
783 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
784 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
785 it != unacked_packets_.end(); ++it, ++packet_number) {
786 // Only retransmit frames which are in flight, and therefore have been sent.
787 if (!it->in_flight ||
788 (session_decides_what_to_write() && it->state != OUTSTANDING) ||
789 !unacked_packets_.HasRetransmittableFrames(*it)) {
790 continue;
791 }
792 MarkForRetransmission(packet_number, type);
793 return true;
794 }
795 QUIC_DVLOG(1)
796 << "No retransmittable packets, so RetransmitOldestPacket failed.";
797 return false;
798}
799
800void QuicSentPacketManager::RetransmitRtoPackets() {
801 QUIC_BUG_IF(pending_timer_transmission_count_ > 0)
802 << "Retransmissions already queued:" << pending_timer_transmission_count_;
803 // Mark two packets for retransmission.
804 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
805 std::vector<QuicPacketNumber> retransmissions;
806 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
807 it != unacked_packets_.end(); ++it, ++packet_number) {
808 if ((!session_decides_what_to_write() || it->state == OUTSTANDING) &&
809 unacked_packets_.HasRetransmittableFrames(*it) &&
810 pending_timer_transmission_count_ < max_rto_packets_) {
811 if (session_decides_what_to_write()) {
812 retransmissions.push_back(packet_number);
813 } else {
814 MarkForRetransmission(packet_number, RTO_RETRANSMISSION);
815 }
816 ++pending_timer_transmission_count_;
817 }
818 // Abandon non-retransmittable data that's in flight to ensure it doesn't
819 // fill up the congestion window.
820 bool has_retransmissions = it->retransmission.IsInitialized();
821 if (session_decides_what_to_write()) {
822 has_retransmissions = it->state != OUTSTANDING;
823 }
fayanga29eb242019-07-16 12:25:38 -0700824 if (!fix_rto_retransmission_ && it->in_flight && !has_retransmissions &&
QUICHE teama6ef0a62019-03-07 20:34:33 -0500825 !unacked_packets_.HasRetransmittableFrames(*it)) {
826 // Log only for non-retransmittable data.
827 // Retransmittable data is marked as lost during loss detection, and will
828 // be logged later.
829 unacked_packets_.RemoveFromInFlight(packet_number);
830 if (debug_delegate_ != nullptr) {
831 debug_delegate_->OnPacketLoss(packet_number, RTO_RETRANSMISSION,
832 clock_->Now());
833 }
834 }
835 }
836 if (pending_timer_transmission_count_ > 0) {
837 if (consecutive_rto_count_ == 0) {
838 first_rto_transmission_ = unacked_packets_.largest_sent_packet() + 1;
839 }
840 ++consecutive_rto_count_;
841 }
842 if (session_decides_what_to_write()) {
843 for (QuicPacketNumber retransmission : retransmissions) {
844 MarkForRetransmission(retransmission, RTO_RETRANSMISSION);
845 }
fayanga29eb242019-07-16 12:25:38 -0700846 if (fix_rto_retransmission_ && retransmissions.empty()) {
847 QUIC_BUG_IF(pending_timer_transmission_count_ != 0);
848 // No packets to be RTO retransmitted, raise up a credit to allow
849 // connection to send.
850 QUIC_CODE_COUNT(no_packets_to_be_rto_retransmitted);
851 pending_timer_transmission_count_ = 1;
852 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500853 }
854}
855
856QuicSentPacketManager::RetransmissionTimeoutMode
857QuicSentPacketManager::GetRetransmissionMode() const {
858 DCHECK(unacked_packets_.HasInFlightPackets());
859 if (!handshake_confirmed_ && unacked_packets_.HasPendingCryptoPackets()) {
860 return HANDSHAKE_MODE;
861 }
862 if (loss_algorithm_->GetLossTimeout() != QuicTime::Zero()) {
863 return LOSS_MODE;
864 }
865 if (consecutive_tlp_count_ < max_tail_loss_probes_) {
ianswett7ddb34f2019-07-15 12:17:43 -0700866 if (unacked_packets_.HasUnackedRetransmittableFrames()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500867 return TLP_MODE;
868 }
869 }
870 return RTO_MODE;
871}
872
873void QuicSentPacketManager::InvokeLossDetection(QuicTime time) {
874 if (!packets_acked_.empty()) {
875 DCHECK_LE(packets_acked_.front().packet_number,
876 packets_acked_.back().packet_number);
877 largest_newly_acked_ = packets_acked_.back().packet_number;
878 }
879 loss_algorithm_->DetectLosses(unacked_packets_, time, rtt_stats_,
880 largest_newly_acked_, packets_acked_,
881 &packets_lost_);
882 for (const LostPacket& packet : packets_lost_) {
883 ++stats_->packets_lost;
884 if (debug_delegate_ != nullptr) {
885 debug_delegate_->OnPacketLoss(packet.packet_number, LOSS_RETRANSMISSION,
886 time);
887 }
888
ianswett898306b2019-04-23 11:05:57 -0700889 if (loss_removes_from_inflight_) {
890 unacked_packets_.RemoveFromInFlight(packet.packet_number);
891 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500892 MarkForRetransmission(packet.packet_number, LOSS_RETRANSMISSION);
893 }
894}
895
896bool QuicSentPacketManager::MaybeUpdateRTT(QuicPacketNumber largest_acked,
897 QuicTime::Delta ack_delay_time,
898 QuicTime ack_receive_time) {
899 // We rely on ack_delay_time to compute an RTT estimate, so we
900 // only update rtt when the largest observed gets acked.
901 if (!unacked_packets_.IsUnacked(largest_acked)) {
902 return false;
903 }
904 // We calculate the RTT based on the highest ACKed packet number, the lower
905 // packet numbers will include the ACK aggregation delay.
906 const QuicTransmissionInfo& transmission_info =
907 unacked_packets_.GetTransmissionInfo(largest_acked);
908 // Ensure the packet has a valid sent time.
909 if (transmission_info.sent_time == QuicTime::Zero()) {
910 QUIC_BUG << "Acked packet has zero sent time, largest_acked:"
911 << largest_acked;
912 return false;
913 }
914 if (transmission_info.sent_time > ack_receive_time) {
915 QUIC_CODE_COUNT(quic_receive_acked_before_sending);
916 }
917
918 QuicTime::Delta send_delta = ack_receive_time - transmission_info.sent_time;
919 rtt_stats_.UpdateRtt(send_delta, ack_delay_time, ack_receive_time);
920
921 return true;
922}
923
924QuicTime::Delta QuicSentPacketManager::TimeUntilSend(QuicTime now) const {
925 // The TLP logic is entirely contained within QuicSentPacketManager, so the
926 // send algorithm does not need to be consulted.
927 if (pending_timer_transmission_count_ > 0) {
928 return QuicTime::Delta::Zero();
929 }
930
931 if (using_pacing_) {
932 return pacing_sender_.TimeUntilSend(now,
933 unacked_packets_.bytes_in_flight());
934 }
935
936 return send_algorithm_->CanSend(unacked_packets_.bytes_in_flight())
937 ? QuicTime::Delta::Zero()
938 : QuicTime::Delta::Infinite();
939}
940
941const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
942 // Don't set the timer if there is nothing to retransmit or we've already
943 // queued a tlp transmission and it hasn't been sent yet.
944 if (!unacked_packets_.HasInFlightPackets() ||
945 pending_timer_transmission_count_ > 0) {
946 return QuicTime::Zero();
947 }
ianswett7ddb34f2019-07-15 12:17:43 -0700948 if (!unacked_packets_.HasUnackedRetransmittableFrames()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500949 return QuicTime::Zero();
950 }
951 switch (GetRetransmissionMode()) {
952 case HANDSHAKE_MODE:
953 return unacked_packets_.GetLastCryptoPacketSentTime() +
954 GetCryptoRetransmissionDelay();
955 case LOSS_MODE:
956 return loss_algorithm_->GetLossTimeout();
957 case TLP_MODE: {
958 // TODO(ianswett): When CWND is available, it would be preferable to
959 // set the timer based on the earliest retransmittable packet.
960 // Base the updated timer on the send time of the last packet.
961 const QuicTime sent_time = unacked_packets_.GetLastPacketSentTime();
962 const QuicTime tlp_time = sent_time + GetTailLossProbeDelay();
963 // Ensure the TLP timer never gets set to a time in the past.
964 return std::max(clock_->ApproximateNow(), tlp_time);
965 }
966 case RTO_MODE: {
967 // The RTO is based on the first outstanding packet.
968 const QuicTime sent_time = unacked_packets_.GetLastPacketSentTime();
969 QuicTime rto_time = sent_time + GetRetransmissionDelay();
970 // Wait for TLP packets to be acked before an RTO fires.
971 QuicTime tlp_time =
972 unacked_packets_.GetLastPacketSentTime() + GetTailLossProbeDelay();
973 return std::max(tlp_time, rto_time);
974 }
975 }
976 DCHECK(false);
977 return QuicTime::Zero();
978}
979
980const QuicTime::Delta QuicSentPacketManager::GetPathDegradingDelay() const {
981 QuicTime::Delta delay = QuicTime::Delta::Zero();
982 for (size_t i = 0; i < max_tail_loss_probes_; ++i) {
983 delay = delay + GetTailLossProbeDelay(i);
984 }
985 for (size_t i = 0; i < kNumRetransmissionDelaysForPathDegradingDelay; ++i) {
986 delay = delay + GetRetransmissionDelay(i);
987 }
988 return delay;
989}
990
991const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay()
992 const {
993 // This is equivalent to the TailLossProbeDelay, but slightly more aggressive
994 // because crypto handshake messages don't incur a delayed ack time.
995 QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
996 int64_t delay_ms;
997 if (conservative_handshake_retransmits_) {
998 // Using the delayed ack time directly could cause conservative handshake
999 // retransmissions to actually be more aggressive than the default.
fkastenholz59c653b2019-07-15 09:55:53 -07001000 delay_ms = std::max(peer_max_ack_delay_.ToMilliseconds(),
QUICHE teama6ef0a62019-03-07 20:34:33 -05001001 static_cast<int64_t>(2 * srtt.ToMilliseconds()));
1002 } else {
1003 delay_ms = std::max(kMinHandshakeTimeoutMs,
1004 static_cast<int64_t>(1.5 * srtt.ToMilliseconds()));
1005 }
1006 return QuicTime::Delta::FromMilliseconds(
1007 delay_ms << consecutive_crypto_retransmission_count_);
1008}
1009
1010const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay(
1011 size_t consecutive_tlp_count) const {
1012 QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
1013 if (enable_half_rtt_tail_loss_probe_ && consecutive_tlp_count == 0u) {
zhongyi1b2f7832019-06-14 13:31:34 -07001014 if (!ignore_tlpr_if_no_pending_stream_data_ ||
1015 !session_decides_what_to_write()) {
1016 return std::max(min_tlp_timeout_, srtt * 0.5);
1017 }
1018 QUIC_RELOADABLE_FLAG_COUNT_N(quic_ignore_tlpr_if_no_pending_stream_data, 1,
1019 5);
1020 if (unacked_packets().HasUnackedStreamData()) {
1021 // Enable TLPR if there are pending data packets.
1022 return std::max(min_tlp_timeout_, srtt * 0.5);
1023 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001024 }
1025 if (ietf_style_tlp_) {
1026 return std::max(min_tlp_timeout_, 1.5 * srtt + rtt_stats_.max_ack_delay());
1027 }
1028 if (ietf_style_2x_tlp_) {
1029 return std::max(min_tlp_timeout_, 2 * srtt + rtt_stats_.max_ack_delay());
1030 }
1031 if (!unacked_packets_.HasMultipleInFlightPackets()) {
1032 // This expression really should be using the delayed ack time, but in TCP
1033 // MinRTO was traditionally set to 2x the delayed ack timer and this
1034 // expression assumed QUIC did the same.
1035 return std::max(2 * srtt, 1.5 * srtt + (min_rto_timeout_ * 0.5));
1036 }
1037 return std::max(min_tlp_timeout_, 2 * srtt);
1038}
1039
1040const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay(
1041 size_t consecutive_rto_count) const {
1042 QuicTime::Delta retransmission_delay = QuicTime::Delta::Zero();
1043 if (rtt_stats_.smoothed_rtt().IsZero()) {
1044 // We are in the initial state, use default timeout values.
1045 retransmission_delay =
1046 QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs);
1047 } else {
1048 retransmission_delay =
1049 rtt_stats_.smoothed_rtt() + 4 * rtt_stats_.mean_deviation();
1050 if (retransmission_delay < min_rto_timeout_) {
1051 retransmission_delay = min_rto_timeout_;
1052 }
1053 }
1054
1055 // Calculate exponential back off.
1056 retransmission_delay =
1057 retransmission_delay *
1058 (1 << std::min<size_t>(consecutive_rto_count, kMaxRetransmissions));
1059
1060 if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) {
1061 return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs);
1062 }
1063 return retransmission_delay;
1064}
1065
wub967ba572019-04-01 09:27:52 -07001066QuicTime::Delta QuicSentPacketManager::GetSlowStartDuration() const {
1067 if (send_algorithm_->GetCongestionControlType() != kBBR) {
1068 return QuicTime::Delta::Infinite();
1069 }
1070
1071 if (!send_algorithm_->InSlowStart()) {
1072 return stats_->slowstart_duration;
1073 }
1074
1075 return clock_->ApproximateNow() - stats_->slowstart_start_time +
1076 stats_->slowstart_duration;
1077}
1078
vasilvvc48c8712019-03-11 13:38:16 -07001079std::string QuicSentPacketManager::GetDebugState() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001080 return send_algorithm_->GetDebugState();
1081}
1082
1083void QuicSentPacketManager::CancelRetransmissionsForStream(
1084 QuicStreamId stream_id) {
1085 if (session_decides_what_to_write()) {
1086 return;
1087 }
1088 unacked_packets_.CancelRetransmissionsForStream(stream_id);
1089 auto it = pending_retransmissions_.begin();
1090 while (it != pending_retransmissions_.end()) {
1091 if (unacked_packets_.HasRetransmittableFrames(it->first)) {
1092 ++it;
1093 continue;
1094 }
1095 it = pending_retransmissions_.erase(it);
1096 }
1097}
1098
1099void QuicSentPacketManager::SetSendAlgorithm(
1100 CongestionControlType congestion_control_type) {
1101 SetSendAlgorithm(SendAlgorithmInterface::Create(
QUICHE team73957f12019-04-18 16:21:52 -07001102 clock_, &rtt_stats_, &unacked_packets_, congestion_control_type, random_,
1103 stats_, initial_congestion_window_));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001104}
1105
1106void QuicSentPacketManager::SetSendAlgorithm(
1107 SendAlgorithmInterface* send_algorithm) {
1108 send_algorithm_.reset(send_algorithm);
1109 pacing_sender_.set_sender(send_algorithm);
1110}
1111
1112void QuicSentPacketManager::OnConnectionMigration(AddressChangeType type) {
1113 if (type == PORT_CHANGE || type == IPV4_SUBNET_CHANGE) {
1114 // Rtt and cwnd do not need to be reset when the peer address change is
1115 // considered to be caused by NATs.
1116 return;
1117 }
1118 consecutive_rto_count_ = 0;
1119 consecutive_tlp_count_ = 0;
1120 rtt_stats_.OnConnectionMigration();
1121 send_algorithm_->OnConnectionMigration();
1122}
1123
1124void QuicSentPacketManager::OnAckFrameStart(QuicPacketNumber largest_acked,
1125 QuicTime::Delta ack_delay_time,
1126 QuicTime ack_receive_time) {
1127 DCHECK(packets_acked_.empty());
1128 DCHECK_LE(largest_acked, unacked_packets_.largest_sent_packet());
1129 rtt_updated_ =
1130 MaybeUpdateRTT(largest_acked, ack_delay_time, ack_receive_time);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001131 last_ack_frame_.ack_delay_time = ack_delay_time;
1132 acked_packets_iter_ = last_ack_frame_.packets.rbegin();
1133}
1134
1135void QuicSentPacketManager::OnAckRange(QuicPacketNumber start,
1136 QuicPacketNumber end) {
1137 if (!last_ack_frame_.largest_acked.IsInitialized() ||
1138 end > last_ack_frame_.largest_acked + 1) {
1139 // Largest acked increases.
1140 unacked_packets_.IncreaseLargestAcked(end - 1);
1141 last_ack_frame_.largest_acked = end - 1;
1142 }
1143 // Drop ack ranges which ack packets below least_unacked.
1144 QuicPacketNumber least_unacked = unacked_packets_.GetLeastUnacked();
1145 if (least_unacked.IsInitialized() && end <= least_unacked) {
1146 return;
1147 }
1148 start = std::max(start, least_unacked);
1149 do {
1150 QuicPacketNumber newly_acked_start = start;
1151 if (acked_packets_iter_ != last_ack_frame_.packets.rend()) {
1152 newly_acked_start = std::max(start, acked_packets_iter_->max());
1153 }
1154 for (QuicPacketNumber acked = end - 1; acked >= newly_acked_start;
1155 --acked) {
1156 // Check if end is above the current range. If so add newly acked packets
1157 // in descending order.
1158 packets_acked_.push_back(AckedPacket(acked, 0, QuicTime::Zero()));
1159 if (acked == FirstSendingPacketNumber()) {
1160 break;
1161 }
1162 }
1163 if (acked_packets_iter_ == last_ack_frame_.packets.rend() ||
1164 start > acked_packets_iter_->min()) {
1165 // Finish adding all newly acked packets.
1166 return;
1167 }
1168 end = std::min(end, acked_packets_iter_->min());
1169 ++acked_packets_iter_;
1170 } while (start < end);
1171}
1172
1173void QuicSentPacketManager::OnAckTimestamp(QuicPacketNumber packet_number,
1174 QuicTime timestamp) {
1175 last_ack_frame_.received_packet_times.push_back({packet_number, timestamp});
1176 for (AckedPacket& packet : packets_acked_) {
1177 if (packet.packet_number == packet_number) {
1178 packet.receive_timestamp = timestamp;
1179 return;
1180 }
1181 }
1182}
1183
fayang3eb82212019-04-16 12:05:46 -07001184AckResult QuicSentPacketManager::OnAckFrameEnd(
1185 QuicTime ack_receive_time,
fayangf8e918b2019-07-16 13:03:16 -07001186 QuicPacketNumber ack_packet_number,
fayang3eb82212019-04-16 12:05:46 -07001187 EncryptionLevel ack_decrypted_level) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001188 QuicByteCount prior_bytes_in_flight = unacked_packets_.bytes_in_flight();
1189 // Reverse packets_acked_ so that it is in ascending order.
1190 reverse(packets_acked_.begin(), packets_acked_.end());
1191 for (AckedPacket& acked_packet : packets_acked_) {
1192 QuicTransmissionInfo* info =
1193 unacked_packets_.GetMutableTransmissionInfo(acked_packet.packet_number);
1194 if (!QuicUtils::IsAckable(info->state)) {
1195 if (info->state == ACKED) {
1196 QUIC_BUG << "Trying to ack an already acked packet: "
1197 << acked_packet.packet_number
1198 << ", last_ack_frame_: " << last_ack_frame_
1199 << ", least_unacked: " << unacked_packets_.GetLeastUnacked()
1200 << ", packets_acked_: " << packets_acked_;
1201 } else {
fayang3eb82212019-04-16 12:05:46 -07001202 QUIC_PEER_BUG << "Received "
1203 << QuicUtils::EncryptionLevelToString(ack_decrypted_level)
1204 << " ack for unackable packet: "
QUICHE teama6ef0a62019-03-07 20:34:33 -05001205 << acked_packet.packet_number << " with state: "
1206 << QuicUtils::SentPacketStateToString(info->state);
fayang3eb82212019-04-16 12:05:46 -07001207 if (supports_multiple_packet_number_spaces()) {
1208 if (info->state == NEVER_SENT) {
1209 return UNSENT_PACKETS_ACKED;
1210 }
1211 return UNACKABLE_PACKETS_ACKED;
1212 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001213 }
1214 continue;
1215 }
fayang3eb82212019-04-16 12:05:46 -07001216 QUIC_DVLOG(1) << ENDPOINT << "Got an "
1217 << QuicUtils::EncryptionLevelToString(ack_decrypted_level)
1218 << " ack for packet " << acked_packet.packet_number;
1219 const PacketNumberSpace packet_number_space =
fayangbf3d2862019-06-20 14:13:44 -07001220 unacked_packets_.GetPacketNumberSpace(info->encryption_level);
fayang3eb82212019-04-16 12:05:46 -07001221 if (supports_multiple_packet_number_spaces() &&
1222 QuicUtils::GetPacketNumberSpace(ack_decrypted_level) !=
1223 packet_number_space) {
1224 return PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE;
1225 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001226 last_ack_frame_.packets.Add(acked_packet.packet_number);
QUICHE teamc264e362019-03-19 14:21:06 -07001227 largest_packet_peer_knows_is_acked_.UpdateMax(info->largest_acked);
QUICHE teamc279cec2019-03-22 06:51:48 -07001228 if (supports_multiple_packet_number_spaces()) {
fayang3eb82212019-04-16 12:05:46 -07001229 largest_packets_peer_knows_is_acked_[packet_number_space].UpdateMax(
1230 info->largest_acked);
QUICHE teamc279cec2019-03-22 06:51:48 -07001231 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001232 // If data is associated with the most recent transmission of this
1233 // packet, then inform the caller.
1234 if (info->in_flight) {
1235 acked_packet.bytes_acked = info->bytes_sent;
1236 } else {
1237 // Unackable packets are skipped earlier.
1238 largest_newly_acked_ = acked_packet.packet_number;
1239 }
fayangbf3d2862019-06-20 14:13:44 -07001240 unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
1241 packet_number_space, acked_packet.packet_number);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001242 MarkPacketHandled(acked_packet.packet_number, info,
QUICHE team9467db02019-05-30 09:38:45 -07001243 last_ack_frame_.ack_delay_time,
1244 acked_packet.receive_timestamp);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001245 }
1246 const bool acked_new_packet = !packets_acked_.empty();
fayangf8e918b2019-07-16 13:03:16 -07001247 PostProcessNewlyAckedPackets(ack_packet_number, last_ack_frame_,
1248 ack_receive_time, rtt_updated_,
fayang3eb82212019-04-16 12:05:46 -07001249 prior_bytes_in_flight);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001250
fayang3eb82212019-04-16 12:05:46 -07001251 return acked_new_packet ? PACKETS_NEWLY_ACKED : NO_PACKETS_NEWLY_ACKED;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001252}
1253
1254void QuicSentPacketManager::SetDebugDelegate(DebugDelegate* debug_delegate) {
1255 debug_delegate_ = debug_delegate;
1256}
1257
1258void QuicSentPacketManager::OnApplicationLimited() {
1259 if (using_pacing_) {
1260 pacing_sender_.OnApplicationLimited();
1261 }
1262 send_algorithm_->OnApplicationLimited(unacked_packets_.bytes_in_flight());
1263 if (debug_delegate_ != nullptr) {
1264 debug_delegate_->OnApplicationLimited();
1265 }
1266}
1267
1268QuicTime QuicSentPacketManager::GetNextReleaseTime() const {
1269 return using_pacing_ ? pacing_sender_.ideal_next_packet_send_time()
1270 : QuicTime::Zero();
1271}
1272
1273void QuicSentPacketManager::SetInitialRtt(QuicTime::Delta rtt) {
1274 const QuicTime::Delta min_rtt =
1275 QuicTime::Delta::FromMicroseconds(kMinInitialRoundTripTimeUs);
1276 const QuicTime::Delta max_rtt =
1277 QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs);
1278 rtt_stats_.set_initial_rtt(std::max(min_rtt, std::min(max_rtt, rtt)));
1279}
1280
QUICHE teamc279cec2019-03-22 06:51:48 -07001281void QuicSentPacketManager::EnableMultiplePacketNumberSpacesSupport() {
1282 unacked_packets_.EnableMultiplePacketNumberSpacesSupport();
1283}
1284
1285QuicPacketNumber QuicSentPacketManager::GetLargestAckedPacket(
1286 EncryptionLevel decrypted_packet_level) const {
1287 DCHECK(supports_multiple_packet_number_spaces());
1288 return unacked_packets_.GetLargestAckedOfPacketNumberSpace(
1289 QuicUtils::GetPacketNumberSpace(decrypted_packet_level));
1290}
1291
1292QuicPacketNumber QuicSentPacketManager::GetLargestSentPacket(
1293 EncryptionLevel decrypted_packet_level) const {
1294 DCHECK(supports_multiple_packet_number_spaces());
1295 return unacked_packets_.GetLargestSentPacketOfPacketNumberSpace(
1296 decrypted_packet_level);
1297}
1298
1299QuicPacketNumber QuicSentPacketManager::GetLargestPacketPeerKnowsIsAcked(
1300 EncryptionLevel decrypted_packet_level) const {
1301 DCHECK(supports_multiple_packet_number_spaces());
1302 return largest_packets_peer_knows_is_acked_[QuicUtils::GetPacketNumberSpace(
1303 decrypted_packet_level)];
1304}
1305
QUICHE teama6ef0a62019-03-07 20:34:33 -05001306#undef ENDPOINT // undef for jumbo builds
1307} // namespace quic