| 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/congestion_control/pacing_sender.h" | |
| 12 #include "net/quic/crypto/crypto_protocol.h" | |
| 13 #include "net/quic/quic_ack_notifier_manager.h" | |
| 14 #include "net/quic/quic_connection_stats.h" | |
| 15 #include "net/quic/quic_flags.h" | |
| 16 #include "net/quic/quic_utils_chromium.h" | |
| 17 | |
| 18 using std::max; | |
| 19 using std::min; | |
| 20 | |
| 21 namespace net { | |
| 22 | |
| 23 // The length of the recent min rtt window in seconds. Windowing is disabled for | |
| 24 // values less than or equal to 0. | |
| 25 int32 FLAGS_quic_recent_min_rtt_window_s = 60; | |
| 26 | |
| 27 namespace { | |
| 28 static const int64 kDefaultRetransmissionTimeMs = 500; | |
| 29 // TCP RFC calls for 1 second RTO however Linux differs from this default and | |
| 30 // define the minimum RTO to 200ms, we will use the same until we have data to | |
| 31 // support a higher or lower value. | |
| 32 static const int64 kMinRetransmissionTimeMs = 200; | |
| 33 static const int64 kMaxRetransmissionTimeMs = 60000; | |
| 34 // Maximum number of exponential backoffs used for RTO timeouts. | |
| 35 static const size_t kMaxRetransmissions = 10; | |
| 36 // Maximum number of packets retransmitted upon an RTO. | |
| 37 static const size_t kMaxRetransmissionsOnTimeout = 2; | |
| 38 | |
| 39 // Ensure the handshake timer isnt't faster than 10ms. | |
| 40 // This limits the tenth retransmitted packet to 10s after the initial CHLO. | |
| 41 static const int64 kMinHandshakeTimeoutMs = 10; | |
| 42 | |
| 43 // Sends up to two tail loss probes before firing an RTO, | |
| 44 // per draft RFC draft-dukkipati-tcpm-tcp-loss-probe. | |
| 45 static const size_t kDefaultMaxTailLossProbes = 2; | |
| 46 static const int64 kMinTailLossProbeTimeoutMs = 10; | |
| 47 | |
| 48 // Number of samples before we force a new recent min rtt to be captured. | |
| 49 static const size_t kNumMinRttSamplesAfterQuiescence = 2; | |
| 50 | |
| 51 // Number of unpaced packets to send after quiescence. | |
| 52 static const size_t kInitialUnpacedBurst = 10; | |
| 53 | |
| 54 // Fraction of the receive buffer that can be used for encrypted bytes. | |
| 55 // Allows a 5% overhead for IP and UDP framing, as well as ack only packets. | |
| 56 static const float kUsableRecieveBufferFraction = 0.95f; | |
| 57 | |
| 58 bool HasCryptoHandshake(const TransmissionInfo& transmission_info) { | |
| 59 if (transmission_info.retransmittable_frames == nullptr) { | |
| 60 return false; | |
| 61 } | |
| 62 return transmission_info.retransmittable_frames->HasCryptoHandshake() == | |
| 63 IS_HANDSHAKE; | |
| 64 } | |
| 65 | |
| 66 } // namespace | |
| 67 | |
| 68 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") | |
| 69 | |
| 70 QuicSentPacketManager::QuicSentPacketManager( | |
| 71 bool is_server, | |
| 72 const QuicClock* clock, | |
| 73 QuicConnectionStats* stats, | |
| 74 CongestionControlType congestion_control_type, | |
| 75 LossDetectionType loss_type, | |
| 76 bool is_secure) | |
| 77 : unacked_packets_(), | |
| 78 is_server_(is_server), | |
| 79 clock_(clock), | |
| 80 stats_(stats), | |
| 81 debug_delegate_(nullptr), | |
| 82 network_change_visitor_(nullptr), | |
| 83 initial_congestion_window_(is_secure ? kInitialCongestionWindowSecure | |
| 84 : kInitialCongestionWindowInsecure), | |
| 85 send_algorithm_( | |
| 86 SendAlgorithmInterface::Create(clock, | |
| 87 &rtt_stats_, | |
| 88 congestion_control_type, | |
| 89 stats, | |
| 90 initial_congestion_window_)), | |
| 91 loss_algorithm_(LossDetectionInterface::Create(loss_type)), | |
| 92 n_connection_simulation_(false), | |
| 93 receive_buffer_bytes_(kDefaultSocketReceiveBuffer), | |
| 94 least_packet_awaited_by_peer_(1), | |
| 95 first_rto_transmission_(0), | |
| 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 using_pacing_(false), | |
| 102 use_new_rto_(false), | |
| 103 handshake_confirmed_(false) { | |
| 104 } | |
| 105 | |
| 106 QuicSentPacketManager::~QuicSentPacketManager() { | |
| 107 } | |
| 108 | |
| 109 void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { | |
| 110 if (config.HasReceivedInitialRoundTripTimeUs() && | |
| 111 config.ReceivedInitialRoundTripTimeUs() > 0) { | |
| 112 rtt_stats_.set_initial_rtt_us( | |
| 113 max(kMinInitialRoundTripTimeUs, | |
| 114 min(kMaxInitialRoundTripTimeUs, | |
| 115 config.ReceivedInitialRoundTripTimeUs()))); | |
| 116 } else if (config.HasInitialRoundTripTimeUsToSend() && | |
| 117 config.GetInitialRoundTripTimeUsToSend() > 0) { | |
| 118 rtt_stats_.set_initial_rtt_us( | |
| 119 max(kMinInitialRoundTripTimeUs, | |
| 120 min(kMaxInitialRoundTripTimeUs, | |
| 121 config.GetInitialRoundTripTimeUsToSend()))); | |
| 122 } | |
| 123 // Initial RTT may have changed. | |
| 124 if (network_change_visitor_ != nullptr) { | |
| 125 network_change_visitor_->OnRttChange(); | |
| 126 } | |
| 127 // TODO(ianswett): BBR is currently a server only feature. | |
| 128 if (FLAGS_quic_allow_bbr && | |
| 129 config.HasReceivedConnectionOptions() && | |
| 130 ContainsQuicTag(config.ReceivedConnectionOptions(), kTBBR)) { | |
| 131 if (FLAGS_quic_recent_min_rtt_window_s > 0) { | |
| 132 rtt_stats_.set_recent_min_rtt_window( | |
| 133 QuicTime::Delta::FromSeconds(FLAGS_quic_recent_min_rtt_window_s)); | |
| 134 } | |
| 135 send_algorithm_.reset(SendAlgorithmInterface::Create( | |
| 136 clock_, &rtt_stats_, kBBR, stats_, initial_congestion_window_)); | |
| 137 } | |
| 138 if (config.HasReceivedConnectionOptions() && | |
| 139 ContainsQuicTag(config.ReceivedConnectionOptions(), kRENO)) { | |
| 140 send_algorithm_.reset(SendAlgorithmInterface::Create( | |
| 141 clock_, &rtt_stats_, kReno, stats_, initial_congestion_window_)); | |
| 142 } | |
| 143 if (HasClientSentConnectionOption(config, kPACE) || | |
| 144 FLAGS_quic_enable_pacing || | |
| 145 (FLAGS_quic_allow_bbr && HasClientSentConnectionOption(config, kTBBR))) { | |
| 146 EnablePacing(); | |
| 147 } | |
| 148 if (HasClientSentConnectionOption(config, k1CON)) { | |
| 149 send_algorithm_->SetNumEmulatedConnections(1); | |
| 150 } | |
| 151 if (HasClientSentConnectionOption(config, kNCON)) { | |
| 152 n_connection_simulation_ = true; | |
| 153 } | |
| 154 if (HasClientSentConnectionOption(config, kNTLP)) { | |
| 155 max_tail_loss_probes_ = 0; | |
| 156 } | |
| 157 if (HasClientSentConnectionOption(config, kNRTO)) { | |
| 158 use_new_rto_ = true; | |
| 159 } | |
| 160 if (config.HasReceivedConnectionOptions() && | |
| 161 ContainsQuicTag(config.ReceivedConnectionOptions(), kTIME)) { | |
| 162 loss_algorithm_.reset(LossDetectionInterface::Create(kTime)); | |
| 163 } | |
| 164 if (config.HasReceivedSocketReceiveBuffer()) { | |
| 165 receive_buffer_bytes_ = | |
| 166 max(kMinSocketReceiveBuffer, | |
| 167 static_cast<QuicByteCount>(config.ReceivedSocketReceiveBuffer())); | |
| 168 } | |
| 169 send_algorithm_->SetFromConfig(config, is_server_, using_pacing_); | |
| 170 | |
| 171 if (network_change_visitor_ != nullptr) { | |
| 172 network_change_visitor_->OnCongestionWindowChange(); | |
| 173 } | |
| 174 } | |
| 175 | |
| 176 bool QuicSentPacketManager::ResumeConnectionState( | |
| 177 const CachedNetworkParameters& cached_network_params) { | |
| 178 if (cached_network_params.has_min_rtt_ms()) { | |
| 179 uint32 initial_rtt_us = | |
| 180 kNumMicrosPerMilli * cached_network_params.min_rtt_ms(); | |
| 181 rtt_stats_.set_initial_rtt_us( | |
| 182 max(kMinInitialRoundTripTimeUs, | |
| 183 min(kMaxInitialRoundTripTimeUs, initial_rtt_us))); | |
| 184 } | |
| 185 return send_algorithm_->ResumeConnectionState(cached_network_params); | |
| 186 } | |
| 187 | |
| 188 void QuicSentPacketManager::SetNumOpenStreams(size_t num_streams) { | |
| 189 if (n_connection_simulation_) { | |
| 190 // Ensure the number of connections is between 1 and 5. | |
| 191 send_algorithm_->SetNumEmulatedConnections( | |
| 192 min<size_t>(5, max<size_t>(1, num_streams))); | |
| 193 } | |
| 194 } | |
| 195 | |
| 196 bool QuicSentPacketManager::HasClientSentConnectionOption( | |
| 197 const QuicConfig& config, QuicTag tag) const { | |
| 198 if (is_server_) { | |
| 199 if (config.HasReceivedConnectionOptions() && | |
| 200 ContainsQuicTag(config.ReceivedConnectionOptions(), tag)) { | |
| 201 return true; | |
| 202 } | |
| 203 } else if (config.HasSendConnectionOptions() && | |
| 204 ContainsQuicTag(config.SendConnectionOptions(), tag)) { | |
| 205 return true; | |
| 206 } | |
| 207 return false; | |
| 208 } | |
| 209 | |
| 210 void QuicSentPacketManager::OnIncomingAck(const QuicAckFrame& ack_frame, | |
| 211 QuicTime ack_receive_time) { | |
| 212 QuicByteCount bytes_in_flight = unacked_packets_.bytes_in_flight(); | |
| 213 | |
| 214 UpdatePacketInformationReceivedByPeer(ack_frame); | |
| 215 bool rtt_updated = MaybeUpdateRTT(ack_frame, ack_receive_time); | |
| 216 DCHECK_GE(ack_frame.largest_observed, unacked_packets_.largest_observed()); | |
| 217 unacked_packets_.IncreaseLargestObserved(ack_frame.largest_observed); | |
| 218 | |
| 219 HandleAckForSentPackets(ack_frame); | |
| 220 InvokeLossDetection(ack_receive_time); | |
| 221 // Ignore losses in RTO mode. | |
| 222 if (FLAGS_quic_use_new_rto && consecutive_rto_count_ > 0 && !use_new_rto_) { | |
| 223 packets_lost_.clear(); | |
| 224 } | |
| 225 MaybeInvokeCongestionEvent(rtt_updated, bytes_in_flight); | |
| 226 unacked_packets_.RemoveObsoletePackets(); | |
| 227 | |
| 228 sustained_bandwidth_recorder_.RecordEstimate( | |
| 229 send_algorithm_->InRecovery(), | |
| 230 send_algorithm_->InSlowStart(), | |
| 231 send_algorithm_->BandwidthEstimate(), | |
| 232 ack_receive_time, | |
| 233 clock_->WallNow(), | |
| 234 rtt_stats_.smoothed_rtt()); | |
| 235 | |
| 236 // If we have received a truncated ack, then we need to clear out some | |
| 237 // previous transmissions to allow the peer to actually ACK new packets. | |
| 238 if (ack_frame.is_truncated) { | |
| 239 unacked_packets_.ClearAllPreviousRetransmissions(); | |
| 240 } | |
| 241 | |
| 242 // Anytime we are making forward progress and have a new RTT estimate, reset | |
| 243 // the backoff counters. | |
| 244 if (rtt_updated) { | |
| 245 if (FLAGS_quic_use_new_rto && consecutive_rto_count_ > 0) { | |
| 246 // If the ack acknowledges data sent prior to the RTO, | |
| 247 // the RTO was spurious. | |
| 248 if (ack_frame.largest_observed < first_rto_transmission_) { | |
| 249 // Replace SRTT with latest_rtt and increase the variance to prevent | |
| 250 // a spurious RTO from happening again. | |
| 251 rtt_stats_.ExpireSmoothedMetrics(); | |
| 252 } else { | |
| 253 if (!use_new_rto_) { | |
| 254 send_algorithm_->OnRetransmissionTimeout(true); | |
| 255 } | |
| 256 } | |
| 257 } | |
| 258 // Reset all retransmit counters any time a new packet is acked. | |
| 259 consecutive_rto_count_ = 0; | |
| 260 consecutive_tlp_count_ = 0; | |
| 261 consecutive_crypto_retransmission_count_ = 0; | |
| 262 } | |
| 263 | |
| 264 if (debug_delegate_ != nullptr) { | |
| 265 debug_delegate_->OnIncomingAck(ack_frame, ack_receive_time, | |
| 266 unacked_packets_.largest_observed(), | |
| 267 rtt_updated, GetLeastUnacked()); | |
| 268 } | |
| 269 } | |
| 270 | |
| 271 void QuicSentPacketManager::UpdatePacketInformationReceivedByPeer( | |
| 272 const QuicAckFrame& ack_frame) { | |
| 273 if (ack_frame.missing_packets.empty()) { | |
| 274 least_packet_awaited_by_peer_ = ack_frame.largest_observed + 1; | |
| 275 } else { | |
| 276 least_packet_awaited_by_peer_ = *(ack_frame.missing_packets.begin()); | |
| 277 } | |
| 278 } | |
| 279 | |
| 280 void QuicSentPacketManager::MaybeInvokeCongestionEvent( | |
| 281 bool rtt_updated, QuicByteCount bytes_in_flight) { | |
| 282 if (!rtt_updated && packets_acked_.empty() && packets_lost_.empty()) { | |
| 283 return; | |
| 284 } | |
| 285 send_algorithm_->OnCongestionEvent(rtt_updated, bytes_in_flight, | |
| 286 packets_acked_, packets_lost_); | |
| 287 packets_acked_.clear(); | |
| 288 packets_lost_.clear(); | |
| 289 if (network_change_visitor_ != nullptr) { | |
| 290 network_change_visitor_->OnCongestionWindowChange(); | |
| 291 } | |
| 292 } | |
| 293 | |
| 294 void QuicSentPacketManager::HandleAckForSentPackets( | |
| 295 const QuicAckFrame& ack_frame) { | |
| 296 // Go through the packets we have not received an ack for and see if this | |
| 297 // incoming_ack shows they've been seen by the peer. | |
| 298 QuicTime::Delta delta_largest_observed = | |
| 299 ack_frame.delta_time_largest_observed; | |
| 300 QuicPacketSequenceNumber sequence_number = unacked_packets_.GetLeastUnacked(); | |
| 301 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | |
| 302 it != unacked_packets_.end(); ++it, ++sequence_number) { | |
| 303 if (sequence_number > ack_frame.largest_observed) { | |
| 304 // These packets are still in flight. | |
| 305 break; | |
| 306 } | |
| 307 | |
| 308 if (ContainsKey(ack_frame.missing_packets, sequence_number)) { | |
| 309 // Don't continue to increase the nack count for packets not in flight. | |
| 310 if (!it->in_flight) { | |
| 311 continue; | |
| 312 } | |
| 313 // Consider it multiple nacks when there is a gap between the missing | |
| 314 // packet and the largest observed, since the purpose of a nack | |
| 315 // threshold is to tolerate re-ordering. This handles both StretchAcks | |
| 316 // and Forward Acks. | |
| 317 // The nack count only increases when the largest observed increases. | |
| 318 QuicPacketCount min_nacks = ack_frame.largest_observed - sequence_number; | |
| 319 // Truncated acks can nack the largest observed, so use a min of 1. | |
| 320 if (min_nacks == 0) { | |
| 321 min_nacks = 1; | |
| 322 } | |
| 323 unacked_packets_.NackPacket(sequence_number, min_nacks); | |
| 324 continue; | |
| 325 } | |
| 326 // Packet was acked, so remove it from our unacked packet list. | |
| 327 DVLOG(1) << ENDPOINT << "Got an ack for packet " << sequence_number; | |
| 328 // If data is associated with the most recent transmission of this | |
| 329 // packet, then inform the caller. | |
| 330 if (it->in_flight) { | |
| 331 packets_acked_.push_back(std::make_pair(sequence_number, *it)); | |
| 332 } | |
| 333 MarkPacketHandled(sequence_number, *it, delta_largest_observed); | |
| 334 } | |
| 335 | |
| 336 // Discard any retransmittable frames associated with revived packets. | |
| 337 for (SequenceNumberSet::const_iterator revived_it = | |
| 338 ack_frame.revived_packets.begin(); | |
| 339 revived_it != ack_frame.revived_packets.end(); ++revived_it) { | |
| 340 MarkPacketRevived(*revived_it, delta_largest_observed); | |
| 341 } | |
| 342 } | |
| 343 | |
| 344 bool QuicSentPacketManager::HasRetransmittableFrames( | |
| 345 QuicPacketSequenceNumber sequence_number) const { | |
| 346 return unacked_packets_.HasRetransmittableFrames(sequence_number); | |
| 347 } | |
| 348 | |
| 349 void QuicSentPacketManager::RetransmitUnackedPackets( | |
| 350 TransmissionType retransmission_type) { | |
| 351 DCHECK(retransmission_type == ALL_UNACKED_RETRANSMISSION || | |
| 352 retransmission_type == ALL_INITIAL_RETRANSMISSION); | |
| 353 QuicPacketSequenceNumber sequence_number = unacked_packets_.GetLeastUnacked(); | |
| 354 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | |
| 355 it != unacked_packets_.end(); ++it, ++sequence_number) { | |
| 356 const RetransmittableFrames* frames = it->retransmittable_frames; | |
| 357 if (frames != nullptr && | |
| 358 (retransmission_type == ALL_UNACKED_RETRANSMISSION || | |
| 359 frames->encryption_level() == ENCRYPTION_INITIAL)) { | |
| 360 MarkForRetransmission(sequence_number, retransmission_type); | |
| 361 } else if (it->is_fec_packet) { | |
| 362 // Remove FEC packets from the packet map, since we can't retransmit them. | |
| 363 unacked_packets_.RemoveFromInFlight(sequence_number); | |
| 364 } | |
| 365 } | |
| 366 } | |
| 367 | |
| 368 void QuicSentPacketManager::NeuterUnencryptedPackets() { | |
| 369 QuicPacketSequenceNumber sequence_number = unacked_packets_.GetLeastUnacked(); | |
| 370 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | |
| 371 it != unacked_packets_.end(); ++it, ++sequence_number) { | |
| 372 const RetransmittableFrames* frames = it->retransmittable_frames; | |
| 373 if (frames != nullptr && frames->encryption_level() == ENCRYPTION_NONE) { | |
| 374 // Once you're forward secure, no unencrypted packets will be sent, crypto | |
| 375 // or otherwise. Unencrypted packets are neutered and abandoned, to ensure | |
| 376 // they are not retransmitted or considered lost from a congestion control | |
| 377 // perspective. | |
| 378 pending_retransmissions_.erase(sequence_number); | |
| 379 unacked_packets_.RemoveFromInFlight(sequence_number); | |
| 380 unacked_packets_.RemoveRetransmittability(sequence_number); | |
| 381 } | |
| 382 } | |
| 383 } | |
| 384 | |
| 385 void QuicSentPacketManager::MarkForRetransmission( | |
| 386 QuicPacketSequenceNumber sequence_number, | |
| 387 TransmissionType transmission_type) { | |
| 388 const TransmissionInfo& transmission_info = | |
| 389 unacked_packets_.GetTransmissionInfo(sequence_number); | |
| 390 LOG_IF(DFATAL, transmission_info.retransmittable_frames == nullptr); | |
| 391 // Both TLP and the new RTO leave the packets in flight and let the loss | |
| 392 // detection decide if packets are lost. | |
| 393 if (transmission_type != TLP_RETRANSMISSION && | |
| 394 (!FLAGS_quic_use_new_rto || transmission_type != RTO_RETRANSMISSION)) { | |
| 395 unacked_packets_.RemoveFromInFlight(sequence_number); | |
| 396 } | |
| 397 // TODO(ianswett): Currently the RTO can fire while there are pending NACK | |
| 398 // retransmissions for the same data, which is not ideal. | |
| 399 if (ContainsKey(pending_retransmissions_, sequence_number)) { | |
| 400 return; | |
| 401 } | |
| 402 | |
| 403 pending_retransmissions_[sequence_number] = transmission_type; | |
| 404 } | |
| 405 | |
| 406 void QuicSentPacketManager::RecordSpuriousRetransmissions( | |
| 407 const SequenceNumberList& all_transmissions, | |
| 408 QuicPacketSequenceNumber acked_sequence_number) { | |
| 409 if (!FLAGS_quic_use_new_rto && | |
| 410 acked_sequence_number < first_rto_transmission_) { | |
| 411 // Cancel all pending RTO transmissions and restore their in flight status. | |
| 412 // Replace SRTT with latest_rtt and increase the variance to prevent | |
| 413 // a spurious RTO from happening again. | |
| 414 rtt_stats_.ExpireSmoothedMetrics(); | |
| 415 for (PendingRetransmissionMap::const_iterator it = | |
| 416 pending_retransmissions_.begin(); | |
| 417 it != pending_retransmissions_.end(); ++it) { | |
| 418 DCHECK_EQ(it->second, RTO_RETRANSMISSION); | |
| 419 unacked_packets_.RestoreInFlight(it->first); | |
| 420 } | |
| 421 pending_retransmissions_.clear(); | |
| 422 send_algorithm_->RevertRetransmissionTimeout(); | |
| 423 first_rto_transmission_ = 0; | |
| 424 ++stats_->spurious_rto_count; | |
| 425 } | |
| 426 for (SequenceNumberList::const_reverse_iterator it = | |
| 427 all_transmissions.rbegin(); | |
| 428 it != all_transmissions.rend() && *it > acked_sequence_number; ++it) { | |
| 429 const TransmissionInfo& retransmit_info = | |
| 430 unacked_packets_.GetTransmissionInfo(*it); | |
| 431 | |
| 432 stats_->bytes_spuriously_retransmitted += retransmit_info.bytes_sent; | |
| 433 ++stats_->packets_spuriously_retransmitted; | |
| 434 if (debug_delegate_ != nullptr) { | |
| 435 debug_delegate_->OnSpuriousPacketRetransmission( | |
| 436 retransmit_info.transmission_type, retransmit_info.bytes_sent); | |
| 437 } | |
| 438 } | |
| 439 } | |
| 440 | |
| 441 bool QuicSentPacketManager::HasPendingRetransmissions() const { | |
| 442 return !pending_retransmissions_.empty(); | |
| 443 } | |
| 444 | |
| 445 QuicSentPacketManager::PendingRetransmission | |
| 446 QuicSentPacketManager::NextPendingRetransmission() { | |
| 447 LOG_IF(DFATAL, pending_retransmissions_.empty()) | |
| 448 << "Unexpected call to PendingRetransmissions() with empty pending " | |
| 449 << "retransmission list. Corrupted memory usage imminent."; | |
| 450 QuicPacketSequenceNumber sequence_number = | |
| 451 pending_retransmissions_.begin()->first; | |
| 452 TransmissionType transmission_type = pending_retransmissions_.begin()->second; | |
| 453 if (unacked_packets_.HasPendingCryptoPackets()) { | |
| 454 // Ensure crypto packets are retransmitted before other packets. | |
| 455 PendingRetransmissionMap::const_iterator it = | |
| 456 pending_retransmissions_.begin(); | |
| 457 do { | |
| 458 if (HasCryptoHandshake(unacked_packets_.GetTransmissionInfo(it->first))) { | |
| 459 sequence_number = it->first; | |
| 460 transmission_type = it->second; | |
| 461 break; | |
| 462 } | |
| 463 ++it; | |
| 464 } while (it != pending_retransmissions_.end()); | |
| 465 } | |
| 466 DCHECK(unacked_packets_.IsUnacked(sequence_number)) << sequence_number; | |
| 467 const TransmissionInfo& transmission_info = | |
| 468 unacked_packets_.GetTransmissionInfo(sequence_number); | |
| 469 DCHECK(transmission_info.retransmittable_frames); | |
| 470 | |
| 471 return PendingRetransmission(sequence_number, | |
| 472 transmission_type, | |
| 473 *transmission_info.retransmittable_frames, | |
| 474 transmission_info.sequence_number_length); | |
| 475 } | |
| 476 | |
| 477 void QuicSentPacketManager::MarkPacketRevived( | |
| 478 QuicPacketSequenceNumber sequence_number, | |
| 479 QuicTime::Delta delta_largest_observed) { | |
| 480 if (!unacked_packets_.IsUnacked(sequence_number)) { | |
| 481 return; | |
| 482 } | |
| 483 | |
| 484 const TransmissionInfo& transmission_info = | |
| 485 unacked_packets_.GetTransmissionInfo(sequence_number); | |
| 486 QuicPacketSequenceNumber newest_transmission = | |
| 487 transmission_info.all_transmissions == nullptr | |
| 488 ? sequence_number | |
| 489 : *transmission_info.all_transmissions->rbegin(); | |
| 490 // This packet has been revived at the receiver. If we were going to | |
| 491 // retransmit it, do not retransmit it anymore. | |
| 492 pending_retransmissions_.erase(newest_transmission); | |
| 493 | |
| 494 // The AckNotifierManager needs to be notified for revived packets, | |
| 495 // since it indicates the packet arrived from the appliction's perspective. | |
| 496 if (FLAGS_quic_attach_ack_notifiers_to_packets || | |
| 497 transmission_info.retransmittable_frames) { | |
| 498 ack_notifier_manager_.OnPacketAcked(newest_transmission, | |
| 499 delta_largest_observed); | |
| 500 } | |
| 501 | |
| 502 unacked_packets_.RemoveRetransmittability(sequence_number); | |
| 503 } | |
| 504 | |
| 505 void QuicSentPacketManager::MarkPacketHandled( | |
| 506 QuicPacketSequenceNumber sequence_number, | |
| 507 const TransmissionInfo& info, | |
| 508 QuicTime::Delta delta_largest_observed) { | |
| 509 QuicPacketSequenceNumber newest_transmission = | |
| 510 info.all_transmissions == nullptr ? | |
| 511 sequence_number : *info.all_transmissions->rbegin(); | |
| 512 // Remove the most recent packet, if it is pending retransmission. | |
| 513 pending_retransmissions_.erase(newest_transmission); | |
| 514 | |
| 515 // The AckNotifierManager needs to be notified about the most recent | |
| 516 // transmission, since that's the one only one it tracks. | |
| 517 ack_notifier_manager_.OnPacketAcked(newest_transmission, | |
| 518 delta_largest_observed); | |
| 519 if (newest_transmission != sequence_number) { | |
| 520 RecordSpuriousRetransmissions(*info.all_transmissions, sequence_number); | |
| 521 // Remove the most recent packet from flight if it's a crypto handshake | |
| 522 // packet, since they won't be acked now that one has been processed. | |
| 523 // Other crypto handshake packets won't be in flight, only the newest | |
| 524 // transmission of a crypto packet is in flight at once. | |
| 525 // TODO(ianswett): Instead of handling all crypto packets special, | |
| 526 // only handle nullptr encrypted packets in a special way. | |
| 527 if (HasCryptoHandshake( | |
| 528 unacked_packets_.GetTransmissionInfo(newest_transmission))) { | |
| 529 unacked_packets_.RemoveFromInFlight(newest_transmission); | |
| 530 } | |
| 531 } | |
| 532 | |
| 533 unacked_packets_.RemoveFromInFlight(sequence_number); | |
| 534 unacked_packets_.RemoveRetransmittability(sequence_number); | |
| 535 } | |
| 536 | |
| 537 bool QuicSentPacketManager::IsUnacked( | |
| 538 QuicPacketSequenceNumber sequence_number) const { | |
| 539 return unacked_packets_.IsUnacked(sequence_number); | |
| 540 } | |
| 541 | |
| 542 bool QuicSentPacketManager::HasUnackedPackets() const { | |
| 543 return unacked_packets_.HasUnackedPackets(); | |
| 544 } | |
| 545 | |
| 546 QuicPacketSequenceNumber | |
| 547 QuicSentPacketManager::GetLeastUnacked() const { | |
| 548 return unacked_packets_.GetLeastUnacked(); | |
| 549 } | |
| 550 | |
| 551 bool QuicSentPacketManager::OnPacketSent( | |
| 552 SerializedPacket* serialized_packet, | |
| 553 QuicPacketSequenceNumber original_sequence_number, | |
| 554 QuicTime sent_time, | |
| 555 QuicByteCount bytes, | |
| 556 TransmissionType transmission_type, | |
| 557 HasRetransmittableData has_retransmittable_data) { | |
| 558 QuicPacketSequenceNumber sequence_number = serialized_packet->sequence_number; | |
| 559 DCHECK_LT(0u, sequence_number); | |
| 560 DCHECK(!unacked_packets_.IsUnacked(sequence_number)); | |
| 561 LOG_IF(DFATAL, bytes == 0) << "Cannot send empty packets."; | |
| 562 | |
| 563 if (original_sequence_number != 0) { | |
| 564 PendingRetransmissionMap::iterator it = | |
| 565 pending_retransmissions_.find(original_sequence_number); | |
| 566 if (it != pending_retransmissions_.end()) { | |
| 567 pending_retransmissions_.erase(it); | |
| 568 } else { | |
| 569 DLOG(DFATAL) << "Expected sequence number to be in " | |
| 570 << "pending_retransmissions_. sequence_number: " | |
| 571 << original_sequence_number; | |
| 572 } | |
| 573 // Inform the ack notifier of retransmissions so it can calculate the | |
| 574 // retransmit rate. | |
| 575 ack_notifier_manager_.OnPacketRetransmitted(original_sequence_number, | |
| 576 sequence_number, bytes); | |
| 577 } | |
| 578 | |
| 579 if (pending_timer_transmission_count_ > 0) { | |
| 580 --pending_timer_transmission_count_; | |
| 581 } | |
| 582 | |
| 583 if (unacked_packets_.bytes_in_flight() == 0) { | |
| 584 // TODO(ianswett): Consider being less aggressive to force a new | |
| 585 // recent_min_rtt, likely by not discarding a relatively new sample. | |
| 586 DVLOG(1) << "Sampling a new recent min rtt within 2 samples. currently:" | |
| 587 << rtt_stats_.recent_min_rtt().ToMilliseconds() << "ms"; | |
| 588 rtt_stats_.SampleNewRecentMinRtt(kNumMinRttSamplesAfterQuiescence); | |
| 589 } | |
| 590 | |
| 591 // Only track packets as in flight that the send algorithm wants us to track. | |
| 592 // Since FEC packets should also be counted towards the congestion window, | |
| 593 // consider them as retransmittable for the purposes of congestion control. | |
| 594 HasRetransmittableData has_congestion_controlled_data = | |
| 595 serialized_packet->is_fec_packet ? HAS_RETRANSMITTABLE_DATA | |
| 596 : has_retransmittable_data; | |
| 597 const bool in_flight = | |
| 598 send_algorithm_->OnPacketSent(sent_time, | |
| 599 unacked_packets_.bytes_in_flight(), | |
| 600 sequence_number, | |
| 601 bytes, | |
| 602 has_congestion_controlled_data); | |
| 603 | |
| 604 unacked_packets_.AddSentPacket(*serialized_packet, | |
| 605 original_sequence_number, | |
| 606 transmission_type, | |
| 607 sent_time, | |
| 608 bytes, | |
| 609 in_flight); | |
| 610 | |
| 611 // Take ownership of the retransmittable frames before exiting. | |
| 612 serialized_packet->retransmittable_frames = nullptr; | |
| 613 // Reset the retransmission timer anytime a pending packet is sent. | |
| 614 return in_flight; | |
| 615 } | |
| 616 | |
| 617 void QuicSentPacketManager::OnRetransmissionTimeout() { | |
| 618 DCHECK(unacked_packets_.HasInFlightPackets()); | |
| 619 DCHECK_EQ(0u, pending_timer_transmission_count_); | |
| 620 // Handshake retransmission, timer based loss detection, TLP, and RTO are | |
| 621 // implemented with a single alarm. The handshake alarm is set when the | |
| 622 // handshake has not completed, the loss alarm is set when the loss detection | |
| 623 // algorithm says to, and the TLP and RTO alarms are set after that. | |
| 624 // The TLP alarm is always set to run for under an RTO. | |
| 625 switch (GetRetransmissionMode()) { | |
| 626 case HANDSHAKE_MODE: | |
| 627 ++stats_->crypto_retransmit_count; | |
| 628 RetransmitCryptoPackets(); | |
| 629 return; | |
| 630 case LOSS_MODE: { | |
| 631 ++stats_->loss_timeout_count; | |
| 632 QuicByteCount bytes_in_flight = unacked_packets_.bytes_in_flight(); | |
| 633 InvokeLossDetection(clock_->Now()); | |
| 634 MaybeInvokeCongestionEvent(false, bytes_in_flight); | |
| 635 return; | |
| 636 } | |
| 637 case TLP_MODE: | |
| 638 // If no tail loss probe can be sent, because there are no retransmittable | |
| 639 // packets, execute a conventional RTO to abandon old packets. | |
| 640 ++stats_->tlp_count; | |
| 641 ++consecutive_tlp_count_; | |
| 642 pending_timer_transmission_count_ = 1; | |
| 643 // TLPs prefer sending new data instead of retransmitting data, so | |
| 644 // give the connection a chance to write before completing the TLP. | |
| 645 return; | |
| 646 case RTO_MODE: | |
| 647 ++stats_->rto_count; | |
| 648 if (FLAGS_quic_use_new_rto) { | |
| 649 RetransmitRtoPackets(); | |
| 650 } else { | |
| 651 RetransmitAllPackets(); | |
| 652 } | |
| 653 return; | |
| 654 } | |
| 655 } | |
| 656 | |
| 657 void QuicSentPacketManager::RetransmitCryptoPackets() { | |
| 658 DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode()); | |
| 659 ++consecutive_crypto_retransmission_count_; | |
| 660 bool packet_retransmitted = false; | |
| 661 QuicPacketSequenceNumber sequence_number = unacked_packets_.GetLeastUnacked(); | |
| 662 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | |
| 663 it != unacked_packets_.end(); ++it, ++sequence_number) { | |
| 664 // Only retransmit frames which are in flight, and therefore have been sent. | |
| 665 if (!it->in_flight || it->retransmittable_frames == nullptr || | |
| 666 it->retransmittable_frames->HasCryptoHandshake() != IS_HANDSHAKE) { | |
| 667 continue; | |
| 668 } | |
| 669 packet_retransmitted = true; | |
| 670 MarkForRetransmission(sequence_number, HANDSHAKE_RETRANSMISSION); | |
| 671 ++pending_timer_transmission_count_; | |
| 672 } | |
| 673 DCHECK(packet_retransmitted) << "No crypto packets found to retransmit."; | |
| 674 } | |
| 675 | |
| 676 bool QuicSentPacketManager::MaybeRetransmitTailLossProbe() { | |
| 677 if (pending_timer_transmission_count_ == 0) { | |
| 678 return false; | |
| 679 } | |
| 680 QuicPacketSequenceNumber sequence_number = unacked_packets_.GetLeastUnacked(); | |
| 681 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | |
| 682 it != unacked_packets_.end(); ++it, ++sequence_number) { | |
| 683 // Only retransmit frames which are in flight, and therefore have been sent. | |
| 684 if (!it->in_flight || it->retransmittable_frames == nullptr) { | |
| 685 continue; | |
| 686 } | |
| 687 if (!handshake_confirmed_) { | |
| 688 DCHECK_NE(IS_HANDSHAKE, it->retransmittable_frames->HasCryptoHandshake()); | |
| 689 } | |
| 690 MarkForRetransmission(sequence_number, TLP_RETRANSMISSION); | |
| 691 return true; | |
| 692 } | |
| 693 DLOG(FATAL) | |
| 694 << "No retransmittable packets, so RetransmitOldestPacket failed."; | |
| 695 return false; | |
| 696 } | |
| 697 | |
| 698 void QuicSentPacketManager::RetransmitRtoPackets() { | |
| 699 LOG_IF(DFATAL, pending_timer_transmission_count_ > 0) | |
| 700 << "Retransmissions already queued:" << pending_timer_transmission_count_; | |
| 701 // Mark two packets for retransmission. | |
| 702 QuicPacketSequenceNumber sequence_number = unacked_packets_.GetLeastUnacked(); | |
| 703 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | |
| 704 it != unacked_packets_.end(); ++it, ++sequence_number) { | |
| 705 if (it->retransmittable_frames != nullptr && | |
| 706 pending_timer_transmission_count_ < kMaxRetransmissionsOnTimeout) { | |
| 707 MarkForRetransmission(sequence_number, RTO_RETRANSMISSION); | |
| 708 ++pending_timer_transmission_count_; | |
| 709 } | |
| 710 // Abandon non-retransmittable data that's in flight to ensure it doesn't | |
| 711 // fill up the congestion window. | |
| 712 if (it->retransmittable_frames == nullptr && it->in_flight && | |
| 713 it->all_transmissions == nullptr) { | |
| 714 unacked_packets_.RemoveFromInFlight(sequence_number); | |
| 715 } | |
| 716 } | |
| 717 if (pending_timer_transmission_count_ > 0) { | |
| 718 if (consecutive_rto_count_ == 0) { | |
| 719 first_rto_transmission_ = unacked_packets_.largest_sent_packet() + 1; | |
| 720 } | |
| 721 ++consecutive_rto_count_; | |
| 722 } | |
| 723 } | |
| 724 | |
| 725 void QuicSentPacketManager::RetransmitAllPackets() { | |
| 726 DVLOG(1) << "RetransmitAllPackets() called with " | |
| 727 << unacked_packets_.GetNumUnackedPacketsDebugOnly() | |
| 728 << " unacked packets."; | |
| 729 // Request retransmission of all retransmittable packets when the RTO | |
| 730 // fires, and let the congestion manager decide how many to send | |
| 731 // immediately and the remaining packets will be queued. | |
| 732 // Abandon any non-retransmittable packets that are sufficiently old. | |
| 733 bool packets_retransmitted = false; | |
| 734 QuicPacketSequenceNumber sequence_number = unacked_packets_.GetLeastUnacked(); | |
| 735 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | |
| 736 it != unacked_packets_.end(); ++it, ++sequence_number) { | |
| 737 if (it->retransmittable_frames != nullptr) { | |
| 738 packets_retransmitted = true; | |
| 739 MarkForRetransmission(sequence_number, RTO_RETRANSMISSION); | |
| 740 } else { | |
| 741 unacked_packets_.RemoveFromInFlight(sequence_number); | |
| 742 } | |
| 743 } | |
| 744 | |
| 745 send_algorithm_->OnRetransmissionTimeout(packets_retransmitted); | |
| 746 if (packets_retransmitted) { | |
| 747 if (consecutive_rto_count_ == 0) { | |
| 748 first_rto_transmission_ = unacked_packets_.largest_sent_packet() + 1; | |
| 749 } | |
| 750 ++consecutive_rto_count_; | |
| 751 } | |
| 752 | |
| 753 if (network_change_visitor_ != nullptr) { | |
| 754 network_change_visitor_->OnCongestionWindowChange(); | |
| 755 } | |
| 756 } | |
| 757 | |
| 758 QuicSentPacketManager::RetransmissionTimeoutMode | |
| 759 QuicSentPacketManager::GetRetransmissionMode() const { | |
| 760 DCHECK(unacked_packets_.HasInFlightPackets()); | |
| 761 if (!handshake_confirmed_ && unacked_packets_.HasPendingCryptoPackets()) { | |
| 762 return HANDSHAKE_MODE; | |
| 763 } | |
| 764 if (loss_algorithm_->GetLossTimeout() != QuicTime::Zero()) { | |
| 765 return LOSS_MODE; | |
| 766 } | |
| 767 if (consecutive_tlp_count_ < max_tail_loss_probes_) { | |
| 768 if (unacked_packets_.HasUnackedRetransmittableFrames()) { | |
| 769 return TLP_MODE; | |
| 770 } | |
| 771 } | |
| 772 return RTO_MODE; | |
| 773 } | |
| 774 | |
| 775 void QuicSentPacketManager::InvokeLossDetection(QuicTime time) { | |
| 776 SequenceNumberSet lost_packets = | |
| 777 loss_algorithm_->DetectLostPackets(unacked_packets_, | |
| 778 time, | |
| 779 unacked_packets_.largest_observed(), | |
| 780 rtt_stats_); | |
| 781 for (SequenceNumberSet::const_iterator it = lost_packets.begin(); | |
| 782 it != lost_packets.end(); ++it) { | |
| 783 QuicPacketSequenceNumber sequence_number = *it; | |
| 784 const TransmissionInfo& transmission_info = | |
| 785 unacked_packets_.GetTransmissionInfo(sequence_number); | |
| 786 // TODO(ianswett): If it's expected the FEC packet may repair the loss, it | |
| 787 // should be recorded as a loss to the send algorithm, but not retransmitted | |
| 788 // until it's known whether the FEC packet arrived. | |
| 789 ++stats_->packets_lost; | |
| 790 packets_lost_.push_back(std::make_pair(sequence_number, transmission_info)); | |
| 791 DVLOG(1) << ENDPOINT << "Lost packet " << sequence_number; | |
| 792 | |
| 793 if (transmission_info.retransmittable_frames != nullptr) { | |
| 794 MarkForRetransmission(sequence_number, LOSS_RETRANSMISSION); | |
| 795 } else { | |
| 796 // Since we will not retransmit this, we need to remove it from | |
| 797 // unacked_packets_. This is either the current transmission of | |
| 798 // a packet whose previous transmission has been acked, a packet that has | |
| 799 // been TLP retransmitted, or an FEC packet. | |
| 800 unacked_packets_.RemoveFromInFlight(sequence_number); | |
| 801 } | |
| 802 } | |
| 803 } | |
| 804 | |
| 805 bool QuicSentPacketManager::MaybeUpdateRTT( | |
| 806 const QuicAckFrame& ack_frame, | |
| 807 const QuicTime& ack_receive_time) { | |
| 808 // We rely on delta_time_largest_observed to compute an RTT estimate, so we | |
| 809 // only update rtt when the largest observed gets acked. | |
| 810 // NOTE: If ack is a truncated ack, then the largest observed is in fact | |
| 811 // unacked, and may cause an RTT sample to be taken. | |
| 812 if (!unacked_packets_.IsUnacked(ack_frame.largest_observed)) { | |
| 813 return false; | |
| 814 } | |
| 815 // We calculate the RTT based on the highest ACKed sequence number, the lower | |
| 816 // sequence numbers will include the ACK aggregation delay. | |
| 817 const TransmissionInfo& transmission_info = | |
| 818 unacked_packets_.GetTransmissionInfo(ack_frame.largest_observed); | |
| 819 // Ensure the packet has a valid sent time. | |
| 820 if (transmission_info.sent_time == QuicTime::Zero()) { | |
| 821 LOG(DFATAL) << "Acked packet has zero sent time, largest_observed:" | |
| 822 << ack_frame.largest_observed; | |
| 823 return false; | |
| 824 } | |
| 825 | |
| 826 QuicTime::Delta send_delta = | |
| 827 ack_receive_time.Subtract(transmission_info.sent_time); | |
| 828 rtt_stats_.UpdateRtt( | |
| 829 send_delta, ack_frame.delta_time_largest_observed, ack_receive_time); | |
| 830 | |
| 831 if (network_change_visitor_ != nullptr) { | |
| 832 network_change_visitor_->OnRttChange(); | |
| 833 } | |
| 834 | |
| 835 return true; | |
| 836 } | |
| 837 | |
| 838 QuicTime::Delta QuicSentPacketManager::TimeUntilSend( | |
| 839 QuicTime now, | |
| 840 HasRetransmittableData retransmittable) { | |
| 841 // The TLP logic is entirely contained within QuicSentPacketManager, so the | |
| 842 // send algorithm does not need to be consulted. | |
| 843 if (pending_timer_transmission_count_ > 0) { | |
| 844 return QuicTime::Delta::Zero(); | |
| 845 } | |
| 846 if (unacked_packets_.bytes_in_flight() >= | |
| 847 kUsableRecieveBufferFraction * receive_buffer_bytes_) { | |
| 848 return QuicTime::Delta::Infinite(); | |
| 849 } | |
| 850 return send_algorithm_->TimeUntilSend( | |
| 851 now, unacked_packets_.bytes_in_flight(), retransmittable); | |
| 852 } | |
| 853 | |
| 854 // Uses a 25ms delayed ack timer. Also helps with better signaling | |
| 855 // in low-bandwidth (< ~384 kbps), where an ack is sent per packet. | |
| 856 // Ensures that the Delayed Ack timer is always set to a value lesser | |
| 857 // than the retransmission timer's minimum value (MinRTO). We want the | |
| 858 // delayed ack to get back to the QUIC peer before the sender's | |
| 859 // retransmission timer triggers. Since we do not know the | |
| 860 // reverse-path one-way delay, we assume equal delays for forward and | |
| 861 // reverse paths, and ensure that the timer is set to less than half | |
| 862 // of the MinRTO. | |
| 863 // There may be a value in making this delay adaptive with the help of | |
| 864 // the sender and a signaling mechanism -- if the sender uses a | |
| 865 // different MinRTO, we may get spurious retransmissions. May not have | |
| 866 // any benefits, but if the delayed ack becomes a significant source | |
| 867 // of (likely, tail) latency, then consider such a mechanism. | |
| 868 const QuicTime::Delta QuicSentPacketManager::DelayedAckTime() const { | |
| 869 return QuicTime::Delta::FromMilliseconds(min(kMaxDelayedAckTimeMs, | |
| 870 kMinRetransmissionTimeMs / 2)); | |
| 871 } | |
| 872 | |
| 873 const QuicTime QuicSentPacketManager::GetRetransmissionTime() const { | |
| 874 // Don't set the timer if there are no packets in flight or we've already | |
| 875 // queued a tlp transmission and it hasn't been sent yet. | |
| 876 if (!unacked_packets_.HasInFlightPackets() || | |
| 877 pending_timer_transmission_count_ > 0) { | |
| 878 return QuicTime::Zero(); | |
| 879 } | |
| 880 switch (GetRetransmissionMode()) { | |
| 881 case HANDSHAKE_MODE: | |
| 882 return clock_->ApproximateNow().Add(GetCryptoRetransmissionDelay()); | |
| 883 case LOSS_MODE: | |
| 884 return loss_algorithm_->GetLossTimeout(); | |
| 885 case TLP_MODE: { | |
| 886 // TODO(ianswett): When CWND is available, it would be preferable to | |
| 887 // set the timer based on the earliest retransmittable packet. | |
| 888 // Base the updated timer on the send time of the last packet. | |
| 889 const QuicTime sent_time = unacked_packets_.GetLastPacketSentTime(); | |
| 890 const QuicTime tlp_time = sent_time.Add(GetTailLossProbeDelay()); | |
| 891 // Ensure the TLP timer never gets set to a time in the past. | |
| 892 return QuicTime::Max(clock_->ApproximateNow(), tlp_time); | |
| 893 } | |
| 894 case RTO_MODE: { | |
| 895 // The RTO is based on the first outstanding packet. | |
| 896 const QuicTime sent_time = | |
| 897 FLAGS_quic_rto_uses_last_sent | |
| 898 ? unacked_packets_.GetLastPacketSentTime() | |
| 899 : unacked_packets_.GetFirstInFlightPacketSentTime(); | |
| 900 QuicTime rto_time = sent_time.Add(GetRetransmissionDelay()); | |
| 901 // Wait for TLP packets to be acked before an RTO fires. | |
| 902 QuicTime tlp_time = | |
| 903 unacked_packets_.GetLastPacketSentTime().Add(GetTailLossProbeDelay()); | |
| 904 return QuicTime::Max(tlp_time, rto_time); | |
| 905 } | |
| 906 } | |
| 907 DCHECK(false); | |
| 908 return QuicTime::Zero(); | |
| 909 } | |
| 910 | |
| 911 const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay() | |
| 912 const { | |
| 913 // This is equivalent to the TailLossProbeDelay, but slightly more aggressive | |
| 914 // because crypto handshake messages don't incur a delayed ack time. | |
| 915 QuicTime::Delta srtt = rtt_stats_.smoothed_rtt(); | |
| 916 if (srtt.IsZero()) { | |
| 917 srtt = QuicTime::Delta::FromMicroseconds(rtt_stats_.initial_rtt_us()); | |
| 918 } | |
| 919 int64 delay_ms = max(kMinHandshakeTimeoutMs, | |
| 920 static_cast<int64>(1.5 * srtt.ToMilliseconds())); | |
| 921 return QuicTime::Delta::FromMilliseconds( | |
| 922 delay_ms << consecutive_crypto_retransmission_count_); | |
| 923 } | |
| 924 | |
| 925 const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const { | |
| 926 QuicTime::Delta srtt = rtt_stats_.smoothed_rtt(); | |
| 927 if (srtt.IsZero()) { | |
| 928 srtt = QuicTime::Delta::FromMicroseconds(rtt_stats_.initial_rtt_us()); | |
| 929 } | |
| 930 if (!unacked_packets_.HasMultipleInFlightPackets()) { | |
| 931 return QuicTime::Delta::Max( | |
| 932 srtt.Multiply(2), srtt.Multiply(1.5).Add( | |
| 933 QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs / 2))); | |
| 934 } | |
| 935 return QuicTime::Delta::FromMilliseconds( | |
| 936 max(kMinTailLossProbeTimeoutMs, | |
| 937 static_cast<int64>(2 * srtt.ToMilliseconds()))); | |
| 938 } | |
| 939 | |
| 940 const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const { | |
| 941 QuicTime::Delta retransmission_delay = send_algorithm_->RetransmissionDelay(); | |
| 942 // TODO(rch): This code should move to |send_algorithm_|. | |
| 943 if (retransmission_delay.IsZero()) { | |
| 944 // We are in the initial state, use default timeout values. | |
| 945 retransmission_delay = | |
| 946 QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); | |
| 947 } else if (retransmission_delay.ToMilliseconds() < kMinRetransmissionTimeMs) { | |
| 948 retransmission_delay = | |
| 949 QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs); | |
| 950 } | |
| 951 | |
| 952 // Calculate exponential back off. | |
| 953 retransmission_delay = retransmission_delay.Multiply( | |
| 954 1 << min<size_t>(consecutive_rto_count_, kMaxRetransmissions)); | |
| 955 | |
| 956 if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) { | |
| 957 return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs); | |
| 958 } | |
| 959 return retransmission_delay; | |
| 960 } | |
| 961 | |
| 962 const RttStats* QuicSentPacketManager::GetRttStats() const { | |
| 963 return &rtt_stats_; | |
| 964 } | |
| 965 | |
| 966 QuicBandwidth QuicSentPacketManager::BandwidthEstimate() const { | |
| 967 // TODO(ianswett): Remove BandwidthEstimate from SendAlgorithmInterface | |
| 968 // and implement the logic here. | |
| 969 return send_algorithm_->BandwidthEstimate(); | |
| 970 } | |
| 971 | |
| 972 bool QuicSentPacketManager::HasReliableBandwidthEstimate() const { | |
| 973 return send_algorithm_->HasReliableBandwidthEstimate(); | |
| 974 } | |
| 975 | |
| 976 const QuicSustainedBandwidthRecorder& | |
| 977 QuicSentPacketManager::SustainedBandwidthRecorder() const { | |
| 978 return sustained_bandwidth_recorder_; | |
| 979 } | |
| 980 | |
| 981 QuicPacketCount QuicSentPacketManager::EstimateMaxPacketsInFlight( | |
| 982 QuicByteCount max_packet_length) const { | |
| 983 return send_algorithm_->GetCongestionWindow() / max_packet_length; | |
| 984 } | |
| 985 | |
| 986 QuicPacketCount QuicSentPacketManager::GetCongestionWindowInTcpMss() const { | |
| 987 return send_algorithm_->GetCongestionWindow() / kDefaultTCPMSS; | |
| 988 } | |
| 989 | |
| 990 QuicPacketCount QuicSentPacketManager::GetSlowStartThresholdInTcpMss() const { | |
| 991 return send_algorithm_->GetSlowStartThreshold() / kDefaultTCPMSS; | |
| 992 } | |
| 993 | |
| 994 void QuicSentPacketManager::OnSerializedPacket( | |
| 995 const SerializedPacket& serialized_packet) { | |
| 996 ack_notifier_manager_.OnSerializedPacket(serialized_packet); | |
| 997 } | |
| 998 | |
| 999 void QuicSentPacketManager::EnablePacing() { | |
| 1000 if (using_pacing_) { | |
| 1001 return; | |
| 1002 } | |
| 1003 | |
| 1004 // Set up a pacing sender with a 1 millisecond alarm granularity, the same as | |
| 1005 // the default granularity of the Linux kernel's FQ qdisc. | |
| 1006 using_pacing_ = true; | |
| 1007 send_algorithm_.reset( | |
| 1008 new PacingSender(send_algorithm_.release(), | |
| 1009 QuicTime::Delta::FromMilliseconds(1), | |
| 1010 kInitialUnpacedBurst)); | |
| 1011 } | |
| 1012 | |
| 1013 } // namespace net | |
| OLD | NEW |