| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/quic_sent_packet_manager.h" | 5 #include "net/quic/quic_sent_packet_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 return false; | 56 return false; |
| 57 } | 57 } |
| 58 return transmission_info.retransmittable_frames->HasCryptoHandshake() == | 58 return transmission_info.retransmittable_frames->HasCryptoHandshake() == |
| 59 IS_HANDSHAKE; | 59 IS_HANDSHAKE; |
| 60 } | 60 } |
| 61 | 61 |
| 62 } // namespace | 62 } // namespace |
| 63 | 63 |
| 64 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") | 64 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") |
| 65 | 65 |
| 66 QuicSentPacketManager::QuicSentPacketManager(bool is_server, | 66 QuicSentPacketManager::QuicSentPacketManager( |
| 67 const QuicClock* clock, | 67 bool is_server, |
| 68 QuicConnectionStats* stats, | 68 const QuicClock* clock, |
| 69 CongestionFeedbackType type, | 69 QuicConnectionStats* stats, |
| 70 LossDetectionType loss_type) | 70 CongestionControlType congestion_control_type, |
| 71 LossDetectionType loss_type) |
| 71 : unacked_packets_(), | 72 : unacked_packets_(), |
| 72 is_server_(is_server), | 73 is_server_(is_server), |
| 73 clock_(clock), | 74 clock_(clock), |
| 74 stats_(stats), | 75 stats_(stats), |
| 75 debug_delegate_(NULL), | 76 debug_delegate_(NULL), |
| 76 send_algorithm_( | 77 network_change_visitor_(NULL), |
| 77 SendAlgorithmInterface::Create(clock, &rtt_stats_, type, stats)), | 78 send_algorithm_(SendAlgorithmInterface::Create(clock, |
| 79 &rtt_stats_, |
| 80 congestion_control_type, |
| 81 stats)), |
| 78 loss_algorithm_(LossDetectionInterface::Create(loss_type)), | 82 loss_algorithm_(LossDetectionInterface::Create(loss_type)), |
| 79 largest_observed_(0), | 83 largest_observed_(0), |
| 80 first_rto_transmission_(0), | 84 first_rto_transmission_(0), |
| 81 consecutive_rto_count_(0), | 85 consecutive_rto_count_(0), |
| 82 consecutive_tlp_count_(0), | 86 consecutive_tlp_count_(0), |
| 83 consecutive_crypto_retransmission_count_(0), | 87 consecutive_crypto_retransmission_count_(0), |
| 84 pending_tlp_transmission_(false), | 88 pending_tlp_transmission_(false), |
| 85 max_tail_loss_probes_(kDefaultMaxTailLossProbes), | 89 max_tail_loss_probes_(kDefaultMaxTailLossProbes), |
| 86 using_pacing_(false) { | 90 using_pacing_(false) { |
| 87 } | 91 } |
| 88 | 92 |
| 89 QuicSentPacketManager::~QuicSentPacketManager() { | 93 QuicSentPacketManager::~QuicSentPacketManager() { |
| 90 } | 94 } |
| 91 | 95 |
| 92 void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { | 96 void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { |
| 93 if (config.HasReceivedInitialRoundTripTimeUs() && | 97 if (config.HasReceivedInitialRoundTripTimeUs() && |
| 94 config.ReceivedInitialRoundTripTimeUs() > 0) { | 98 config.ReceivedInitialRoundTripTimeUs() > 0) { |
| 95 rtt_stats_.set_initial_rtt_us(min(kMaxInitialRoundTripTimeUs, | 99 rtt_stats_.set_initial_rtt_us(min(kMaxInitialRoundTripTimeUs, |
| 96 config.ReceivedInitialRoundTripTimeUs())); | 100 config.ReceivedInitialRoundTripTimeUs())); |
| 97 } | 101 } |
| 98 // TODO(ianswett): BBR is currently a server only feature. | 102 // TODO(ianswett): BBR is currently a server only feature. |
| 99 if (config.HasReceivedConnectionOptions() && | 103 if (config.HasReceivedConnectionOptions() && |
| 100 ContainsQuicTag(config.ReceivedConnectionOptions(), kTBBR)) { | 104 ContainsQuicTag(config.ReceivedConnectionOptions(), kTBBR)) { |
| 101 if (FLAGS_quic_recent_min_rtt_window_s > 0) { | 105 if (FLAGS_quic_recent_min_rtt_window_s > 0) { |
| 102 rtt_stats_.set_recent_min_rtt_window( | 106 rtt_stats_.set_recent_min_rtt_window( |
| 103 QuicTime::Delta::FromSeconds(FLAGS_quic_recent_min_rtt_window_s)); | 107 QuicTime::Delta::FromSeconds(FLAGS_quic_recent_min_rtt_window_s)); |
| 104 } | 108 } |
| 105 send_algorithm_.reset( | 109 send_algorithm_.reset( |
| 106 SendAlgorithmInterface::Create(clock_, &rtt_stats_, kTCPBBR, stats_)); | 110 SendAlgorithmInterface::Create(clock_, &rtt_stats_, kBBR, stats_)); |
| 107 } | 111 } |
| 108 if (config.congestion_feedback() == kPACE || | 112 if (config.congestion_feedback() == kPACE || |
| 109 (config.HasReceivedConnectionOptions() && | 113 (config.HasReceivedConnectionOptions() && |
| 110 ContainsQuicTag(config.ReceivedConnectionOptions(), kPACE))) { | 114 ContainsQuicTag(config.ReceivedConnectionOptions(), kPACE))) { |
| 111 MaybeEnablePacing(); | 115 MaybeEnablePacing(); |
| 112 } | 116 } |
| 113 // TODO(ianswett): Remove the "HasReceivedLossDetection" branch once | 117 // TODO(ianswett): Remove the "HasReceivedLossDetection" branch once |
| 114 // the ConnectionOptions code is live everywhere. | 118 // the ConnectionOptions code is live everywhere. |
| 115 if ((config.HasReceivedLossDetection() && | 119 if ((config.HasReceivedLossDetection() && |
| 116 config.ReceivedLossDetection() == kTIME) || | 120 config.ReceivedLossDetection() == kTIME) || |
| 117 (config.HasReceivedConnectionOptions() && | 121 (config.HasReceivedConnectionOptions() && |
| 118 ContainsQuicTag(config.ReceivedConnectionOptions(), kTIME))) { | 122 ContainsQuicTag(config.ReceivedConnectionOptions(), kTIME))) { |
| 119 loss_algorithm_.reset(LossDetectionInterface::Create(kTime)); | 123 loss_algorithm_.reset(LossDetectionInterface::Create(kTime)); |
| 120 } | 124 } |
| 121 send_algorithm_->SetFromConfig(config, is_server_); | 125 send_algorithm_->SetFromConfig(config, is_server_); |
| 126 |
| 127 if (network_change_visitor_ != NULL) { |
| 128 network_change_visitor_->OnCongestionWindowChange(GetCongestionWindow()); |
| 129 } |
| 122 } | 130 } |
| 123 | 131 |
| 124 // TODO(ianswett): Combine this method with OnPacketSent once packets are always | 132 // TODO(ianswett): Combine this method with OnPacketSent once packets are always |
| 125 // sent in order and the connection tracks RetransmittableFrames for longer. | 133 // sent in order and the connection tracks RetransmittableFrames for longer. |
| 126 void QuicSentPacketManager::OnSerializedPacket( | 134 void QuicSentPacketManager::OnSerializedPacket( |
| 127 const SerializedPacket& serialized_packet) { | 135 const SerializedPacket& serialized_packet) { |
| 128 if (serialized_packet.retransmittable_frames) { | 136 if (serialized_packet.retransmittable_frames) { |
| 129 ack_notifier_manager_.OnSerializedPacket(serialized_packet); | 137 ack_notifier_manager_.OnSerializedPacket(serialized_packet); |
| 130 } | 138 } |
| 131 | 139 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 debug_delegate_->OnIncomingAck(received_info, | 208 debug_delegate_->OnIncomingAck(received_info, |
| 201 ack_receive_time, | 209 ack_receive_time, |
| 202 largest_observed_, | 210 largest_observed_, |
| 203 largest_observed_acked, | 211 largest_observed_acked, |
| 204 GetLeastUnackedSentPacket()); | 212 GetLeastUnackedSentPacket()); |
| 205 } | 213 } |
| 206 } | 214 } |
| 207 | 215 |
| 208 void QuicSentPacketManager::MaybeInvokeCongestionEvent( | 216 void QuicSentPacketManager::MaybeInvokeCongestionEvent( |
| 209 bool rtt_updated, QuicByteCount bytes_in_flight) { | 217 bool rtt_updated, QuicByteCount bytes_in_flight) { |
| 210 if (rtt_updated || !packets_acked_.empty() || | 218 if (!rtt_updated && packets_acked_.empty() && packets_lost_.empty()) { |
| 211 !packets_lost_.empty()) { | 219 return; |
| 212 send_algorithm_->OnCongestionEvent( | 220 } |
| 213 rtt_updated, bytes_in_flight, packets_acked_, packets_lost_); | 221 send_algorithm_->OnCongestionEvent(rtt_updated, bytes_in_flight, |
| 214 packets_acked_.clear(); | 222 packets_acked_, packets_lost_); |
| 215 packets_lost_.clear(); | 223 packets_acked_.clear(); |
| 224 packets_lost_.clear(); |
| 225 if (network_change_visitor_ != NULL) { |
| 226 network_change_visitor_->OnCongestionWindowChange(GetCongestionWindow()); |
| 216 } | 227 } |
| 217 } | 228 } |
| 218 | 229 |
| 219 void QuicSentPacketManager::HandleAckForSentPackets( | 230 void QuicSentPacketManager::HandleAckForSentPackets( |
| 220 const ReceivedPacketInfo& received_info) { | 231 const ReceivedPacketInfo& received_info) { |
| 221 // Go through the packets we have not received an ack for and see if this | 232 // Go through the packets we have not received an ack for and see if this |
| 222 // incoming_ack shows they've been seen by the peer. | 233 // incoming_ack shows they've been seen by the peer. |
| 223 QuicTime::Delta delta_largest_observed = | 234 QuicTime::Delta delta_largest_observed = |
| 224 received_info.delta_time_largest_observed; | 235 received_info.delta_time_largest_observed; |
| 225 QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | 236 QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 } | 632 } |
| 622 } | 633 } |
| 623 | 634 |
| 624 send_algorithm_->OnRetransmissionTimeout(packets_retransmitted); | 635 send_algorithm_->OnRetransmissionTimeout(packets_retransmitted); |
| 625 if (packets_retransmitted) { | 636 if (packets_retransmitted) { |
| 626 if (consecutive_rto_count_ == 0) { | 637 if (consecutive_rto_count_ == 0) { |
| 627 first_rto_transmission_ = unacked_packets_.largest_sent_packet() + 1; | 638 first_rto_transmission_ = unacked_packets_.largest_sent_packet() + 1; |
| 628 } | 639 } |
| 629 ++consecutive_rto_count_; | 640 ++consecutive_rto_count_; |
| 630 } | 641 } |
| 642 |
| 643 if (network_change_visitor_ != NULL) { |
| 644 network_change_visitor_->OnCongestionWindowChange(GetCongestionWindow()); |
| 645 } |
| 631 } | 646 } |
| 632 | 647 |
| 633 QuicSentPacketManager::RetransmissionTimeoutMode | 648 QuicSentPacketManager::RetransmissionTimeoutMode |
| 634 QuicSentPacketManager::GetRetransmissionMode() const { | 649 QuicSentPacketManager::GetRetransmissionMode() const { |
| 635 DCHECK(unacked_packets_.HasInFlightPackets()); | 650 DCHECK(unacked_packets_.HasInFlightPackets()); |
| 636 if (unacked_packets_.HasPendingCryptoPackets()) { | 651 if (unacked_packets_.HasPendingCryptoPackets()) { |
| 637 return HANDSHAKE_MODE; | 652 return HANDSHAKE_MODE; |
| 638 } | 653 } |
| 639 if (loss_algorithm_->GetLossTimeout() != QuicTime::Zero()) { | 654 if (loss_algorithm_->GetLossTimeout() != QuicTime::Zero()) { |
| 640 return LOSS_MODE; | 655 return LOSS_MODE; |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 843 | 858 |
| 844 // Set up a pacing sender with a 5 millisecond alarm granularity. | 859 // Set up a pacing sender with a 5 millisecond alarm granularity. |
| 845 using_pacing_ = true; | 860 using_pacing_ = true; |
| 846 send_algorithm_.reset( | 861 send_algorithm_.reset( |
| 847 new PacingSender(send_algorithm_.release(), | 862 new PacingSender(send_algorithm_.release(), |
| 848 QuicTime::Delta::FromMilliseconds(5), | 863 QuicTime::Delta::FromMilliseconds(5), |
| 849 kInitialUnpacedBurst)); | 864 kInitialUnpacedBurst)); |
| 850 } | 865 } |
| 851 | 866 |
| 852 } // namespace net | 867 } // namespace net |
| OLD | NEW |