diff options
author | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-02 20:26:57 +0000 |
---|---|---|
committer | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-02 20:26:57 +0000 |
commit | 2adef90e3a8b95cbdb1c4bf720594035e19a80b1 (patch) | |
tree | 9334f0dc046c04732b7ed3589be124ec84bac6a5 /net/quic/congestion_control | |
parent | 48d4ae39a1e5423ff721b63bccdc994754c9df29 (diff) | |
download | chromium_src-2adef90e3a8b95cbdb1c4bf720594035e19a80b1.zip chromium_src-2adef90e3a8b95cbdb1c4bf720594035e19a80b1.tar.gz chromium_src-2adef90e3a8b95cbdb1c4bf720594035e19a80b1.tar.bz2 |
Land Recent QUIC Changes.
Change the defaults QuicConfig::server_initial_congestion_window to be
kDefaultInitialWindow, kDefaultInitialWindow instead of
kMaxInitialWindow, kDefaultInitialWindow. Move the logic for allowing a
larger max from SetDefaults to the quic_server and internal QUIC server.
Remove the logic for setting "safe" defaults from the client.
Merge internal change: 57382959
https://codereview.chromium.org/97433002/
QUIC refactor to merge the QuicCongestionManager and the
SentPacketManager.
Merge internal change: 57374920
https://codereview.chromium.org/96513003/
Rename ReliableQuicStream::Close to Reset to accurately reflect the
correct semantics.
Merge internal change: 57369140
https://codereview.chromium.org/97383003/
Removing QuicCongestionControlTest.
QuicCongestionControlTest only tested the fixed rate sender and
receiver, which already has a test in FixRateTest. Other functionality
is tested by the QuicCongestionManagerTest, so this is an orphan test.
Merge internal change: 57366308
https://codereview.chromium.org/97413002/
Remove confusing ReliableQuicStream::TerminateFromPeer method.
Merge internal change: 57325567
https://codereview.chromium.org/97403002/
R=rch@chromium.org
Review URL: https://codereview.chromium.org/97443002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@238169 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/quic/congestion_control')
4 files changed, 0 insertions, 1091 deletions
diff --git a/net/quic/congestion_control/quic_congestion_control_test.cc b/net/quic/congestion_control/quic_congestion_control_test.cc deleted file mode 100644 index a93263a..0000000 --- a/net/quic/congestion_control/quic_congestion_control_test.cc +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Test of the full congestion control chain. - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "net/quic/congestion_control/quic_congestion_manager.h" -#include "net/quic/quic_protocol.h" -#include "net/quic/test_tools/mock_clock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using std::max; - -namespace net { -namespace test { - -class QuicCongestionControlTest : public ::testing::Test { - protected: - QuicCongestionControlTest() - : start_(clock_.ApproximateNow()) { - } - - void SetUpCongestionType(CongestionFeedbackType congestion_type) { - manager_.reset(new QuicCongestionManager(&clock_, congestion_type)); - } - - MockClock clock_; - QuicTime start_; - scoped_ptr<QuicCongestionManager> manager_; -}; - -TEST_F(QuicCongestionControlTest, FixedRateSenderAPI) { - SetUpCongestionType(kFixRate); - QuicCongestionFeedbackFrame congestion_feedback; - congestion_feedback.type = kFixRate; - congestion_feedback.fix_rate.bitrate = QuicBandwidth::FromKBytesPerSecond(30); - manager_->OnIncomingQuicCongestionFeedbackFrame(congestion_feedback, - clock_.Now()); - EXPECT_TRUE(manager_->TimeUntilSend(clock_.Now(), - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); - manager_->OnPacketSent(1, clock_.Now(), kDefaultMaxPacketSize, - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); - EXPECT_EQ(QuicTime::Delta::FromMilliseconds(40), - manager_->TimeUntilSend(clock_.Now(), - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)); - clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(35)); - EXPECT_EQ(QuicTime::Delta::Infinite(), - manager_->TimeUntilSend(clock_.Now(), - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)); - clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5)); - EXPECT_EQ(QuicTime::Delta::Infinite(), - manager_->TimeUntilSend(clock_.Now(), - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)); -} - -TEST_F(QuicCongestionControlTest, FixedRatePacing) { - SetUpCongestionType(kFixRate); - QuicAckFrame ack; - ack.received_info.largest_observed = 0; - manager_->OnIncomingAckFrame(ack, clock_.Now()); - - QuicCongestionFeedbackFrame feedback; - feedback.type = kFixRate; - feedback.fix_rate.bitrate = QuicBandwidth::FromKBytesPerSecond(100); - manager_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); - - QuicTime acc_advance_time(QuicTime::Zero()); - for (QuicPacketSequenceNumber i = 1; i <= 100; ++i) { - EXPECT_TRUE(manager_->TimeUntilSend(clock_.Now(), - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); - manager_->OnPacketSent(i, clock_.Now(), kDefaultMaxPacketSize, - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); - QuicTime::Delta advance_time = manager_->TimeUntilSend(clock_.Now(), - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE); - clock_.AdvanceTime(advance_time); - acc_advance_time = acc_advance_time.Add(advance_time); - // Ack the packet we sent. - ack.received_info.largest_observed = max( - i, ack.received_info.largest_observed); - manager_->OnIncomingAckFrame(ack, clock_.Now()); - } - EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1200), - acc_advance_time.Subtract(start_)); -} - -TEST_F(QuicCongestionControlTest, Pacing) { - SetUpCongestionType(kFixRate); - QuicAckFrame ack; - ack.received_info.largest_observed = 0; - manager_->OnIncomingAckFrame(ack, clock_.Now()); - - QuicCongestionFeedbackFrame feedback; - feedback.type = kFixRate; - // Test a high bitrate (8Mbit/s) to trigger pacing. - feedback.fix_rate.bitrate = QuicBandwidth::FromKBytesPerSecond(1000); - manager_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); - - QuicTime acc_advance_time(QuicTime::Zero()); - for (QuicPacketSequenceNumber i = 1; i <= 100;) { - EXPECT_TRUE(manager_->TimeUntilSend(clock_.Now(), - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); - manager_->OnPacketSent(i++, clock_.Now(), kDefaultMaxPacketSize, - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); - EXPECT_TRUE(manager_->TimeUntilSend(clock_.Now(), - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); - manager_->OnPacketSent(i++, clock_.Now(), kDefaultMaxPacketSize, - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); - QuicTime::Delta advance_time = manager_->TimeUntilSend(clock_.Now(), - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE); - clock_.AdvanceTime(advance_time); - acc_advance_time = acc_advance_time.Add(advance_time); - // Ack the packets we sent. - ack.received_info.largest_observed = max( - i - 2, ack.received_info.largest_observed); - manager_->OnIncomingAckFrame(ack, clock_.Now()); - ack.received_info.largest_observed = max( - i - 1, ack.received_info.largest_observed); - manager_->OnIncomingAckFrame(ack, clock_.Now()); - } - EXPECT_EQ(QuicTime::Delta::FromMilliseconds(120), - acc_advance_time.Subtract(start_)); -} - -// TODO(pwestin): add TCP tests. - -// TODO(pwestin): add InterArrival tests. - -} // namespace test -} // namespace net diff --git a/net/quic/congestion_control/quic_congestion_manager.cc b/net/quic/congestion_control/quic_congestion_manager.cc deleted file mode 100644 index c97136a..0000000 --- a/net/quic/congestion_control/quic_congestion_manager.cc +++ /dev/null @@ -1,370 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/congestion_control/quic_congestion_manager.h" - -#include <algorithm> -#include <map> - -#include "base/stl_util.h" -#include "net/quic/congestion_control/pacing_sender.h" -#include "net/quic/congestion_control/receive_algorithm_interface.h" -#include "net/quic/congestion_control/send_algorithm_interface.h" -#include "net/quic/quic_protocol.h" - -using std::map; -using std::min; - -// A test-only flag to prevent the RTO from backing off when multiple sequential -// tail drops occur. -bool FLAGS_limit_rto_increase_for_tests = false; - -// Do not remove this flag until the Finch-trials described in b/11706275 -// are complete. -// If true, QUIC connections will support the use of a pacing algorithm when -// sending packets, in an attempt to reduce packet loss. The client must also -// request pacing for the server to enable it. -bool FLAGS_enable_quic_pacing = false; - -namespace net { -namespace { -static const int kBitrateSmoothingPeriodMs = 1000; -static const int kHistoryPeriodMs = 5000; - -static const int kDefaultRetransmissionTimeMs = 500; -// TCP RFC calls for 1 second RTO however Linux differs from this default and -// define the minimum RTO to 200ms, we will use the same until we have data to -// support a higher or lower value. -static const int kMinRetransmissionTimeMs = 200; -static const int kMaxRetransmissionTimeMs = 60000; -static const size_t kMaxRetransmissions = 10; - -// We want to make sure if we get a nack packet which triggers several -// retransmissions, we don't queue up too many packets. 10 is TCP's default -// initial congestion window(RFC 6928). -static const size_t kMaxRetransmissionsPerAck = kDefaultInitialWindow; - -// TCP retransmits after 3 nacks. -// TODO(ianswett): Change to match TCP's rule of retransmitting once an ack -// at least 3 sequence numbers larger arrives. -static const size_t kNumberOfNacksBeforeRetransmission = 3; - -COMPILE_ASSERT(kHistoryPeriodMs >= kBitrateSmoothingPeriodMs, - history_must_be_longer_or_equal_to_the_smoothing_period); -} // namespace - -QuicCongestionManager::QuicCongestionManager( - const QuicClock* clock, - CongestionFeedbackType congestion_type) - : clock_(clock), - send_algorithm_(SendAlgorithmInterface::Create(clock, congestion_type)), - rtt_sample_(QuicTime::Delta::Infinite()), - consecutive_rto_count_(0), - using_pacing_(false) { -} - -QuicCongestionManager::~QuicCongestionManager() { - STLDeleteValues(&packet_history_map_); -} - -void QuicCongestionManager::SetFromConfig(const QuicConfig& config, - bool is_server) { - if (config.initial_round_trip_time_us() > 0 && - rtt_sample_.IsInfinite()) { - // The initial rtt should already be set on the client side. - DVLOG_IF(1, !is_server) - << "Client did not set an initial RTT, but did negotiate one."; - rtt_sample_ = - QuicTime::Delta::FromMicroseconds(config.initial_round_trip_time_us()); - } - if (config.congestion_control() == kPACE) { - MaybeEnablePacing(); - } - send_algorithm_->SetFromConfig(config, is_server); -} - -void QuicCongestionManager::SetMaxPacketSize(QuicByteCount max_packet_size) { - send_algorithm_->SetMaxPacketSize(max_packet_size); -} - -void QuicCongestionManager::OnPacketSent( - QuicPacketSequenceNumber sequence_number, - QuicTime sent_time, - QuicByteCount bytes, - TransmissionType transmission_type, - HasRetransmittableData has_retransmittable_data) { - DCHECK_LT(0u, sequence_number); - DCHECK(!ContainsKey(pending_packets_, sequence_number)); - - // Only track packets the send algorithm wants us to track. - if (!send_algorithm_->OnPacketSent(sent_time, sequence_number, bytes, - transmission_type, - has_retransmittable_data)) { - return; - } - packet_history_map_[sequence_number] = new SendAlgorithmInterface::SentPacket( - bytes, sent_time, has_retransmittable_data); - pending_packets_.insert(sequence_number); - CleanupPacketHistory(); -} - -void QuicCongestionManager::OnRetransmissionTimeout() { - ++consecutive_rto_count_; - send_algorithm_->OnRetransmissionTimeout(); - // Abandon all pending packets to ensure the congestion window - // opens up before we attempt to retransmit packets. - for (SequenceNumberSet::const_iterator it = pending_packets_.begin(); - it != pending_packets_.end(); ++it) { - QuicPacketSequenceNumber sequence_number = *it; - DCHECK(ContainsKey(packet_history_map_, sequence_number)); - send_algorithm_->OnPacketAbandoned( - sequence_number, packet_history_map_[sequence_number]->bytes_sent()); - } - pending_packets_.clear(); -} - -void QuicCongestionManager::OnLeastUnackedIncreased() { - consecutive_rto_count_ = 0; -} - -void QuicCongestionManager::OnPacketAbandoned( - QuicPacketSequenceNumber sequence_number) { - SequenceNumberSet::iterator it = pending_packets_.find(sequence_number); - if (it != pending_packets_.end()) { - DCHECK(ContainsKey(packet_history_map_, sequence_number)); - send_algorithm_->OnPacketAbandoned( - sequence_number, packet_history_map_[sequence_number]->bytes_sent()); - pending_packets_.erase(it); - } -} - -void QuicCongestionManager::OnIncomingQuicCongestionFeedbackFrame( - const QuicCongestionFeedbackFrame& frame, QuicTime feedback_receive_time) { - send_algorithm_->OnIncomingQuicCongestionFeedbackFrame( - frame, feedback_receive_time, packet_history_map_); -} - -SequenceNumberSet QuicCongestionManager::OnIncomingAckFrame( - const QuicAckFrame& frame, - QuicTime ack_receive_time) { - // We calculate the RTT based on the highest ACKed sequence number, the lower - // sequence numbers will include the ACK aggregation delay. - SendAlgorithmInterface::SentPacketsMap::iterator history_it = - packet_history_map_.find(frame.received_info.largest_observed); - // TODO(satyamshekhar): largest_observed might be missing. - if (history_it != packet_history_map_.end()) { - QuicTime::Delta send_delta = ack_receive_time.Subtract( - history_it->second->send_timestamp()); - if (send_delta > frame.received_info.delta_time_largest_observed) { - rtt_sample_ = send_delta.Subtract( - frame.received_info.delta_time_largest_observed); - } else if (rtt_sample_.IsInfinite()) { - // Even though we received information from the peer suggesting - // an invalid (negative) RTT, we can use the send delta as an - // approximation until we get a better estimate. - rtt_sample_ = send_delta; - } - } - // We want to. - // * Get all packets lower(including) than largest_observed - // from pending_packets_. - // * Remove all missing packets. - // * Send each ACK in the list to send_algorithm_. - SequenceNumberSet::iterator it = pending_packets_.begin(); - SequenceNumberSet::iterator it_upper = - pending_packets_.upper_bound(frame.received_info.largest_observed); - - SequenceNumberSet retransmission_packets; - SequenceNumberSet lost_packets; - while (it != it_upper) { - QuicPacketSequenceNumber sequence_number = *it; - if (!IsAwaitingPacket(frame.received_info, sequence_number)) { - // Not missing, hence implicitly acked. - size_t bytes_sent = packet_history_map_[sequence_number]->bytes_sent(); - send_algorithm_->OnPacketAcked(sequence_number, bytes_sent, rtt_sample_); - pending_packets_.erase(it++); // Must be incremented post to work. - continue; - } - - // The peer got packets after this sequence number. This is an explicit - // nack. - DVLOG(1) << "still missing packet " << sequence_number; - DCHECK(ContainsKey(packet_history_map_, sequence_number)); - const SendAlgorithmInterface::SentPacket* sent_packet = - packet_history_map_[sequence_number]; - // Consider it multiple nacks when there is a gap between the missing packet - // and the largest observed, since the purpose of a nack threshold is to - // tolerate re-ordering. This handles both StretchAcks and Forward Acks. - // TODO(ianswett): This relies heavily on sequential reception of packets, - // and makes an assumption that the congestion control uses TCP style nacks. - size_t min_nacks = frame.received_info.largest_observed - sequence_number; - packet_history_map_[sequence_number]->Nack(min_nacks); - - size_t num_nacks_needed = kNumberOfNacksBeforeRetransmission; - // Check for early retransmit(RFC5827) when the last packet gets acked and - // the there are fewer than 4 pending packets. - if (pending_packets_.size() <= kNumberOfNacksBeforeRetransmission && - sent_packet->has_retransmittable_data() == HAS_RETRANSMITTABLE_DATA && - *pending_packets_.rbegin() == frame.received_info.largest_observed) { - num_nacks_needed = frame.received_info.largest_observed - sequence_number; - } - - if (sent_packet->nack_count() < num_nacks_needed) { - ++it; - continue; - } - - // If the number of retransmissions has maxed out, don't lose or retransmit - // any more packets. - if (retransmission_packets.size() >= kMaxRetransmissionsPerAck) { - ++it; - continue; - } - - lost_packets.insert(sequence_number); - if (sent_packet->has_retransmittable_data() == HAS_RETRANSMITTABLE_DATA) { - retransmission_packets.insert(sequence_number); - } - - ++it; - } - // Abandon packets after the loop over pending packets, because otherwise it - // changes the early retransmit logic and iteration. - for (SequenceNumberSet::const_iterator it = lost_packets.begin(); - it != lost_packets.end(); ++it) { - // TODO(ianswett): OnPacketLost is also called from TCPCubicSender when - // an FEC packet is lost, but FEC loss information should be shared among - // congestion managers. Additionally, if it's expected the FEC packet may - // repair the loss, it should be recorded as a loss to the congestion - // manager, but not retransmitted until it's known whether the FEC packet - // arrived. - send_algorithm_->OnPacketLost(*it, ack_receive_time); - OnPacketAbandoned(*it); - } - - return retransmission_packets; -} - -QuicTime::Delta QuicCongestionManager::TimeUntilSend( - QuicTime now, - TransmissionType transmission_type, - HasRetransmittableData retransmittable, - IsHandshake handshake) { - return send_algorithm_->TimeUntilSend(now, transmission_type, retransmittable, - handshake); -} - -const QuicTime::Delta QuicCongestionManager::DefaultRetransmissionTime() { - return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); -} - -// Ensures that the Delayed Ack timer is always set to a value lesser -// than the retransmission timer's minimum value (MinRTO). We want the -// delayed ack to get back to the QUIC peer before the sender's -// retransmission timer triggers. Since we do not know the -// reverse-path one-way delay, we assume equal delays for forward and -// reverse paths, and ensure that the timer is set to less than half -// of the MinRTO. -// There may be a value in making this delay adaptive with the help of -// the sender and a signaling mechanism -- if the sender uses a -// different MinRTO, we may get spurious retransmissions. May not have -// any benefits, but if the delayed ack becomes a significant source -// of (likely, tail) latency, then consider such a mechanism. - -const QuicTime::Delta QuicCongestionManager::DelayedAckTime() { - return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs/2); -} - -const QuicTime::Delta QuicCongestionManager::GetRetransmissionDelay() const { - size_t number_retransmissions = consecutive_rto_count_; - if (FLAGS_limit_rto_increase_for_tests) { - const size_t kTailDropWindowSize = 5; - const size_t kTailDropMaxRetransmissions = 4; - if (pending_packets_.size() <= kTailDropWindowSize) { - // Avoid exponential backoff of RTO when there are only a few packets - // outstanding. This helps avoid the situation where fake packet loss - // causes a packet and it's retransmission to be dropped causing - // test timouts. - if (number_retransmissions <= kTailDropMaxRetransmissions) { - number_retransmissions = 0; - } else { - number_retransmissions -= kTailDropMaxRetransmissions; - } - } - } - - QuicTime::Delta retransmission_delay = send_algorithm_->RetransmissionDelay(); - if (retransmission_delay.IsZero()) { - // We are in the initial state, use default timeout values. - retransmission_delay = - QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); - } - // Calculate exponential back off. - retransmission_delay = QuicTime::Delta::FromMilliseconds( - retransmission_delay.ToMilliseconds() * static_cast<size_t>( - (1 << min<size_t>(number_retransmissions, kMaxRetransmissions)))); - - // TODO(rch): This code should move to |send_algorithm_|. - if (retransmission_delay.ToMilliseconds() < kMinRetransmissionTimeMs) { - return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs); - } - if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) { - return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs); - } - return retransmission_delay; -} - -const QuicTime::Delta QuicCongestionManager::SmoothedRtt() const { - return send_algorithm_->SmoothedRtt(); -} - -QuicBandwidth QuicCongestionManager::BandwidthEstimate() const { - return send_algorithm_->BandwidthEstimate(); -} - -QuicByteCount QuicCongestionManager::GetCongestionWindow() const { - return send_algorithm_->GetCongestionWindow(); -} - -void QuicCongestionManager::SetCongestionWindow(QuicByteCount window) { - send_algorithm_->SetCongestionWindow(window); -} - -void QuicCongestionManager::CleanupPacketHistory() { - const QuicTime::Delta kHistoryPeriod = - QuicTime::Delta::FromMilliseconds(kHistoryPeriodMs); - QuicTime now = clock_->ApproximateNow(); - - SendAlgorithmInterface::SentPacketsMap::iterator history_it = - packet_history_map_.begin(); - for (; history_it != packet_history_map_.end(); ++history_it) { - if (now.Subtract(history_it->second->send_timestamp()) <= kHistoryPeriod) { - return; - } - // Don't remove packets which have not been acked. - if (ContainsKey(pending_packets_, history_it->first)) { - continue; - } - delete history_it->second; - packet_history_map_.erase(history_it); - history_it = packet_history_map_.begin(); - } -} - -void QuicCongestionManager::MaybeEnablePacing() { - if (!FLAGS_enable_quic_pacing) { - return; - } - - if (using_pacing_) { - return; - } - - using_pacing_ = true; - send_algorithm_.reset( - new PacingSender(send_algorithm_.release(), - QuicTime::Delta::FromMicroseconds(1))); -} - -} // namespace net diff --git a/net/quic/congestion_control/quic_congestion_manager.h b/net/quic/congestion_control/quic_congestion_manager.h deleted file mode 100644 index 42be9c2..0000000 --- a/net/quic/congestion_control/quic_congestion_manager.h +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// This is the interface from the QuicConnection into the QUIC -// congestion control code. It wraps the SendAlgorithmInterface and -// ReceiveAlgorithmInterface and provides a single interface -// for consumers. - -#ifndef NET_QUIC_CONGESTION_CONTROL_QUIC_CONGESTION_MANAGER_H_ -#define NET_QUIC_CONGESTION_CONTROL_QUIC_CONGESTION_MANAGER_H_ - -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "net/quic/congestion_control/send_algorithm_interface.h" -#include "net/quic/quic_bandwidth.h" -#include "net/quic/quic_protocol.h" - -NET_EXPORT_PRIVATE extern bool FLAGS_limit_rto_increase_for_tests; -NET_EXPORT_PRIVATE extern bool FLAGS_enable_quic_pacing; - -namespace net { - -namespace test { -class QuicConnectionPeer; -class QuicCongestionManagerPeer; -} // namespace test - -class QuicClock; -class ReceiveAlgorithmInterface; - -class NET_EXPORT_PRIVATE QuicCongestionManager { - public: - QuicCongestionManager(const QuicClock* clock, - CongestionFeedbackType congestion_type); - virtual ~QuicCongestionManager(); - - virtual void SetFromConfig(const QuicConfig& config, bool is_server); - - virtual void SetMaxPacketSize(QuicByteCount max_packet_size); - - // Called when we have received an ack frame from peer. - // Returns a set containing all the sequence numbers to be nack retransmitted - // as a result of the ack. - virtual SequenceNumberSet OnIncomingAckFrame(const QuicAckFrame& frame, - QuicTime ack_receive_time); - - // Called when a congestion feedback frame is received from peer. - virtual void OnIncomingQuicCongestionFeedbackFrame( - const QuicCongestionFeedbackFrame& frame, - QuicTime feedback_receive_time); - - // Called when we have sent bytes to the peer. This informs the manager both - // the number of bytes sent and if they were retransmitted. - virtual void OnPacketSent(QuicPacketSequenceNumber sequence_number, - QuicTime sent_time, - QuicByteCount bytes, - TransmissionType transmission_type, - HasRetransmittableData has_retransmittable_data); - - // Called when the retransmission timer expires. - virtual void OnRetransmissionTimeout(); - - // Called when the least unacked sequence number increases, indicating the - // consecutive rto count should be reset to 0. - virtual void OnLeastUnackedIncreased(); - - // Called when a packet is timed out, such as an RTO. Removes the bytes from - // the congestion manager, but does not change the congestion window size. - virtual void OnPacketAbandoned(QuicPacketSequenceNumber sequence_number); - - // Calculate the time until we can send the next packet to the wire. - // Note 1: When kUnknownWaitTime is returned, there is no need to poll - // TimeUntilSend again until we receive an OnIncomingAckFrame event. - // Note 2: Send algorithms may or may not use |retransmit| in their - // calculations. - virtual QuicTime::Delta TimeUntilSend(QuicTime now, - TransmissionType transmission_type, - HasRetransmittableData retransmittable, - IsHandshake handshake); - - const QuicTime::Delta DefaultRetransmissionTime(); - - // Returns amount of time for delayed ack timer. - const QuicTime::Delta DelayedAckTime(); - - // Returns the current RTO delay. - const QuicTime::Delta GetRetransmissionDelay() const; - - // Returns the estimated smoothed RTT calculated by the congestion algorithm. - const QuicTime::Delta SmoothedRtt() const; - - // Returns the estimated bandwidth calculated by the congestion algorithm. - QuicBandwidth BandwidthEstimate() const; - - // Returns the size of the current congestion window in bytes. Note, this is - // not the *available* window. Some send algorithms may not use a congestion - // window and will return 0. - QuicByteCount GetCongestionWindow() const; - - // Sets the value of the current congestion window to |window|. - void SetCongestionWindow(QuicByteCount window); - - // Enables pacing if it has not already been enabled, and if - // FLAGS_enable_quic_pacing is set. - void MaybeEnablePacing(); - - bool using_pacing() const { return using_pacing_; } - - private: - friend class test::QuicConnectionPeer; - friend class test::QuicCongestionManagerPeer; - - void CleanupPacketHistory(); - - const QuicClock* clock_; - scoped_ptr<SendAlgorithmInterface> send_algorithm_; - // Tracks the send time, size, and nack count of sent packets. Packets are - // removed after 5 seconds and they've been removed from pending_packets_. - SendAlgorithmInterface::SentPacketsMap packet_history_map_; - // Packets that are outstanding and have not been abandoned or lost. - SequenceNumberSet pending_packets_; - QuicPacketSequenceNumber largest_missing_; - QuicTime::Delta rtt_sample_; // RTT estimate from the most recent ACK. - // Number of times the RTO timer has fired in a row without receiving an ack. - size_t consecutive_rto_count_; - bool using_pacing_; - - DISALLOW_COPY_AND_ASSIGN(QuicCongestionManager); -}; - -} // namespace net - -#endif // NET_QUIC_CONGESTION_CONTROL_QUIC_CONGESTION_MANAGER_H_ diff --git a/net/quic/congestion_control/quic_congestion_manager_test.cc b/net/quic/congestion_control/quic_congestion_manager_test.cc deleted file mode 100644 index 4130935..0000000 --- a/net/quic/congestion_control/quic_congestion_manager_test.cc +++ /dev/null @@ -1,456 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/congestion_control/quic_congestion_manager.h" - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "net/quic/congestion_control/inter_arrival_sender.h" -#include "net/quic/quic_protocol.h" -#include "net/quic/test_tools/mock_clock.h" -#include "net/quic/test_tools/quic_test_utils.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using testing::_; -using testing::StrictMock; -using testing::Return; - -namespace net { -namespace test { - -class QuicCongestionManagerPeer : public QuicCongestionManager { - public: - explicit QuicCongestionManagerPeer(const QuicClock* clock, - CongestionFeedbackType congestion_type) - : QuicCongestionManager(clock, congestion_type) { - } - void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) { - this->send_algorithm_.reset(send_algorithm); - } - - QuicTime::Delta rtt() { - return rtt_sample_; - } - - size_t GetNackCount(QuicPacketSequenceNumber sequence_number) const { - return packet_history_map_.find(sequence_number)->second->nack_count(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(QuicCongestionManagerPeer); -}; - -class QuicCongestionManagerTest : public ::testing::Test { - protected: - QuicCongestionManagerTest() - : manager_(&clock_, kFixRate), - send_algorithm_(new StrictMock<MockSendAlgorithm>) { - manager_.SetSendAlgorithm(send_algorithm_); - } - - static const HasRetransmittableData kIgnored = HAS_RETRANSMITTABLE_DATA; - - MockClock clock_; - QuicCongestionManagerPeer manager_; - MockSendAlgorithm* send_algorithm_; -}; - -TEST_F(QuicCongestionManagerTest, NackRetransmit1Packet) { - const size_t kNumSentPackets = 4; - // Transmit 4 packets. - for (size_t i = 1; i <= kNumSentPackets; ++i) { - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) - .Times(1).WillOnce(Return(true)); - manager_.OnPacketSent(i, clock_.Now(), 1000, - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); - } - - // Nack the first packet 3 times with increasing largest observed. - QuicAckFrame ack; - ack.received_info.delta_time_largest_observed = - QuicTime::Delta::FromMilliseconds(5); - ack.received_info.missing_packets.insert(1); - for (size_t i = 1; i <= 3; ++i) { - ack.received_info.largest_observed = i + 1; - EXPECT_CALL(*send_algorithm_, OnPacketAcked(i + 1, _, _)).Times(1); - if (i == 3) { - EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _)).Times(1); - EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1); - } - SequenceNumberSet retransmissions = - manager_.OnIncomingAckFrame(ack, clock_.Now()); - EXPECT_EQ(i == 3 ? 1u : 0u, retransmissions.size()); - EXPECT_EQ(i, manager_.GetNackCount(1)); - } -} - -// A stretch ack is an ack that covers more than 1 packet of previously -// unacknowledged data. -TEST_F(QuicCongestionManagerTest, NackRetransmit1PacketWith1StretchAck) { - const size_t kNumSentPackets = 4; - // Transmit 4 packets. - for (size_t i = 1; i <= kNumSentPackets; ++i) { - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) - .Times(1).WillOnce(Return(true)); - manager_.OnPacketSent(i, clock_.Now(), 1000, - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); - } - - // Nack the first packet 3 times in a single StretchAck. - QuicAckFrame ack; - ack.received_info.delta_time_largest_observed = - QuicTime::Delta::FromMilliseconds(5); - ack.received_info.missing_packets.insert(1); - ack.received_info.largest_observed = kNumSentPackets; - EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(3); - EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _)).Times(1); - EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1); - SequenceNumberSet retransmissions = - manager_.OnIncomingAckFrame(ack, clock_.Now()); - EXPECT_EQ(1u, retransmissions.size()); - EXPECT_EQ(3u, manager_.GetNackCount(1)); -} - -// Ack a packet 3 packets ahead, causing a retransmit. -TEST_F(QuicCongestionManagerTest, NackRetransmit1PacketSingleAck) { - const size_t kNumSentPackets = 4; - // Transmit 4 packets. - for (size_t i = 1; i <= kNumSentPackets; ++i) { - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) - .Times(1).WillOnce(Return(true)); - manager_.OnPacketSent(i, clock_.Now(), 1000, - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); - } - - // Nack the first packet 3 times in an AckFrame with three missing packets. - QuicAckFrame ack; - ack.received_info.delta_time_largest_observed = - QuicTime::Delta::FromMilliseconds(5); - ack.received_info.missing_packets.insert(1); - ack.received_info.missing_packets.insert(2); - ack.received_info.missing_packets.insert(3); - ack.received_info.largest_observed = kNumSentPackets; - EXPECT_CALL(*send_algorithm_, OnPacketAcked(kNumSentPackets, _, _)).Times(1); - EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _)).Times(1); - EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1); - SequenceNumberSet retransmissions = - manager_.OnIncomingAckFrame(ack, clock_.Now()); - EXPECT_EQ(1u, retransmissions.size()); - EXPECT_EQ(3u, manager_.GetNackCount(1)); -} - -TEST_F(QuicCongestionManagerTest, EarlyRetransmit1Packet) { - const size_t kNumSentPackets = 2; - // Transmit 2 packets. - for (size_t i = 1; i <= kNumSentPackets; ++i) { - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) - .Times(1).WillOnce(Return(true)); - manager_.OnPacketSent(i, clock_.Now(), 1000, - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); - } - - // Early retransmit when the final packet gets acked and the first is nacked. - QuicAckFrame ack; - ack.received_info.delta_time_largest_observed = - QuicTime::Delta::FromMilliseconds(5); - ack.received_info.missing_packets.insert(1); - ack.received_info.largest_observed = kNumSentPackets; - EXPECT_CALL(*send_algorithm_, OnPacketAcked(kNumSentPackets, _, _)).Times(1); - EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _)).Times(1); - EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1); - SequenceNumberSet retransmissions = - manager_.OnIncomingAckFrame(ack, clock_.Now()); - EXPECT_EQ(1u, retransmissions.size()); - EXPECT_EQ(1u, manager_.GetNackCount(1)); -} - -TEST_F(QuicCongestionManagerTest, DontEarlyRetransmitPacket) { - const size_t kNumSentPackets = 4; - for (size_t i = 1; i <= kNumSentPackets; ++i) { - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) - .Times(1).WillOnce(Return(true)); - manager_.OnPacketSent(i, clock_.Now(), 1000, - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); - } - - // Fast retransmit when the final packet gets acked, but don't early - // retransmit as well, because there are 4 packets outstanding when the ack - // arrives. - QuicAckFrame ack; - ack.received_info.delta_time_largest_observed = - QuicTime::Delta::FromMilliseconds(5); - ack.received_info.missing_packets.insert(1); - ack.received_info.missing_packets.insert(2); - ack.received_info.missing_packets.insert(3); - ack.received_info.largest_observed = kNumSentPackets; - EXPECT_CALL(*send_algorithm_, OnPacketAcked(kNumSentPackets, _, _)).Times(1); - EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _)).Times(1); - EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1); - SequenceNumberSet retransmissions = - manager_.OnIncomingAckFrame(ack, clock_.Now()); - EXPECT_EQ(1u, retransmissions.size()); - EXPECT_EQ(3u, manager_.GetNackCount(1)); -} - -TEST_F(QuicCongestionManagerTest, NackRetransmit10Packets) { - const size_t kNumSentPackets = 20; - // Transmit 20 packets. - for (QuicPacketSequenceNumber i = 1; i <= kNumSentPackets; ++i) { - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) - .Times(1).WillOnce(Return(true)); - manager_.OnPacketSent(i, clock_.Now(), 1000, - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); - } - - // Nack the first 19 packets 3 times. - QuicAckFrame ack; - ack.received_info.largest_observed = kNumSentPackets; - ack.received_info.delta_time_largest_observed = - QuicTime::Delta::FromMilliseconds(5); - for (size_t i = 1; i < kNumSentPackets; ++i) { - ack.received_info.missing_packets.insert(i); - } - EXPECT_CALL(*send_algorithm_, - OnPacketAcked(kNumSentPackets, _, _)).Times(1); - EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(10); - EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(10); - SequenceNumberSet retransmissions = - manager_.OnIncomingAckFrame(ack, clock_.Now()); - EXPECT_EQ(10u, retransmissions.size()); - for (size_t j = 1; j < kNumSentPackets; ++j) { - EXPECT_EQ(kNumSentPackets - j, manager_.GetNackCount(j)); - } -} - -TEST_F(QuicCongestionManagerTest, NackRetransmit10PacketsAlternateAcks) { - const size_t kNumSentPackets = 30; - // Transmit 15 packets of data and 15 ack packets. The send algorithm will - // inform the congestion manager not to save the acks by returning false. - for (QuicPacketSequenceNumber i = 1; i <= kNumSentPackets; ++i) { - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) - .Times(1).WillOnce(Return(i % 2 == 0 ? false : true)); - manager_.OnPacketSent( - i, clock_.Now(), 1000, NOT_RETRANSMISSION, - i % 2 == 0 ? NO_RETRANSMITTABLE_DATA : HAS_RETRANSMITTABLE_DATA); - } - - // Nack the first 29 packets 3 times. - QuicAckFrame ack; - ack.received_info.largest_observed = kNumSentPackets; - ack.received_info.delta_time_largest_observed = - QuicTime::Delta::FromMilliseconds(5); - for (size_t i = 1; i < kNumSentPackets; ++i) { - ack.received_info.missing_packets.insert(i); - } - // We never actually get an ack call, since the kNumSentPackets packet was - // not saved. - EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(10); - EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(10); - SequenceNumberSet retransmissions = - manager_.OnIncomingAckFrame(ack, clock_.Now()); - EXPECT_EQ(10u, retransmissions.size()); - // Only non-ack packets have a nack count. - for (size_t j = 1; j < kNumSentPackets; j += 2) { - EXPECT_EQ(kNumSentPackets - j, manager_.GetNackCount(j)); - } - - // Ensure only the odd packets were retransmitted, since the others were not - // retransmittable(ie: acks). - for (SequenceNumberSet::const_iterator it = retransmissions.begin(); - it != retransmissions.end(); ++it) { - EXPECT_EQ(1u, *it % 2); - } -} - -TEST_F(QuicCongestionManagerTest, NackTwiceThenAck) { - // Transmit 4 packets. - for (QuicPacketSequenceNumber i = 1; i <= 4; ++i) { - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) - .Times(1).WillOnce(Return(true)); - manager_.OnPacketSent(i, clock_.Now(), 1000, - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); - } - - // Nack the first packet 2 times, then ack it. - QuicAckFrame ack; - ack.received_info.missing_packets.insert(1); - for (size_t i = 1; i <= 3; ++i) { - if (i == 3) { - ack.received_info.missing_packets.clear(); - } - ack.received_info.largest_observed = i + 1; - ack.received_info.delta_time_largest_observed = - QuicTime::Delta::FromMilliseconds(5); - EXPECT_CALL(*send_algorithm_, - OnPacketAcked(_, _, _)).Times(i == 3 ? 2 : 1); - SequenceNumberSet retransmissions = - manager_.OnIncomingAckFrame(ack, clock_.Now()); - EXPECT_EQ(0u, retransmissions.size()); - // The nack count remains at 2 when the packet is acked. - EXPECT_EQ(i == 3 ? 2u : i, manager_.GetNackCount(1)); - } -} - -TEST_F(QuicCongestionManagerTest, Rtt) { - QuicPacketSequenceNumber sequence_number = 1; - QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(15); - - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) - .Times(1).WillOnce(Return(true)); - EXPECT_CALL(*send_algorithm_, - OnPacketAcked(sequence_number, _, expected_rtt)).Times(1); - - manager_.OnPacketSent(sequence_number, clock_.Now(), 1000, - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); - clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20)); - - QuicAckFrame ack; - ack.received_info.largest_observed = sequence_number; - ack.received_info.delta_time_largest_observed = - QuicTime::Delta::FromMilliseconds(5); - manager_.OnIncomingAckFrame(ack, clock_.Now()); - EXPECT_EQ(manager_.rtt(), expected_rtt); -} - -TEST_F(QuicCongestionManagerTest, RttWithInvalidDelta) { - // Expect that the RTT is equal to the local time elapsed, since the - // delta_time_largest_observed is larger than the local time elapsed - // and is hence invalid. - QuicPacketSequenceNumber sequence_number = 1; - QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10); - - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) - .Times(1).WillOnce(Return(true)); - EXPECT_CALL(*send_algorithm_, - OnPacketAcked(sequence_number, _, expected_rtt)).Times(1); - - manager_.OnPacketSent(sequence_number, clock_.Now(), 1000, - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); - clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10)); - - QuicAckFrame ack; - ack.received_info.largest_observed = sequence_number; - ack.received_info.delta_time_largest_observed = - QuicTime::Delta::FromMilliseconds(11); - manager_.OnIncomingAckFrame(ack, clock_.Now()); - EXPECT_EQ(manager_.rtt(), expected_rtt); -} - -TEST_F(QuicCongestionManagerTest, RttWithInfiniteDelta) { - // Expect that the RTT is equal to the local time elapsed, since the - // delta_time_largest_observed is infinite, and is hence invalid. - QuicPacketSequenceNumber sequence_number = 1; - QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10); - - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) - .Times(1).WillOnce(Return(true)); - EXPECT_CALL(*send_algorithm_, - OnPacketAcked(sequence_number, _, expected_rtt)).Times(1); - - manager_.OnPacketSent(sequence_number, clock_.Now(), 1000, - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); - clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10)); - - QuicAckFrame ack; - ack.received_info.largest_observed = sequence_number; - ack.received_info.delta_time_largest_observed = QuicTime::Delta::Infinite(); - manager_.OnIncomingAckFrame(ack, clock_.Now()); - EXPECT_EQ(manager_.rtt(), expected_rtt); -} - -TEST_F(QuicCongestionManagerTest, RttZeroDelta) { - // Expect that the RTT is the time between send and receive since the - // delta_time_largest_observed is zero. - QuicPacketSequenceNumber sequence_number = 1; - QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10); - - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) - .Times(1).WillOnce(Return(true)); - EXPECT_CALL(*send_algorithm_, OnPacketAcked(sequence_number, _, expected_rtt)) - .Times(1); - - manager_.OnPacketSent(sequence_number, clock_.Now(), 1000, - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); - clock_.AdvanceTime(expected_rtt); - - QuicAckFrame ack; - ack.received_info.largest_observed = sequence_number; - ack.received_info.delta_time_largest_observed = QuicTime::Delta::Zero(); - manager_.OnIncomingAckFrame(ack, clock_.Now()); - EXPECT_EQ(manager_.rtt(), expected_rtt); -} - -TEST_F(QuicCongestionManagerTest, RetransmissionTimeout) { - // Send 100 packets and then ensure all are abandoned when the RTO fires. - const size_t kNumSentPackets = 100; - for (size_t i = 1; i <= kNumSentPackets; ++i) { - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) - .Times(1).WillOnce(Return(true)); - manager_.OnPacketSent(i, clock_.Now(), 1000, - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); - } - - EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout()); - EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(kNumSentPackets); - - manager_.OnRetransmissionTimeout(); -} - -TEST_F(QuicCongestionManagerTest, GetTransmissionDelayMin) { - EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout()); - QuicTime::Delta delay = QuicTime::Delta::FromMilliseconds(1); - EXPECT_CALL(*send_algorithm_, RetransmissionDelay()) - .WillOnce(Return(delay)); - - manager_.OnRetransmissionTimeout(); - EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), - manager_.GetRetransmissionDelay()); -} - -TEST_F(QuicCongestionManagerTest, GetTransmissionDelayMax) { - EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout()); - QuicTime::Delta delay = QuicTime::Delta::FromSeconds(500); - EXPECT_CALL(*send_algorithm_, RetransmissionDelay()) - .WillOnce(Return(delay)); - - manager_.OnRetransmissionTimeout(); - EXPECT_EQ(QuicTime::Delta::FromSeconds(60), - manager_.GetRetransmissionDelay()); -} - -TEST_F(QuicCongestionManagerTest, GetTransmissionDelay) { - QuicTime::Delta delay = QuicTime::Delta::FromMilliseconds(500); - EXPECT_CALL(*send_algorithm_, RetransmissionDelay()) - .WillRepeatedly(Return(delay)); - - // Delay should back off exponentially. - for (int i = 0; i < 5; ++i) { - EXPECT_EQ(delay, manager_.GetRetransmissionDelay()); - delay = delay.Add(delay); - EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout()); - manager_.OnRetransmissionTimeout(); - } -} - -TEST_F(QuicCongestionManagerTest, GetTestTransmissionDelayTailDrop) { - FLAGS_limit_rto_increase_for_tests = true; - - QuicTime::Delta delay = QuicTime::Delta::FromMilliseconds(500); - EXPECT_CALL(*send_algorithm_, RetransmissionDelay()) - .WillRepeatedly(Return(delay)); - - // No backoff for the first 5 retransmissions. - for (int i = 0; i < 5; ++i) { - EXPECT_EQ(delay, manager_.GetRetransmissionDelay()); - EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout()); - manager_.OnRetransmissionTimeout(); - } - - // Then backoff starts. - EXPECT_EQ(delay.Add(delay), manager_.GetRetransmissionDelay()); -} - -} // namespace test -} // namespace net |