Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(173)

Side by Side Diff: net/quic/quic_sent_packet_manager.cc

Issue 2193073003: Move shared files in net/quic/ into net/quic/core/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: io_thread_unittest.cc Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/quic/quic_sent_packet_manager.h ('k') | net/quic/quic_sent_packet_manager_interface.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // 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/quic/quic_sent_packet_manager.h"
6
7 #include <algorithm>
8
9 #include "base/logging.h"
10 #include "base/stl_util.h"
11 #include "net/quic/chromium/quic_utils_chromium.h"
12 #include "net/quic/congestion_control/general_loss_algorithm.h"
13 #include "net/quic/congestion_control/pacing_sender.h"
14 #include "net/quic/crypto/crypto_protocol.h"
15 #include "net/quic/proto/cached_network_parameters.pb.h"
16 #include "net/quic/quic_bug_tracker.h"
17 #include "net/quic/quic_connection_stats.h"
18 #include "net/quic/quic_flags.h"
19
20 using std::max;
21 using std::min;
22 using std::pair;
23
24 namespace net {
25
26 namespace {
27 static const int64_t kDefaultRetransmissionTimeMs = 500;
28 static const int64_t kMaxRetransmissionTimeMs = 60000;
29 // Maximum number of exponential backoffs used for RTO timeouts.
30 static const size_t kMaxRetransmissions = 10;
31 // Maximum number of packets retransmitted upon an RTO.
32 static const size_t kMaxRetransmissionsOnTimeout = 2;
33 // Minimum number of consecutive RTOs before path is considered to be degrading.
34 const size_t kMinTimeoutsBeforePathDegrading = 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.
38 static 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.
42 static const size_t kDefaultMaxTailLossProbes = 2;
43
44 // Number of unpaced packets to send after quiescence.
45 static const size_t kInitialUnpacedBurst = 10;
46
47 bool HasCryptoHandshake(const TransmissionInfo& transmission_info) {
48 DCHECK(!transmission_info.has_crypto_handshake ||
49 !transmission_info.retransmittable_frames.empty());
50 return transmission_info.has_crypto_handshake;
51 }
52
53 } // namespace
54
55 #define ENDPOINT \
56 (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
57
58 QuicSentPacketManager::QuicSentPacketManager(
59 Perspective perspective,
60 QuicPathId path_id,
61 const QuicClock* clock,
62 QuicConnectionStats* stats,
63 CongestionControlType congestion_control_type,
64 LossDetectionType loss_type,
65 MultipathDelegateInterface* delegate)
66 : unacked_packets_(),
67 perspective_(perspective),
68 path_id_(path_id),
69 clock_(clock),
70 stats_(stats),
71 delegate_(delegate),
72 debug_delegate_(nullptr),
73 network_change_visitor_(nullptr),
74 initial_congestion_window_(kInitialCongestionWindow),
75 send_algorithm_(
76 SendAlgorithmInterface::Create(clock,
77 &rtt_stats_,
78 congestion_control_type,
79 stats,
80 initial_congestion_window_)),
81 loss_algorithm_(new GeneralLossAlgorithm(loss_type)),
82 n_connection_simulation_(false),
83 receive_buffer_bytes_(kDefaultSocketReceiveBuffer),
84 least_packet_awaited_by_peer_(1),
85 first_rto_transmission_(0),
86 consecutive_rto_count_(0),
87 consecutive_tlp_count_(0),
88 consecutive_crypto_retransmission_count_(0),
89 pending_timer_transmission_count_(0),
90 max_tail_loss_probes_(kDefaultMaxTailLossProbes),
91 enable_half_rtt_tail_loss_probe_(false),
92 using_pacing_(false),
93 use_new_rto_(false),
94 undo_pending_retransmits_(false),
95 largest_newly_acked_(0),
96 largest_mtu_acked_(0),
97 handshake_confirmed_(false) {}
98
99 QuicSentPacketManager::~QuicSentPacketManager() {}
100
101 void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
102 if (config.HasReceivedInitialRoundTripTimeUs() &&
103 config.ReceivedInitialRoundTripTimeUs() > 0) {
104 rtt_stats_.set_initial_rtt_us(
105 max(kMinInitialRoundTripTimeUs,
106 min(kMaxInitialRoundTripTimeUs,
107 config.ReceivedInitialRoundTripTimeUs())));
108 } else if (config.HasInitialRoundTripTimeUsToSend() &&
109 config.GetInitialRoundTripTimeUsToSend() > 0) {
110 rtt_stats_.set_initial_rtt_us(
111 max(kMinInitialRoundTripTimeUs,
112 min(kMaxInitialRoundTripTimeUs,
113 config.GetInitialRoundTripTimeUsToSend())));
114 }
115 // TODO(ianswett): BBR is currently a server only feature.
116 if (FLAGS_quic_allow_bbr && config.HasReceivedConnectionOptions() &&
117 ContainsQuicTag(config.ReceivedConnectionOptions(), kTBBR)) {
118 send_algorithm_.reset(SendAlgorithmInterface::Create(
119 clock_, &rtt_stats_, kBBR, stats_, initial_congestion_window_));
120 }
121 if (config.HasReceivedConnectionOptions() &&
122 ContainsQuicTag(config.ReceivedConnectionOptions(), kRENO)) {
123 if (ContainsQuicTag(config.ReceivedConnectionOptions(), kBYTE)) {
124 send_algorithm_.reset(SendAlgorithmInterface::Create(
125 clock_, &rtt_stats_, kRenoBytes, stats_, initial_congestion_window_));
126 } else {
127 send_algorithm_.reset(SendAlgorithmInterface::Create(
128 clock_, &rtt_stats_, kReno, stats_, initial_congestion_window_));
129 }
130 } else if (config.HasReceivedConnectionOptions() &&
131 ContainsQuicTag(config.ReceivedConnectionOptions(), kBYTE)) {
132 send_algorithm_.reset(SendAlgorithmInterface::Create(
133 clock_, &rtt_stats_, kCubicBytes, stats_, initial_congestion_window_));
134 }
135 if (!FLAGS_quic_disable_pacing_for_perf_tests) {
136 EnablePacing();
137 }
138
139 if (config.HasClientSentConnectionOption(k1CON, perspective_)) {
140 send_algorithm_->SetNumEmulatedConnections(1);
141 }
142 if (config.HasClientSentConnectionOption(kNCON, perspective_)) {
143 n_connection_simulation_ = true;
144 }
145 if (config.HasClientSentConnectionOption(kNTLP, perspective_)) {
146 max_tail_loss_probes_ = 0;
147 }
148 if (config.HasClientSentConnectionOption(kTLPR, perspective_)) {
149 enable_half_rtt_tail_loss_probe_ = true;
150 }
151 if (config.HasClientSentConnectionOption(kNRTO, perspective_)) {
152 use_new_rto_ = true;
153 }
154 if (config.HasReceivedConnectionOptions() &&
155 ContainsQuicTag(config.ReceivedConnectionOptions(), kTIME)) {
156 loss_algorithm_.reset(new GeneralLossAlgorithm(kTime));
157 }
158 if (config.HasReceivedConnectionOptions() &&
159 ContainsQuicTag(config.ReceivedConnectionOptions(), kATIM)) {
160 loss_algorithm_.reset(new GeneralLossAlgorithm(kAdaptiveTime));
161 }
162 if (FLAGS_quic_loss_recovery_use_largest_acked &&
163 config.HasClientSentConnectionOption(kUNDO, perspective_)) {
164 undo_pending_retransmits_ = true;
165 }
166 send_algorithm_->SetFromConfig(config, perspective_);
167
168 if (network_change_visitor_ != nullptr) {
169 network_change_visitor_->OnCongestionChange();
170 }
171 }
172
173 void QuicSentPacketManager::ResumeConnectionState(
174 const CachedNetworkParameters& cached_network_params,
175 bool max_bandwidth_resumption) {
176 if (cached_network_params.has_min_rtt_ms()) {
177 uint32_t initial_rtt_us =
178 kNumMicrosPerMilli * cached_network_params.min_rtt_ms();
179 rtt_stats_.set_initial_rtt_us(
180 max(kMinInitialRoundTripTimeUs,
181 min(kMaxInitialRoundTripTimeUs, initial_rtt_us)));
182 }
183 send_algorithm_->ResumeConnectionState(cached_network_params,
184 max_bandwidth_resumption);
185 }
186
187 void QuicSentPacketManager::SetNumOpenStreams(size_t num_streams) {
188 if (n_connection_simulation_) {
189 // Ensure the number of connections is between 1 and 5.
190 send_algorithm_->SetNumEmulatedConnections(
191 min<size_t>(5, max<size_t>(1, num_streams)));
192 }
193 }
194
195 void QuicSentPacketManager::SetMaxPacingRate(QuicBandwidth max_pacing_rate) {
196 if (using_pacing_) {
197 static_cast<PacingSender*>(send_algorithm_.get())
198 ->SetMaxPacingRate(max_pacing_rate);
199 }
200 }
201
202 void QuicSentPacketManager::SetHandshakeConfirmed() {
203 handshake_confirmed_ = true;
204 }
205
206 void QuicSentPacketManager::OnIncomingAck(const QuicAckFrame& ack_frame,
207 QuicTime ack_receive_time) {
208 DCHECK_LE(ack_frame.largest_observed, unacked_packets_.largest_sent_packet());
209 QuicByteCount bytes_in_flight = unacked_packets_.bytes_in_flight();
210 UpdatePacketInformationReceivedByPeer(ack_frame);
211 bool rtt_updated = MaybeUpdateRTT(ack_frame, ack_receive_time);
212 DCHECK_GE(ack_frame.largest_observed, unacked_packets_.largest_observed());
213 unacked_packets_.IncreaseLargestObserved(ack_frame.largest_observed);
214
215 HandleAckForSentPackets(ack_frame);
216 InvokeLossDetection(ack_receive_time);
217 // Ignore losses in RTO mode.
218 if (consecutive_rto_count_ > 0 && !use_new_rto_) {
219 packets_lost_.clear();
220 }
221 MaybeInvokeCongestionEvent(rtt_updated, bytes_in_flight);
222 unacked_packets_.RemoveObsoletePackets();
223
224 sustained_bandwidth_recorder_.RecordEstimate(
225 send_algorithm_->InRecovery(), send_algorithm_->InSlowStart(),
226 send_algorithm_->BandwidthEstimate(), ack_receive_time, clock_->WallNow(),
227 rtt_stats_.smoothed_rtt());
228
229 // Anytime we are making forward progress and have a new RTT estimate, reset
230 // the backoff counters.
231 if (rtt_updated) {
232 if (consecutive_rto_count_ > 0) {
233 // If the ack acknowledges data sent prior to the RTO,
234 // the RTO was spurious.
235 if (ack_frame.largest_observed < first_rto_transmission_) {
236 // Replace SRTT with latest_rtt and increase the variance to prevent
237 // a spurious RTO from happening again.
238 rtt_stats_.ExpireSmoothedMetrics();
239 } else {
240 if (!use_new_rto_) {
241 send_algorithm_->OnRetransmissionTimeout(true);
242 }
243 }
244 }
245 // Reset all retransmit counters any time a new packet is acked.
246 consecutive_rto_count_ = 0;
247 consecutive_tlp_count_ = 0;
248 consecutive_crypto_retransmission_count_ = 0;
249 }
250 // TODO(ianswett): Consider replacing the pending_retransmissions_ with a
251 // fast way to retrieve the next pending retransmission, if there are any.
252 // A single packet number indicating all packets below that are lost should
253 // be all the state that is necessary.
254 while (undo_pending_retransmits_ && !pending_retransmissions_.empty() &&
255 pending_retransmissions_.front().first > largest_newly_acked_ &&
256 pending_retransmissions_.front().second == LOSS_RETRANSMISSION) {
257 // Cancel any pending retransmissions larger than largest_newly_acked_.
258 unacked_packets_.RestoreToInFlight(pending_retransmissions_.front().first);
259 pending_retransmissions_.erase(pending_retransmissions_.begin());
260 }
261
262 if (debug_delegate_ != nullptr) {
263 debug_delegate_->OnIncomingAck(ack_frame, ack_receive_time,
264 unacked_packets_.largest_observed(),
265 rtt_updated, GetLeastUnacked(path_id_));
266 }
267 }
268
269 void QuicSentPacketManager::UpdatePacketInformationReceivedByPeer(
270 const QuicAckFrame& ack_frame) {
271 if (ack_frame.packets.Empty()) {
272 least_packet_awaited_by_peer_ = ack_frame.largest_observed + 1;
273 } else {
274 least_packet_awaited_by_peer_ = ack_frame.packets.Min();
275 }
276 }
277
278 void QuicSentPacketManager::MaybeInvokeCongestionEvent(
279 bool rtt_updated,
280 QuicByteCount bytes_in_flight) {
281 if (!rtt_updated && packets_acked_.empty() && packets_lost_.empty()) {
282 return;
283 }
284 send_algorithm_->OnCongestionEvent(rtt_updated, bytes_in_flight,
285 packets_acked_, packets_lost_);
286 packets_acked_.clear();
287 packets_lost_.clear();
288 if (network_change_visitor_ != nullptr) {
289 network_change_visitor_->OnCongestionChange();
290 }
291 }
292
293 void QuicSentPacketManager::HandleAckForSentPackets(
294 const QuicAckFrame& ack_frame) {
295 // Go through the packets we have not received an ack for and see if this
296 // incoming_ack shows they've been seen by the peer.
297 QuicTime::Delta ack_delay_time = ack_frame.ack_delay_time;
298 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
299 for (QuicUnackedPacketMap::iterator it = unacked_packets_.begin();
300 it != unacked_packets_.end(); ++it, ++packet_number) {
301 if (packet_number > ack_frame.largest_observed) {
302 // These packets are still in flight.
303 break;
304 }
305
306 if ((ack_frame.missing && ack_frame.packets.Contains(packet_number)) ||
307 (!ack_frame.missing && !ack_frame.packets.Contains(packet_number))) {
308 // Packet is still missing.
309 continue;
310 }
311 // Packet was acked, so remove it from our unacked packet list.
312 DVLOG(1) << ENDPOINT << "Got an ack for packet " << packet_number;
313 // If data is associated with the most recent transmission of this
314 // packet, then inform the caller.
315 if (it->in_flight) {
316 packets_acked_.push_back(std::make_pair(packet_number, it->bytes_sent));
317 } else if (FLAGS_quic_loss_recovery_use_largest_acked &&
318 !it->is_unackable) {
319 largest_newly_acked_ = packet_number;
320 }
321 MarkPacketHandled(packet_number, &(*it), ack_delay_time);
322 }
323 }
324
325 void QuicSentPacketManager::RetransmitUnackedPackets(
326 TransmissionType retransmission_type) {
327 DCHECK(retransmission_type == ALL_UNACKED_RETRANSMISSION ||
328 retransmission_type == ALL_INITIAL_RETRANSMISSION);
329 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
330 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
331 it != unacked_packets_.end(); ++it, ++packet_number) {
332 if (!it->retransmittable_frames.empty() &&
333 (retransmission_type == ALL_UNACKED_RETRANSMISSION ||
334 it->encryption_level == ENCRYPTION_INITIAL)) {
335 MarkForRetransmission(packet_number, retransmission_type);
336 }
337 }
338 }
339
340 void QuicSentPacketManager::NeuterUnencryptedPackets() {
341 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
342 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
343 it != unacked_packets_.end(); ++it, ++packet_number) {
344 if (!it->retransmittable_frames.empty() &&
345 it->encryption_level == ENCRYPTION_NONE) {
346 // Once you're forward secure, no unencrypted packets will be sent, crypto
347 // or otherwise. Unencrypted packets are neutered and abandoned, to ensure
348 // they are not retransmitted or considered lost from a congestion control
349 // perspective.
350 if (delegate_ != nullptr) {
351 delegate_->OnUnencryptedPacketsNeutered(path_id_, packet_number);
352 } else {
353 pending_retransmissions_.erase(packet_number);
354 }
355 unacked_packets_.RemoveFromInFlight(packet_number);
356 unacked_packets_.RemoveRetransmittability(packet_number);
357 }
358 }
359 }
360
361 void QuicSentPacketManager::MarkForRetransmission(
362 QuicPacketNumber packet_number,
363 TransmissionType transmission_type) {
364 const TransmissionInfo& transmission_info =
365 unacked_packets_.GetTransmissionInfo(packet_number);
366 QUIC_BUG_IF(transmission_info.retransmittable_frames.empty());
367 // Both TLP and the new RTO leave the packets in flight and let the loss
368 // detection decide if packets are lost.
369 if (transmission_type != TLP_RETRANSMISSION &&
370 transmission_type != RTO_RETRANSMISSION) {
371 unacked_packets_.RemoveFromInFlight(packet_number);
372 }
373 if (delegate_ != nullptr) {
374 delegate_->OnRetransmissionMarked(path_id_, packet_number,
375 transmission_type);
376 } else {
377 // TODO(ianswett): Currently the RTO can fire while there are pending NACK
378 // retransmissions for the same data, which is not ideal.
379 if (ContainsKey(pending_retransmissions_, packet_number)) {
380 return;
381 }
382
383 pending_retransmissions_[packet_number] = transmission_type;
384 }
385 }
386
387 void QuicSentPacketManager::RecordOneSpuriousRetransmission(
388 const TransmissionInfo& info) {
389 stats_->bytes_spuriously_retransmitted += info.bytes_sent;
390 ++stats_->packets_spuriously_retransmitted;
391 if (debug_delegate_ != nullptr) {
392 debug_delegate_->OnSpuriousPacketRetransmission(info.transmission_type,
393 info.bytes_sent);
394 }
395 }
396
397 void QuicSentPacketManager::RecordSpuriousRetransmissions(
398 const TransmissionInfo& info,
399 QuicPacketNumber acked_packet_number) {
400 QuicPacketNumber retransmission = info.retransmission;
401 while (retransmission != 0) {
402 const TransmissionInfo& retransmit_info =
403 unacked_packets_.GetTransmissionInfo(retransmission);
404 retransmission = retransmit_info.retransmission;
405 RecordOneSpuriousRetransmission(retransmit_info);
406 }
407 // Only inform the loss detection of spurious retransmits it caused.
408 if (unacked_packets_.GetTransmissionInfo(info.retransmission)
409 .transmission_type == LOSS_RETRANSMISSION) {
410 loss_algorithm_->SpuriousRetransmitDetected(
411 unacked_packets_, clock_->Now(), rtt_stats_, info.retransmission);
412 }
413 }
414
415 bool QuicSentPacketManager::HasPendingRetransmissions() const {
416 return !pending_retransmissions_.empty();
417 }
418
419 PendingRetransmission QuicSentPacketManager::NextPendingRetransmission() {
420 QUIC_BUG_IF(pending_retransmissions_.empty())
421 << "Unexpected call to PendingRetransmissions() with empty pending "
422 << "retransmission list. Corrupted memory usage imminent.";
423 QuicPacketNumber packet_number = pending_retransmissions_.begin()->first;
424 TransmissionType transmission_type = pending_retransmissions_.begin()->second;
425 if (unacked_packets_.HasPendingCryptoPackets()) {
426 // Ensure crypto packets are retransmitted before other packets.
427 for (const auto& pair : pending_retransmissions_) {
428 if (HasCryptoHandshake(
429 unacked_packets_.GetTransmissionInfo(pair.first))) {
430 packet_number = pair.first;
431 transmission_type = pair.second;
432 break;
433 }
434 }
435 }
436 DCHECK(unacked_packets_.IsUnacked(packet_number)) << packet_number;
437 const TransmissionInfo& transmission_info =
438 unacked_packets_.GetTransmissionInfo(packet_number);
439 DCHECK(!transmission_info.retransmittable_frames.empty());
440
441 return PendingRetransmission(path_id_, packet_number, transmission_type,
442 transmission_info.retransmittable_frames,
443 transmission_info.has_crypto_handshake,
444 transmission_info.num_padding_bytes,
445 transmission_info.encryption_level,
446 transmission_info.packet_number_length);
447 }
448
449 QuicPacketNumber QuicSentPacketManager::GetNewestRetransmission(
450 QuicPacketNumber packet_number,
451 const TransmissionInfo& transmission_info) const {
452 QuicPacketNumber retransmission = transmission_info.retransmission;
453 while (retransmission != 0) {
454 packet_number = retransmission;
455 retransmission =
456 unacked_packets_.GetTransmissionInfo(retransmission).retransmission;
457 }
458 return packet_number;
459 }
460
461 void QuicSentPacketManager::MarkPacketNotRetransmittable(
462 QuicPacketNumber packet_number,
463 QuicTime::Delta ack_delay_time) {
464 if (!unacked_packets_.IsUnacked(packet_number)) {
465 return;
466 }
467
468 const TransmissionInfo& transmission_info =
469 unacked_packets_.GetTransmissionInfo(packet_number);
470 QuicPacketNumber newest_transmission =
471 GetNewestRetransmission(packet_number, transmission_info);
472 // We do not need to retransmit this packet anymore.
473 if (delegate_ != nullptr) {
474 delegate_->OnPacketMarkedNotRetransmittable(path_id_, newest_transmission,
475 ack_delay_time);
476 } else {
477 pending_retransmissions_.erase(newest_transmission);
478 }
479
480 unacked_packets_.NotifyAndClearListeners(newest_transmission, ack_delay_time);
481 unacked_packets_.RemoveRetransmittability(packet_number);
482 }
483
484 void QuicSentPacketManager::MarkPacketHandled(QuicPacketNumber packet_number,
485 TransmissionInfo* info,
486 QuicTime::Delta ack_delay_time) {
487 QuicPacketNumber newest_transmission =
488 GetNewestRetransmission(packet_number, *info);
489 // Remove the most recent packet, if it is pending retransmission.
490 if (delegate_ != nullptr) {
491 delegate_->OnPacketMarkedHandled(path_id_, newest_transmission,
492 ack_delay_time);
493 } else {
494 pending_retransmissions_.erase(newest_transmission);
495 }
496
497 // The AckListener needs to be notified about the most recent
498 // transmission, since that's the one only one it tracks.
499 if (newest_transmission == packet_number) {
500 unacked_packets_.NotifyAndClearListeners(&info->ack_listeners,
501 ack_delay_time);
502 } else {
503 unacked_packets_.NotifyAndClearListeners(newest_transmission,
504 ack_delay_time);
505 RecordSpuriousRetransmissions(*info, packet_number);
506 // Remove the most recent packet from flight if it's a crypto handshake
507 // packet, since they won't be acked now that one has been processed.
508 // Other crypto handshake packets won't be in flight, only the newest
509 // transmission of a crypto packet is in flight at once.
510 // TODO(ianswett): Instead of handling all crypto packets special,
511 // only handle nullptr encrypted packets in a special way.
512 const TransmissionInfo& newest_transmission_info =
513 unacked_packets_.GetTransmissionInfo(newest_transmission);
514 if (HasCryptoHandshake(newest_transmission_info)) {
515 unacked_packets_.RemoveFromInFlight(newest_transmission);
516 }
517 }
518
519 if (FLAGS_quic_no_mtu_discovery_ack_listener &&
520 network_change_visitor_ != nullptr &&
521 info->bytes_sent > largest_mtu_acked_) {
522 largest_mtu_acked_ = info->bytes_sent;
523 network_change_visitor_->OnPathMtuIncreased(largest_mtu_acked_);
524 }
525 unacked_packets_.RemoveFromInFlight(info);
526 unacked_packets_.RemoveRetransmittability(info);
527 if (FLAGS_quic_loss_recovery_use_largest_acked) {
528 info->is_unackable = true;
529 }
530 }
531
532 bool QuicSentPacketManager::HasUnackedPackets() const {
533 return unacked_packets_.HasUnackedPackets();
534 }
535
536 QuicPacketNumber QuicSentPacketManager::GetLeastUnacked(QuicPathId) const {
537 return unacked_packets_.GetLeastUnacked();
538 }
539
540 bool QuicSentPacketManager::OnPacketSent(
541 SerializedPacket* serialized_packet,
542 QuicPathId /*original_path_id*/,
543 QuicPacketNumber original_packet_number,
544 QuicTime sent_time,
545 TransmissionType transmission_type,
546 HasRetransmittableData has_retransmittable_data) {
547 QuicPacketNumber packet_number = serialized_packet->packet_number;
548 DCHECK_LT(0u, packet_number);
549 DCHECK(!unacked_packets_.IsUnacked(packet_number));
550 QUIC_BUG_IF(serialized_packet->encrypted_length == 0)
551 << "Cannot send empty packets.";
552
553 if (delegate_ == nullptr && original_packet_number != 0) {
554 pending_retransmissions_.erase(original_packet_number);
555 }
556
557 if (pending_timer_transmission_count_ > 0) {
558 --pending_timer_transmission_count_;
559 }
560
561 // TODO(ianswett): Remove sent_time, because it's unused.
562 const bool in_flight = send_algorithm_->OnPacketSent(
563 sent_time, unacked_packets_.bytes_in_flight(), packet_number,
564 serialized_packet->encrypted_length, has_retransmittable_data);
565
566 unacked_packets_.AddSentPacket(serialized_packet, original_packet_number,
567 transmission_type, sent_time, in_flight);
568 // Reset the retransmission timer anytime a pending packet is sent.
569 return in_flight;
570 }
571
572 void QuicSentPacketManager::OnRetransmissionTimeout() {
573 DCHECK(unacked_packets_.HasInFlightPackets());
574 DCHECK_EQ(0u, pending_timer_transmission_count_);
575 // Handshake retransmission, timer based loss detection, TLP, and RTO are
576 // implemented with a single alarm. The handshake alarm is set when the
577 // handshake has not completed, the loss alarm is set when the loss detection
578 // algorithm says to, and the TLP and RTO alarms are set after that.
579 // The TLP alarm is always set to run for under an RTO.
580 switch (GetRetransmissionMode()) {
581 case HANDSHAKE_MODE:
582 ++stats_->crypto_retransmit_count;
583 RetransmitCryptoPackets();
584 return;
585 case LOSS_MODE: {
586 ++stats_->loss_timeout_count;
587 QuicByteCount bytes_in_flight = unacked_packets_.bytes_in_flight();
588 InvokeLossDetection(clock_->Now());
589 MaybeInvokeCongestionEvent(false, bytes_in_flight);
590 return;
591 }
592 case TLP_MODE:
593 // If no tail loss probe can be sent, because there are no retransmittable
594 // packets, execute a conventional RTO to abandon old packets.
595 ++stats_->tlp_count;
596 ++consecutive_tlp_count_;
597 pending_timer_transmission_count_ = 1;
598 // TLPs prefer sending new data instead of retransmitting data, so
599 // give the connection a chance to write before completing the TLP.
600 return;
601 case RTO_MODE:
602 ++stats_->rto_count;
603 RetransmitRtoPackets();
604 if (network_change_visitor_ != nullptr &&
605 consecutive_rto_count_ == kMinTimeoutsBeforePathDegrading) {
606 network_change_visitor_->OnPathDegrading();
607 }
608 return;
609 }
610 }
611
612 void QuicSentPacketManager::RetransmitCryptoPackets() {
613 DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode());
614 ++consecutive_crypto_retransmission_count_;
615 bool packet_retransmitted = false;
616 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
617 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
618 it != unacked_packets_.end(); ++it, ++packet_number) {
619 // Only retransmit frames which are in flight, and therefore have been sent.
620 if (!it->in_flight || it->retransmittable_frames.empty() ||
621 !it->has_crypto_handshake) {
622 continue;
623 }
624 packet_retransmitted = true;
625 MarkForRetransmission(packet_number, HANDSHAKE_RETRANSMISSION);
626 ++pending_timer_transmission_count_;
627 }
628 DCHECK(packet_retransmitted) << "No crypto packets found to retransmit.";
629 }
630
631 bool QuicSentPacketManager::MaybeRetransmitTailLossProbe() {
632 if (pending_timer_transmission_count_ == 0) {
633 return false;
634 }
635 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
636 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
637 it != unacked_packets_.end(); ++it, ++packet_number) {
638 // Only retransmit frames which are in flight, and therefore have been sent.
639 if (!it->in_flight || it->retransmittable_frames.empty()) {
640 continue;
641 }
642 if (!handshake_confirmed_) {
643 DCHECK(!it->has_crypto_handshake);
644 }
645 MarkForRetransmission(packet_number, TLP_RETRANSMISSION);
646 return true;
647 }
648 DLOG(ERROR)
649 << "No retransmittable packets, so RetransmitOldestPacket failed.";
650 return false;
651 }
652
653 void QuicSentPacketManager::RetransmitRtoPackets() {
654 QUIC_BUG_IF(pending_timer_transmission_count_ > 0)
655 << "Retransmissions already queued:" << pending_timer_transmission_count_;
656 // Mark two packets for retransmission.
657 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
658 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
659 it != unacked_packets_.end(); ++it, ++packet_number) {
660 if (!it->retransmittable_frames.empty() &&
661 pending_timer_transmission_count_ < kMaxRetransmissionsOnTimeout) {
662 MarkForRetransmission(packet_number, RTO_RETRANSMISSION);
663 ++pending_timer_transmission_count_;
664 }
665 // Abandon non-retransmittable data that's in flight to ensure it doesn't
666 // fill up the congestion window.
667 const bool has_retransmissions = it->retransmission != 0;
668 if (it->retransmittable_frames.empty() && it->in_flight &&
669 !has_retransmissions) {
670 // Log only for non-retransmittable data.
671 // Retransmittable data is marked as lost during loss detection, and will
672 // be logged later.
673 unacked_packets_.RemoveFromInFlight(packet_number);
674 if (debug_delegate_ != nullptr) {
675 debug_delegate_->OnPacketLoss(packet_number, RTO_RETRANSMISSION,
676 clock_->Now());
677 }
678 }
679 }
680 if (pending_timer_transmission_count_ > 0) {
681 if (consecutive_rto_count_ == 0) {
682 first_rto_transmission_ = unacked_packets_.largest_sent_packet() + 1;
683 }
684 ++consecutive_rto_count_;
685 }
686 }
687
688 QuicSentPacketManager::RetransmissionTimeoutMode
689 QuicSentPacketManager::GetRetransmissionMode() const {
690 DCHECK(unacked_packets_.HasInFlightPackets());
691 if (!handshake_confirmed_ && unacked_packets_.HasPendingCryptoPackets()) {
692 return HANDSHAKE_MODE;
693 }
694 if (loss_algorithm_->GetLossTimeout() != QuicTime::Zero()) {
695 return LOSS_MODE;
696 }
697 if (consecutive_tlp_count_ < max_tail_loss_probes_) {
698 if (unacked_packets_.HasUnackedRetransmittableFrames()) {
699 return TLP_MODE;
700 }
701 }
702 return RTO_MODE;
703 }
704
705 void QuicSentPacketManager::InvokeLossDetection(QuicTime time) {
706 if (FLAGS_quic_loss_recovery_use_largest_acked && !packets_acked_.empty()) {
707 DCHECK_LE(packets_acked_.front().first, packets_acked_.back().first);
708 largest_newly_acked_ = packets_acked_.back().first;
709 }
710 loss_algorithm_->DetectLosses(unacked_packets_, time, rtt_stats_,
711 largest_newly_acked_, &packets_lost_);
712 for (const pair<QuicPacketNumber, QuicByteCount>& pair : packets_lost_) {
713 ++stats_->packets_lost;
714 if (debug_delegate_ != nullptr) {
715 debug_delegate_->OnPacketLoss(pair.first, LOSS_RETRANSMISSION, time);
716 }
717
718 // TODO(ianswett): This could be optimized.
719 if (unacked_packets_.HasRetransmittableFrames(pair.first)) {
720 MarkForRetransmission(pair.first, LOSS_RETRANSMISSION);
721 } else {
722 // Since we will not retransmit this, we need to remove it from
723 // unacked_packets_. This is either the current transmission of
724 // a packet whose previous transmission has been acked or a packet that
725 // has been TLP retransmitted.
726 unacked_packets_.RemoveFromInFlight(pair.first);
727 }
728 }
729 }
730
731 bool QuicSentPacketManager::MaybeUpdateRTT(const QuicAckFrame& ack_frame,
732 QuicTime ack_receive_time) {
733 // We rely on ack_delay_time to compute an RTT estimate, so we
734 // only update rtt when the largest observed gets acked.
735 // NOTE: If ack is a truncated ack, then the largest observed is in fact
736 // unacked, and may cause an RTT sample to be taken.
737 if (!unacked_packets_.IsUnacked(ack_frame.largest_observed)) {
738 return false;
739 }
740 // We calculate the RTT based on the highest ACKed packet number, the lower
741 // packet numbers will include the ACK aggregation delay.
742 const TransmissionInfo& transmission_info =
743 unacked_packets_.GetTransmissionInfo(ack_frame.largest_observed);
744 // Ensure the packet has a valid sent time.
745 if (transmission_info.sent_time == QuicTime::Zero()) {
746 QUIC_BUG << "Acked packet has zero sent time, largest_observed:"
747 << ack_frame.largest_observed;
748 return false;
749 }
750
751 QuicTime::Delta send_delta = ack_receive_time - transmission_info.sent_time;
752 const int kMaxSendDeltaSeconds = 30;
753 if (FLAGS_quic_socket_walltimestamps &&
754 send_delta.ToSeconds() > kMaxSendDeltaSeconds) {
755 // send_delta can be very high if local clock is changed mid-connection.
756 LOG(WARNING) << "Excessive send delta: " << send_delta.ToSeconds()
757 << ", setting to: " << kMaxSendDeltaSeconds
758 << " largest_observed:" << ack_frame.largest_observed
759 << " ack_receive_time:" << ack_receive_time.ToDebuggingValue()
760 << " sent_time:"
761 << transmission_info.sent_time.ToDebuggingValue();
762 return false;
763 }
764 rtt_stats_.UpdateRtt(send_delta, ack_frame.ack_delay_time, ack_receive_time);
765
766 return true;
767 }
768
769 QuicTime::Delta QuicSentPacketManager::TimeUntilSend(
770 QuicTime now,
771 HasRetransmittableData retransmittable,
772 QuicPathId* path_id) {
773 QuicTime::Delta delay = QuicTime::Delta::Infinite();
774 // The TLP logic is entirely contained within QuicSentPacketManager, so the
775 // send algorithm does not need to be consulted.
776 if (pending_timer_transmission_count_ > 0) {
777 delay = QuicTime::Delta::Zero();
778 } else {
779 delay =
780 send_algorithm_->TimeUntilSend(now, unacked_packets_.bytes_in_flight());
781 }
782 if (!delay.IsInfinite()) {
783 *path_id = path_id_;
784 }
785 return delay;
786 }
787
788 const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
789 // Don't set the timer if there are no packets in flight or we've already
790 // queued a tlp transmission and it hasn't been sent yet.
791 if (!unacked_packets_.HasInFlightPackets() ||
792 pending_timer_transmission_count_ > 0) {
793 return QuicTime::Zero();
794 }
795 switch (GetRetransmissionMode()) {
796 case HANDSHAKE_MODE:
797 return clock_->ApproximateNow() + GetCryptoRetransmissionDelay();
798 case LOSS_MODE:
799 return loss_algorithm_->GetLossTimeout();
800 case TLP_MODE: {
801 // TODO(ianswett): When CWND is available, it would be preferable to
802 // set the timer based on the earliest retransmittable packet.
803 // Base the updated timer on the send time of the last packet.
804 const QuicTime sent_time = unacked_packets_.GetLastPacketSentTime();
805 const QuicTime tlp_time = sent_time + GetTailLossProbeDelay();
806 // Ensure the TLP timer never gets set to a time in the past.
807 return std::max(clock_->ApproximateNow(), tlp_time);
808 }
809 case RTO_MODE: {
810 // The RTO is based on the first outstanding packet.
811 const QuicTime sent_time = unacked_packets_.GetLastPacketSentTime();
812 QuicTime rto_time = sent_time + GetRetransmissionDelay();
813 // Wait for TLP packets to be acked before an RTO fires.
814 QuicTime tlp_time =
815 unacked_packets_.GetLastPacketSentTime() + GetTailLossProbeDelay();
816 return std::max(tlp_time, rto_time);
817 }
818 }
819 DCHECK(false);
820 return QuicTime::Zero();
821 }
822
823 const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay()
824 const {
825 // This is equivalent to the TailLossProbeDelay, but slightly more aggressive
826 // because crypto handshake messages don't incur a delayed ack time.
827 QuicTime::Delta srtt = rtt_stats_.smoothed_rtt();
828 if (srtt.IsZero()) {
829 srtt = QuicTime::Delta::FromMicroseconds(rtt_stats_.initial_rtt_us());
830 }
831 int64_t delay_ms = max(kMinHandshakeTimeoutMs,
832 static_cast<int64_t>(1.5 * srtt.ToMilliseconds()));
833 return QuicTime::Delta::FromMilliseconds(
834 delay_ms << consecutive_crypto_retransmission_count_);
835 }
836
837 const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const {
838 QuicTime::Delta srtt = rtt_stats_.smoothed_rtt();
839 if (srtt.IsZero()) {
840 srtt = QuicTime::Delta::FromMicroseconds(rtt_stats_.initial_rtt_us());
841 }
842 if (enable_half_rtt_tail_loss_probe_ && consecutive_tlp_count_ == 0u) {
843 return QuicTime::Delta::FromMilliseconds(
844 max(kMinTailLossProbeTimeoutMs,
845 static_cast<int64_t>(0.5 * srtt.ToMilliseconds())));
846 }
847 if (!unacked_packets_.HasMultipleInFlightPackets()) {
848 return std::max(2 * srtt, 1.5 * srtt + QuicTime::Delta::FromMilliseconds(
849 kMinRetransmissionTimeMs / 2));
850 }
851 return QuicTime::Delta::FromMilliseconds(
852 max(kMinTailLossProbeTimeoutMs,
853 static_cast<int64_t>(2 * srtt.ToMilliseconds())));
854 }
855
856 const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const {
857 QuicTime::Delta retransmission_delay = send_algorithm_->RetransmissionDelay();
858 if (retransmission_delay.IsZero()) {
859 // We are in the initial state, use default timeout values.
860 retransmission_delay =
861 QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs);
862 } else if (retransmission_delay.ToMilliseconds() < kMinRetransmissionTimeMs) {
863 retransmission_delay =
864 QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs);
865 }
866
867 // Calculate exponential back off.
868 retransmission_delay =
869 retransmission_delay *
870 (1 << min<size_t>(consecutive_rto_count_, kMaxRetransmissions));
871
872 if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) {
873 return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs);
874 }
875 return retransmission_delay;
876 }
877
878 const RttStats* QuicSentPacketManager::GetRttStats() const {
879 return &rtt_stats_;
880 }
881
882 QuicBandwidth QuicSentPacketManager::BandwidthEstimate() const {
883 // TODO(ianswett): Remove BandwidthEstimate from SendAlgorithmInterface
884 // and implement the logic here.
885 return send_algorithm_->BandwidthEstimate();
886 }
887
888 const QuicSustainedBandwidthRecorder*
889 QuicSentPacketManager::SustainedBandwidthRecorder() const {
890 return &sustained_bandwidth_recorder_;
891 }
892
893 QuicPacketCount QuicSentPacketManager::EstimateMaxPacketsInFlight(
894 QuicByteCount max_packet_length) const {
895 return send_algorithm_->GetCongestionWindow() / max_packet_length;
896 }
897
898 QuicPacketCount QuicSentPacketManager::GetCongestionWindowInTcpMss() const {
899 return send_algorithm_->GetCongestionWindow() / kDefaultTCPMSS;
900 }
901
902 QuicByteCount QuicSentPacketManager::GetCongestionWindowInBytes() const {
903 return send_algorithm_->GetCongestionWindow();
904 }
905
906 QuicPacketCount QuicSentPacketManager::GetSlowStartThresholdInTcpMss() const {
907 return send_algorithm_->GetSlowStartThreshold() / kDefaultTCPMSS;
908 }
909
910 void QuicSentPacketManager::CancelRetransmissionsForStream(
911 QuicStreamId stream_id) {
912 unacked_packets_.CancelRetransmissionsForStream(stream_id);
913 if (delegate_ != nullptr) {
914 return;
915 }
916 PendingRetransmissionMap::iterator it = pending_retransmissions_.begin();
917 while (it != pending_retransmissions_.end()) {
918 if (unacked_packets_.HasRetransmittableFrames(it->first)) {
919 ++it;
920 continue;
921 }
922 it = pending_retransmissions_.erase(it);
923 }
924 }
925
926 void QuicSentPacketManager::EnablePacing() {
927 // TODO(ianswett): Replace with a method which wraps the send algorithm in a
928 // pacer every time a new algorithm is set.
929 if (using_pacing_) {
930 return;
931 }
932
933 // Set up a pacing sender with a 1 millisecond alarm granularity, the same as
934 // the default granularity of the Linux kernel's FQ qdisc.
935 using_pacing_ = true;
936 send_algorithm_.reset(new PacingSender(send_algorithm_.release(),
937 QuicTime::Delta::FromMilliseconds(1),
938 kInitialUnpacedBurst));
939 }
940
941 void QuicSentPacketManager::OnConnectionMigration(QuicPathId,
942 PeerAddressChangeType type) {
943 if (type == PORT_CHANGE || type == IPV4_SUBNET_CHANGE) {
944 // Rtt and cwnd do not need to be reset when the peer address change is
945 // considered to be caused by NATs.
946 return;
947 }
948 consecutive_rto_count_ = 0;
949 consecutive_tlp_count_ = 0;
950 rtt_stats_.OnConnectionMigration();
951 send_algorithm_->OnConnectionMigration();
952 }
953
954 bool QuicSentPacketManager::IsHandshakeConfirmed() const {
955 return handshake_confirmed_;
956 }
957
958 void QuicSentPacketManager::SetDebugDelegate(DebugDelegate* debug_delegate) {
959 debug_delegate_ = debug_delegate;
960 }
961
962 QuicPacketNumber QuicSentPacketManager::GetLargestObserved(QuicPathId) const {
963 return unacked_packets_.largest_observed();
964 }
965
966 QuicPacketNumber QuicSentPacketManager::GetLargestSentPacket(QuicPathId) const {
967 return unacked_packets_.largest_sent_packet();
968 }
969
970 QuicPacketNumber QuicSentPacketManager::GetLeastPacketAwaitedByPeer(
971 QuicPathId) const {
972 return least_packet_awaited_by_peer_;
973 }
974
975 void QuicSentPacketManager::SetNetworkChangeVisitor(
976 NetworkChangeVisitor* visitor) {
977 DCHECK(!network_change_visitor_);
978 DCHECK(visitor);
979 network_change_visitor_ = visitor;
980 }
981
982 bool QuicSentPacketManager::InSlowStart() const {
983 return send_algorithm_->InSlowStart();
984 }
985
986 size_t QuicSentPacketManager::GetConsecutiveRtoCount() const {
987 return consecutive_rto_count_;
988 }
989
990 size_t QuicSentPacketManager::GetConsecutiveTlpCount() const {
991 return consecutive_tlp_count_;
992 }
993
994 TransmissionInfo* QuicSentPacketManager::GetMutableTransmissionInfo(
995 QuicPacketNumber packet_number) {
996 return unacked_packets_.GetMutableTransmissionInfo(packet_number);
997 }
998
999 void QuicSentPacketManager::RemoveObsoletePackets() {
1000 unacked_packets_.RemoveObsoletePackets();
1001 }
1002
1003 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_sent_packet_manager.h ('k') | net/quic/quic_sent_packet_manager_interface.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698