| OLD | NEW |
| (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 | |
| OLD | NEW |