diff options
author | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-09 07:16:30 +0000 |
---|---|---|
committer | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-09 07:16:30 +0000 |
commit | ef0da58240cefeb25ddb44a94fb1fe8099b6f7ea (patch) | |
tree | 53a339d6f13e722e34ef7403900611f78cbeecc9 /net/quic | |
parent | cfe2f5bd6e2b7c8f21b2eade97f6c3f804bd3de4 (diff) | |
download | chromium_src-ef0da58240cefeb25ddb44a94fb1fe8099b6f7ea.zip chromium_src-ef0da58240cefeb25ddb44a94fb1fe8099b6f7ea.tar.gz chromium_src-ef0da58240cefeb25ddb44a94fb1fe8099b6f7ea.tar.bz2 |
Land Recent QUIC Changes.
Fix a bug where if a crypto packet is spuriously retransmitted and then
neutered, it remains in missing_packets until the end of the connection.
Merge internal change: 66262890
https://codereview.chromium.org/270213002/
Minor QUIC cleanup to combine QuicUnackedPacketMap's RemovePacket and
NeuterPacket into RemoveOrNeuterPacket.
This prevents potential bugs where a packet can be set not pending, then
neuter'd, which cuases the packet to never be removed from the unacked
packet map.
Merge internal change: 66306887
https://codereview.chromium.org/271443008/
Change QUIC's slow start CWND increase to match recent TCP improvements
to tweak the algorithm for IsCwndLimited.
Merge internal change: 66256837
https://codereview.chromium.org/261423003/
Re-add the PacingSenderTests accidentally removed in cr/65742790
Merge internal change: 66156383
https://codereview.chromium.org/269953009/
Simple cleanup to combine HandleAckForSentPackets and
MaybeRetransmitOnAckFrame into one method.
Merge internal change: 66155839
https://codereview.chromium.org/269213005/
Cleanup: Remove redundant string conversions.
Merge internal change: 66108555
https://codereview.chromium.org/268643008/
Add bytes_in_flight to QUIC's OnPacketSent for the BBR implementation.
Merge internal change: 66091843
https://codereview.chromium.org/269233005/
Minor cleanup to TcpCubicSender now that OnCongestionEvent contains all
the relevent congestion information in one call.
Merge internal change: 66086997
https://codereview.chromium.org/273463002/
R=rch@chromium.org
Review URL: https://codereview.chromium.org/267293003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269186 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/quic')
27 files changed, 289 insertions, 274 deletions
diff --git a/net/quic/congestion_control/fix_rate_sender.cc b/net/quic/congestion_control/fix_rate_sender.cc index d7051b7..8027205 100644 --- a/net/quic/congestion_control/fix_rate_sender.cc +++ b/net/quic/congestion_control/fix_rate_sender.cc @@ -58,6 +58,7 @@ void FixRateSender::OnCongestionEvent(bool rtt_updated, bool FixRateSender::OnPacketSent( QuicTime sent_time, + QuicByteCount /*bytes_in_flight*/, QuicPacketSequenceNumber /*sequence_number*/, QuicByteCount bytes, HasRetransmittableData /*has_retransmittable_data*/) { diff --git a/net/quic/congestion_control/fix_rate_sender.h b/net/quic/congestion_control/fix_rate_sender.h index 5a64d99..6f85090 100644 --- a/net/quic/congestion_control/fix_rate_sender.h +++ b/net/quic/congestion_control/fix_rate_sender.h @@ -37,6 +37,7 @@ class NET_EXPORT_PRIVATE FixRateSender : public SendAlgorithmInterface { const CongestionMap& lost_packets) OVERRIDE; virtual bool OnPacketSent( QuicTime sent_time, + QuicByteCount bytes_in_flight, QuicPacketSequenceNumber sequence_number, QuicByteCount bytes, HasRetransmittableData has_retransmittable_data) OVERRIDE; diff --git a/net/quic/congestion_control/fix_rate_test.cc b/net/quic/congestion_control/fix_rate_test.cc index 14e1421..e696823 100644 --- a/net/quic/congestion_control/fix_rate_test.cc +++ b/net/quic/congestion_control/fix_rate_test.cc @@ -17,6 +17,9 @@ namespace net { namespace test { +// bytes_in_flight is unused by FixRateSender's OnPacketSent. +QuicByteCount kUnused = 0; + class FixRateReceiverPeer : public FixRateReceiver { public: FixRateReceiverPeer() @@ -63,14 +66,14 @@ TEST_F(FixRateTest, SenderAPI) { 0, HAS_RETRANSMITTABLE_DATA).IsZero()); - sender_->OnPacketSent(clock_.Now(), 1, kDefaultMaxPacketSize, + sender_->OnPacketSent(clock_.Now(), kUnused, 1, kDefaultMaxPacketSize, HAS_RETRANSMITTABLE_DATA); EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), kDefaultMaxPacketSize, HAS_RETRANSMITTABLE_DATA).IsZero()); - sender_->OnPacketSent(clock_.Now(), 2, kDefaultMaxPacketSize, + sender_->OnPacketSent(clock_.Now(), kUnused, 2, kDefaultMaxPacketSize, HAS_RETRANSMITTABLE_DATA); - sender_->OnPacketSent(clock_.Now(), 3, 600, + sender_->OnPacketSent(clock_.Now(), kUnused, 3, 600, HAS_RETRANSMITTABLE_DATA); EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), sender_->TimeUntilSend(clock_.Now(), @@ -101,12 +104,12 @@ TEST_F(FixRateTest, FixRatePacing) { EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA).IsZero()); - sender_->OnPacketSent(clock_.Now(), sequence_number++, packet_size, + sender_->OnPacketSent(clock_.Now(), kUnused, sequence_number++, packet_size, HAS_RETRANSMITTABLE_DATA); EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), kDefaultMaxPacketSize, HAS_RETRANSMITTABLE_DATA).IsZero()); - sender_->OnPacketSent(clock_.Now(), sequence_number++, packet_size, + sender_->OnPacketSent(clock_.Now(), kUnused, sequence_number++, packet_size, HAS_RETRANSMITTABLE_DATA); QuicTime::Delta advance_time = sender_->TimeUntilSend(clock_.Now(), diff --git a/net/quic/congestion_control/pacing_sender.cc b/net/quic/congestion_control/pacing_sender.cc index 5193c75..c487d2a 100644 --- a/net/quic/congestion_control/pacing_sender.cc +++ b/net/quic/congestion_control/pacing_sender.cc @@ -41,6 +41,7 @@ void PacingSender::OnCongestionEvent(bool rtt_updated, bool PacingSender::OnPacketSent( QuicTime sent_time, + QuicByteCount bytes_in_flight, QuicPacketSequenceNumber sequence_number, QuicByteCount bytes, HasRetransmittableData has_retransmittable_data) { @@ -55,8 +56,8 @@ bool PacingSender::OnPacketSent( BandwidthEstimate().Scale(kPacingAggression).TransferTime(bytes); next_packet_send_time_ = next_packet_send_time_.Add(delay); } - return sender_->OnPacketSent(sent_time, sequence_number, bytes, - has_retransmittable_data); + return sender_->OnPacketSent(sent_time, bytes_in_flight, sequence_number, + bytes, has_retransmittable_data); } void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted) { diff --git a/net/quic/congestion_control/pacing_sender.h b/net/quic/congestion_control/pacing_sender.h index 718bcc4..b1060ac 100644 --- a/net/quic/congestion_control/pacing_sender.h +++ b/net/quic/congestion_control/pacing_sender.h @@ -39,6 +39,7 @@ class NET_EXPORT_PRIVATE PacingSender : public SendAlgorithmInterface { const CongestionMap& acked_packets, const CongestionMap& lost_packets) OVERRIDE; virtual bool OnPacketSent(QuicTime sent_time, + QuicByteCount bytes_in_flight, QuicPacketSequenceNumber sequence_number, QuicByteCount bytes, HasRetransmittableData is_retransmittable) OVERRIDE; diff --git a/net/quic/congestion_control/pacing_sender_test.cc b/net/quic/congestion_control/pacing_sender_test.cc index e883365..38e5d02 100644 --- a/net/quic/congestion_control/pacing_sender_test.cc +++ b/net/quic/congestion_control/pacing_sender_test.cc @@ -50,34 +50,33 @@ class PacingSenderTest : public ::testing::Test { // Actually send the packet. EXPECT_CALL(*mock_sender_, - OnPacketSent(clock_.Now(), sequence_number_, kMaxPacketSize, - HAS_RETRANSMITTABLE_DATA)); - pacing_sender_->OnPacketSent(clock_.Now(), sequence_number_++, - kMaxPacketSize, HAS_RETRANSMITTABLE_DATA); + OnPacketSent(clock_.Now(), kBytesInFlight, sequence_number_, + kMaxPacketSize, HAS_RETRANSMITTABLE_DATA)); + pacing_sender_->OnPacketSent(clock_.Now(), kBytesInFlight, + sequence_number_++, kMaxPacketSize, + HAS_RETRANSMITTABLE_DATA); } void CheckAckIsSentImmediately() { // In order for the ack to be sendable, the underlying sender must // permit it to be sent immediately. EXPECT_CALL(*mock_sender_, TimeUntilSend(clock_.Now(), - kBytesInFlight, + 0, NO_RETRANSMITTABLE_DATA)) .WillOnce(Return(zero_time_)); - LOG(ERROR) << __LINE__; // Verify that the ACK can be sent immediately. EXPECT_EQ(zero_time_, pacing_sender_->TimeUntilSend(clock_.Now(), - kBytesInFlight, + 0, NO_RETRANSMITTABLE_DATA)); - LOG(ERROR) << __LINE__; // Actually send the packet. EXPECT_CALL(*mock_sender_, - OnPacketSent(clock_.Now(), sequence_number_, kMaxPacketSize, - NO_RETRANSMITTABLE_DATA)); - LOG(ERROR) << __LINE__; - pacing_sender_->OnPacketSent(clock_.Now(), sequence_number_++, - kMaxPacketSize, NO_RETRANSMITTABLE_DATA); + OnPacketSent(clock_.Now(), 0, sequence_number_, + kMaxPacketSize, NO_RETRANSMITTABLE_DATA)); + pacing_sender_->OnPacketSent(clock_.Now(), 0, + sequence_number_++, kMaxPacketSize, + NO_RETRANSMITTABLE_DATA); } void CheckPacketIsDelayed(QuicTime::Delta delay) { diff --git a/net/quic/congestion_control/send_algorithm_interface.h b/net/quic/congestion_control/send_algorithm_interface.h index 330037c..8412a043 100644 --- a/net/quic/congestion_control/send_algorithm_interface.h +++ b/net/quic/congestion_control/send_algorithm_interface.h @@ -57,6 +57,7 @@ class NET_EXPORT_PRIVATE SendAlgorithmInterface { // that do not count outgoing ACK packets against the congestion window. // Note: this function must be called for every packet sent to the wire. virtual bool OnPacketSent(QuicTime sent_time, + QuicByteCount bytes_in_flight, QuicPacketSequenceNumber sequence_number, QuicByteCount bytes, HasRetransmittableData is_retransmittable) = 0; diff --git a/net/quic/congestion_control/tcp_cubic_sender.cc b/net/quic/congestion_control/tcp_cubic_sender.cc index eabcd2d..aaec6a4 100644 --- a/net/quic/congestion_control/tcp_cubic_sender.cc +++ b/net/quic/congestion_control/tcp_cubic_sender.cc @@ -78,8 +78,11 @@ void TcpCubicSender::OnCongestionEvent( QuicByteCount bytes_in_flight, const CongestionMap& acked_packets, const CongestionMap& lost_packets) { - if (rtt_updated) { - OnRttUpdated(); + if (rtt_updated && InSlowStart() && + hybrid_slow_start_.ShouldExitSlowStart(rtt_stats_->latest_rtt(), + rtt_stats_->min_rtt(), + congestion_window_)) { + slowstart_threshold_ = congestion_window_; } for (CongestionMap::const_iterator it = lost_packets.begin(); it != lost_packets.end(); ++it) { @@ -125,9 +128,6 @@ void TcpCubicSender::OnPacketLost(QuicPacketSequenceNumber sequence_number, } PrrOnPacketLost(bytes_in_flight); - // In a normal TCP we would need to know the lowest missing packet to detect - // if we receive 3 missing packets. Here we get a missing packet for which we - // enter TCP Fast Retransmit immediately. if (reno_) { congestion_window_ = congestion_window_ >> 1; } else { @@ -135,7 +135,7 @@ void TcpCubicSender::OnPacketLost(QuicPacketSequenceNumber sequence_number, cubic_.CongestionWindowAfterPacketLoss(congestion_window_); } slowstart_threshold_ = congestion_window_; - // Enforce TCP's minimimum congestion window of 2*MSS. + // Enforce TCP's minimum congestion window of 2*MSS. if (congestion_window_ < kMinimumCongestionWindow) { congestion_window_ = kMinimumCongestionWindow; } @@ -148,6 +148,7 @@ void TcpCubicSender::OnPacketLost(QuicPacketSequenceNumber sequence_number, } bool TcpCubicSender::OnPacketSent(QuicTime /*sent_time*/, + QuicByteCount /*bytes_in_flight*/, QuicPacketSequenceNumber sequence_number, QuicByteCount bytes, HasRetransmittableData is_retransmittable) { @@ -172,27 +173,17 @@ QuicTime::Delta TcpCubicSender::TimeUntilSend( HasRetransmittableData has_retransmittable_data) { if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) { // For TCP we can always send an ACK immediately. - // We also allow tail loss probes to be sent immediately, in keeping with - // tail loss probe (draft-dukkipati-tcpm-tcp-loss-probe-01). return QuicTime::Delta::Zero(); } if (InRecovery()) { return PrrTimeUntilSend(bytes_in_flight); } - if (AvailableSendWindow(bytes_in_flight) > 0) { + if (SendWindow() > bytes_in_flight) { return QuicTime::Delta::Zero(); } return QuicTime::Delta::Infinite(); } -QuicByteCount TcpCubicSender::AvailableSendWindow( - QuicByteCount bytes_in_flight) { - if (bytes_in_flight > SendWindow()) { - return 0; - } - return SendWindow() - bytes_in_flight; -} - QuicByteCount TcpCubicSender::SendWindow() { // What's the current send window in bytes. return min(receive_window_, GetCongestionWindow()); @@ -222,9 +213,12 @@ bool TcpCubicSender::IsCwndLimited(QuicByteCount bytes_in_flight) const { if (bytes_in_flight >= congestion_window_bytes) { return true; } - const QuicByteCount tcp_max_burst = kMaxBurstLength * kMaxSegmentSize; - const QuicByteCount left = congestion_window_bytes - bytes_in_flight; - return left <= tcp_max_burst; + const QuicByteCount max_burst = kMaxBurstLength * kMaxSegmentSize; + const QuicByteCount available_bytes = + congestion_window_bytes - bytes_in_flight; + const bool slow_start_limited = InSlowStart() && + bytes_in_flight > congestion_window_bytes / 2; + return slow_start_limited || available_bytes <= max_burst; } bool TcpCubicSender::InRecovery() const { @@ -287,15 +281,6 @@ void TcpCubicSender::OnRetransmissionTimeout(bool packets_retransmitted) { } } -void TcpCubicSender::OnRttUpdated() { - if (InSlowStart() && - hybrid_slow_start_.ShouldExitSlowStart(rtt_stats_->latest_rtt(), - rtt_stats_->min_rtt(), - congestion_window_)) { - slowstart_threshold_ = congestion_window_; - } -} - void TcpCubicSender::PrrOnPacketLost(QuicByteCount bytes_in_flight) { prr_out_ = 0; bytes_in_flight_before_loss_ = bytes_in_flight; @@ -315,7 +300,7 @@ QuicTime::Delta TcpCubicSender::PrrTimeUntilSend( if (prr_out_ == 0) { return QuicTime::Delta::Zero(); } - if (AvailableSendWindow(bytes_in_flight) > 0) { + if (SendWindow() > bytes_in_flight) { // During PRR-SSRB, limit outgoing packets to 1 extra MSS per ack, instead // of sending the entire available window. This prevents burst retransmits // when more packets are lost than the CWND reduction. diff --git a/net/quic/congestion_control/tcp_cubic_sender.h b/net/quic/congestion_control/tcp_cubic_sender.h index 5df86c6..3327bda 100644 --- a/net/quic/congestion_control/tcp_cubic_sender.h +++ b/net/quic/congestion_control/tcp_cubic_sender.h @@ -52,6 +52,7 @@ class NET_EXPORT_PRIVATE TcpCubicSender : public SendAlgorithmInterface { const CongestionMap& acked_packets, const CongestionMap& lost_packets) OVERRIDE; virtual bool OnPacketSent(QuicTime sent_time, + QuicByteCount bytes_in_flight, QuicPacketSequenceNumber sequence_number, QuicByteCount bytes, HasRetransmittableData is_retransmittable) OVERRIDE; @@ -74,9 +75,7 @@ class NET_EXPORT_PRIVATE TcpCubicSender : public SendAlgorithmInterface { QuicByteCount bytes_in_flight); void OnPacketLost(QuicPacketSequenceNumber largest_loss, QuicByteCount bytes_in_flight); - void OnRttUpdated(); - QuicByteCount AvailableSendWindow(QuicByteCount bytes_in_flight); QuicByteCount SendWindow(); void MaybeIncreaseCwnd(QuicPacketSequenceNumber acked_sequence_number, QuicByteCount bytes_in_flight); diff --git a/net/quic/congestion_control/tcp_cubic_sender_test.cc b/net/quic/congestion_control/tcp_cubic_sender_test.cc index 7d4f942..c5d991a 100644 --- a/net/quic/congestion_control/tcp_cubic_sender_test.cc +++ b/net/quic/congestion_control/tcp_cubic_sender_test.cc @@ -44,7 +44,6 @@ class TcpCubicSenderPeer : public TcpCubicSender { RttStats rtt_stats_; QuicConnectionStats stats_; - using TcpCubicSender::AvailableSendWindow; using TcpCubicSender::SendWindow; }; @@ -67,8 +66,8 @@ class TcpCubicSenderTest : public ::testing::Test { bool can_send = sender_->TimeUntilSend( clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero(); while (can_send) { - sender_->OnPacketSent(clock_.Now(), sequence_number_++, kDefaultTCPMSS, - HAS_RETRANSMITTABLE_DATA); + sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, sequence_number_++, + kDefaultTCPMSS, HAS_RETRANSMITTABLE_DATA); ++packets_sent; bytes_in_flight_ += kDefaultTCPMSS; can_send = sender_->TimeUntilSend( @@ -151,6 +150,33 @@ TEST_F(TcpCubicSenderTest, SimpleSender) { HAS_RETRANSMITTABLE_DATA).IsZero()); } +TEST_F(TcpCubicSenderTest, ApplicationLimitedSlowStart) { + // Send exactly 10 packets and ensure the CWND ends at 14 packets. + const int kNumberOfAcks = 5; + QuicCongestionFeedbackFrame feedback; + // At startup make sure we can send. + EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), + 0, + HAS_RETRANSMITTABLE_DATA).IsZero()); + // Get default QuicCongestionFeedbackFrame from receiver. + ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); + sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); + // Make sure we can send. + EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), + 0, + HAS_RETRANSMITTABLE_DATA).IsZero()); + + SendAvailableSendWindow(); + for (int i = 0; i < kNumberOfAcks; ++i) { + AckNPackets(2); + } + QuicByteCount bytes_to_send = sender_->SendWindow(); + // It's expected 2 acks will arrive when the bytes_in_flight are greater than + // half the CWND. + EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * 2, + bytes_to_send); +} + TEST_F(TcpCubicSenderTest, ExponentialSlowStart) { const int kNumberOfAcks = 20; QuicCongestionFeedbackFrame feedback; @@ -543,12 +569,14 @@ TEST_F(TcpCubicSenderTest, MultipleLossesInOneWindow) { TEST_F(TcpCubicSenderTest, DontTrackAckPackets) { // Send a packet with no retransmittable data, and ensure it's not tracked. - EXPECT_FALSE(sender_->OnPacketSent(clock_.Now(), sequence_number_++, - kDefaultTCPMSS, NO_RETRANSMITTABLE_DATA)); + EXPECT_FALSE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, + sequence_number_++, kDefaultTCPMSS, + NO_RETRANSMITTABLE_DATA)); // Send a data packet with retransmittable data, and ensure it is tracked. - EXPECT_TRUE(sender_->OnPacketSent(clock_.Now(), sequence_number_++, - kDefaultTCPMSS, HAS_RETRANSMITTABLE_DATA)); + EXPECT_TRUE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, + sequence_number_++, kDefaultTCPMSS, + HAS_RETRANSMITTABLE_DATA)); } TEST_F(TcpCubicSenderTest, ConfigureMaxInitialWindow) { diff --git a/net/quic/congestion_control/tcp_loss_algorithm_test.cc b/net/quic/congestion_control/tcp_loss_algorithm_test.cc index 657ab2b..d7d2d72 100644 --- a/net/quic/congestion_control/tcp_loss_algorithm_test.cc +++ b/net/quic/congestion_control/tcp_loss_algorithm_test.cc @@ -171,7 +171,7 @@ TEST_F(TcpLossAlgorithmTest, DontEarlyRetransmitNeuteredPacket) { // Early retransmit when the final packet gets acked and the first is nacked. unacked_packets_.SetNotPending(2); unacked_packets_.NackPacket(1, 1); - unacked_packets_.NeuterPacket(1); + unacked_packets_.NeuterIfPendingOrRemovePacket(1); VerifyLosses(2, NULL, 0); EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout()); } diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc index 52c177e..6838a1e 100644 --- a/net/quic/quic_connection.cc +++ b/net/quic/quic_connection.cc @@ -1269,8 +1269,8 @@ void QuicConnection::RetransmitUnackedPackets( WriteIfNotBlocked(); } -void QuicConnection::NeuterUnencryptedPackets() { - sent_packet_manager_.NeuterUnencryptedPackets(); +void QuicConnection::DiscardUnencryptedPackets() { + sent_packet_manager_.DiscardUnencryptedPackets(); // This may have changed the retransmission timer, so re-arm it. retransmission_alarm_->Cancel(); QuicTime retransmission_time = sent_packet_manager_.GetRetransmissionTime(); diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h index 62601d8..89affd3 100644 --- a/net/quic/quic_connection.h +++ b/net/quic/quic_connection.h @@ -417,9 +417,9 @@ class NET_EXPORT_PRIVATE QuicConnection // initially encrypted packets when the initial encrypter changes. void RetransmitUnackedPackets(RetransmissionType retransmission_type); - // Calls |sent_packet_manager_|'s NeuterUnencryptedPackets. Used when the + // Calls |sent_packet_manager_|'s DiscardUnencryptedPackets. Used when the // connection becomes forward secure and hasn't received acks for all packets. - void NeuterUnencryptedPackets(); + void DiscardUnencryptedPackets(); // Changes the encrypter used for level |level| to |encrypter|. The function // takes ownership of |encrypter|. diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc index 9b775f8..6ca7c30 100644 --- a/net/quic/quic_connection_test.cc +++ b/net/quic/quic_connection_test.cc @@ -605,13 +605,13 @@ class QuicConnectionTest : public ::testing::TestWithParam<QuicVersion> { QuicTime::Delta::Zero())); EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _)).Times(AnyNumber()); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)) + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) .Times(AnyNumber()); EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( Return(QuicTime::Delta::Zero())); EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly( Return(kMaxPacketSize)); - ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)) + ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) .WillByDefault(Return(true)); EXPECT_CALL(visitor_, HasPendingWrites()).Times(AnyNumber()); EXPECT_CALL(visitor_, HasPendingHandshake()).Times(AnyNumber()); @@ -769,22 +769,22 @@ class QuicConnectionTest : public ::testing::TestWithParam<QuicVersion> { bool fin, QuicPacketSequenceNumber* last_packet) { QuicByteCount packet_size; - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)) - .WillOnce(DoAll(SaveArg<2>(&packet_size), Return(true))); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) + .WillOnce(DoAll(SaveArg<3>(&packet_size), Return(true))); connection_.SendStreamDataWithString(id, data, offset, fin, NULL); if (last_packet != NULL) { *last_packet = QuicConnectionPeer::GetPacketCreator(&connection_)->sequence_number(); } - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)) + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) .Times(AnyNumber()); return packet_size; } void SendAckPacketToPeer() { - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(1); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1); connection_.SendAck(); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)) + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) .Times(AnyNumber()); } @@ -1145,8 +1145,8 @@ TEST_P(QuicConnectionTest, AckReceiptCausesAckSend) { QuicPacketSequenceNumber original; QuicByteCount packet_size; - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)) - .WillOnce(DoAll(SaveArg<1>(&original), SaveArg<2>(&packet_size), + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) + .WillOnce(DoAll(SaveArg<2>(&original), SaveArg<3>(&packet_size), Return(true))); connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL); QuicAckFrame frame = InitAckFrame(original, 1); @@ -1159,8 +1159,8 @@ TEST_P(QuicConnectionTest, AckReceiptCausesAckSend) { EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _)); QuicPacketSequenceNumber retransmission; EXPECT_CALL(*send_algorithm_, - OnPacketSent(_, _, packet_size - kQuicVersionSize, _)) - .WillOnce(DoAll(SaveArg<1>(&retransmission), Return(true))); + OnPacketSent(_, _, _, packet_size - kQuicVersionSize, _)) + .WillOnce(DoAll(SaveArg<2>(&retransmission), Return(true))); ProcessAckPacket(&frame); @@ -1174,7 +1174,7 @@ TEST_P(QuicConnectionTest, AckReceiptCausesAckSend) { // Now if the peer sends an ack which still reports the retransmitted packet // as missing, that will bundle an ack with data after two acks in a row // indicate the high water mark needs to be raised. - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)); connection_.SendStreamDataWithString(3, "foo", 3, !kFin, NULL); // No ack sent. @@ -1185,7 +1185,7 @@ TEST_P(QuicConnectionTest, AckReceiptCausesAckSend) { EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _)) .WillRepeatedly(Return(SequenceNumberSet())); ProcessAckPacket(&frame2); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)); connection_.SendStreamDataWithString(3, "foo", 3, !kFin, NULL); // Ack bundled. @@ -1236,7 +1236,7 @@ TEST_P(QuicConnectionTest, LeastUnackedLower) { // Now claim it's one, but set the ordering so it was sent "after" the first // one. This should cause a connection error. - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); creator_.set_sequence_number(7); if (version() > QUIC_VERSION_15) { EXPECT_CALL(visitor_, @@ -1273,7 +1273,7 @@ TEST_P(QuicConnectionTest, AckUnsentData) { // Ack a packet which has not been sent. EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_INVALID_ACK_DATA, false)); EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); QuicAckFrame frame(MakeAckFrame(1, 0)); EXPECT_CALL(visitor_, OnCanWrite()).Times(0); ProcessAckPacket(&frame); @@ -1447,7 +1447,7 @@ TEST_P(QuicConnectionTest, FECSending) { connection_.options()->max_packets_per_fec_group = 2; // Send 4 data packets and 2 FEC packets. - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(6); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(6); // The first stream frame will consume 2 fewer bytes than the other three. const string payload(payload_length * 4 - 6, 'a'); connection_.SendStreamDataWithString(1, payload, 0, !kFin, NULL); @@ -1477,7 +1477,7 @@ TEST_P(QuicConnectionTest, FECQueueing) { TEST_P(QuicConnectionTest, AbandonFECFromCongestionWindow) { connection_.options()->max_packets_per_fec_group = 1; // 1 Data and 1 FEC packet. - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(2); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2); connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL); const QuicTime::Delta retransmission_time = @@ -1486,7 +1486,7 @@ TEST_P(QuicConnectionTest, AbandonFECFromCongestionWindow) { // Abandon FEC packet and data packet. EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(1); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1); EXPECT_CALL(visitor_, OnCanWrite()); connection_.OnRetransmissionTimeout(); } @@ -1496,7 +1496,7 @@ TEST_P(QuicConnectionTest, DontAbandonAckedFEC) { connection_.options()->max_packets_per_fec_group = 1; // 1 Data and 1 FEC packet. - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(6); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(6); connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL); // Send some more data afterwards to ensure early retransmit doesn't trigger. connection_.SendStreamDataWithString(3, "foo", 3, !kFin, NULL); @@ -1514,7 +1514,7 @@ TEST_P(QuicConnectionTest, DontAbandonAckedFEC) { // Don't abandon the acked FEC packet, but it will abandon 2 the subsequent // FEC packets. EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(3); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3); connection_.GetRetransmissionAlarm()->Fire(); } @@ -1523,7 +1523,7 @@ TEST_P(QuicConnectionTest, AbandonAllFEC) { connection_.options()->max_packets_per_fec_group = 1; // 1 Data and 1 FEC packet. - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(6); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(6); connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL); // Send some more data afterwards to ensure early retransmit doesn't trigger. connection_.SendStreamDataWithString(3, "foo", 3, !kFin, NULL); @@ -1568,7 +1568,7 @@ TEST_P(QuicConnectionTest, FramePacking) { IgnoreResult(InvokeWithoutArgs(&connection_, &TestConnection::SendStreamData5)))); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(1); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1); // Unblock the connection. connection_.GetSendAlarm()->Fire(); EXPECT_EQ(0u, connection_.NumQueuedPackets()); @@ -1602,7 +1602,7 @@ TEST_P(QuicConnectionTest, FramePackingNonCryptoThenCrypto) { IgnoreResult(InvokeWithoutArgs(&connection_, &TestConnection::SendCryptoStreamData)))); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(2); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2); // Unblock the connection. connection_.GetSendAlarm()->Fire(); EXPECT_EQ(0u, connection_.NumQueuedPackets()); @@ -1628,7 +1628,7 @@ TEST_P(QuicConnectionTest, FramePackingCryptoThenNonCrypto) { IgnoreResult(InvokeWithoutArgs(&connection_, &TestConnection::SendStreamData3)))); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(3); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3); // Unblock the connection. connection_.GetSendAlarm()->Fire(); EXPECT_EQ(0u, connection_.NumQueuedPackets()); @@ -1658,7 +1658,7 @@ TEST_P(QuicConnectionTest, FramePackingFEC) { IgnoreResult(InvokeWithoutArgs(&connection_, &TestConnection::SendStreamData5)))); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(2); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2); // Unblock the connection. connection_.GetSendAlarm()->Fire(); EXPECT_EQ(0u, connection_.NumQueuedPackets()); @@ -1681,7 +1681,7 @@ TEST_P(QuicConnectionTest, FramePackingAckResponse) { IgnoreResult(InvokeWithoutArgs(&connection_, &TestConnection::SendStreamData5)))); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(1); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1); // Process an ack to cause the visitor's OnCanWrite to be invoked. creator_.set_sequence_number(2); @@ -1708,7 +1708,7 @@ TEST_P(QuicConnectionTest, FramePackingAckResponse) { TEST_P(QuicConnectionTest, FramePackingSendv) { // Send data in 1 packet by writing multiple blocks in a single iovector // using writev. - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); char data[] = "ABCD"; IOVector data_iov; @@ -1732,7 +1732,7 @@ TEST_P(QuicConnectionTest, FramePackingSendv) { TEST_P(QuicConnectionTest, FramePackingSendvQueued) { // Try to send two stream frames in 1 packet by using writev. - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); BlockOnNextWrite(); char data[] = "ABCD"; @@ -1757,7 +1757,7 @@ TEST_P(QuicConnectionTest, FramePackingSendvQueued) { TEST_P(QuicConnectionTest, SendingZeroBytes) { // Send a zero byte write with a fin using writev. - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); IOVector empty_iov; connection_.SendStreamData(1, empty_iov, 0, kFin, NULL); @@ -1817,7 +1817,7 @@ TEST_P(QuicConnectionTest, RetransmitOnNack) { .WillOnce(Return(lost_packets)); EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _)); EXPECT_CALL(*send_algorithm_, - OnPacketSent(_, _, second_packet_size - kQuicVersionSize, _)). + OnPacketSent(_, _, _, second_packet_size - kQuicVersionSize, _)). Times(1); ProcessAckPacket(&nack_two); } @@ -1854,7 +1854,7 @@ TEST_P(QuicConnectionTest, DiscardRetransmit) { // since the previous transmission has been acked, we will not // send the retransmission. EXPECT_CALL(*send_algorithm_, - OnPacketSent(_, _, _, _)).Times(0); + OnPacketSent(_, _, _, _, _)).Times(0); writer_->SetWritable(); connection_.OnCanWrite(); @@ -1866,8 +1866,8 @@ TEST_P(QuicConnectionTest, RetransmitNackedLargestObserved) { EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); QuicPacketSequenceNumber largest_observed; QuicByteCount packet_size; - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)) - .WillOnce(DoAll(SaveArg<1>(&largest_observed), SaveArg<2>(&packet_size), + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) + .WillOnce(DoAll(SaveArg<2>(&largest_observed), SaveArg<3>(&packet_size), Return(true))); connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL); @@ -1880,13 +1880,13 @@ TEST_P(QuicConnectionTest, RetransmitNackedLargestObserved) { .WillOnce(Return(lost_packets)); EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _)); EXPECT_CALL(*send_algorithm_, - OnPacketSent(_, _, packet_size - kQuicVersionSize, _)); + OnPacketSent(_, _, _, packet_size - kQuicVersionSize, _)); ProcessAckPacket(&frame); } TEST_P(QuicConnectionTest, QueueAfterTwoRTOs) { for (int i = 0; i < 10; ++i) { - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(1); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1); connection_.SendStreamDataWithString(3, "foo", i * 3, !kFin, NULL); } @@ -1904,7 +1904,7 @@ TEST_P(QuicConnectionTest, QueueAfterTwoRTOs) { 2 * DefaultRetransmissionTime().ToMicroseconds())); // Retransmit already retransmitted packets event though the sequence number // greater than the largest observed. - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(10); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(10); connection_.GetRetransmissionAlarm()->Fire(); connection_.OnCanWrite(); } @@ -1915,7 +1915,7 @@ TEST_P(QuicConnectionTest, WriteBlockedThenSent) { connection_.SendStreamDataWithString(1, "foo", 0, !kFin, NULL); EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet()); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(1); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1); connection_.OnPacketSent(WriteResult(WRITE_STATUS_OK, 0)); EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet()); } @@ -1932,7 +1932,7 @@ TEST_P(QuicConnectionTest, WriteBlockedAckedThenSent) { QuicAckFrame ack = InitAckFrame(1, 0); ProcessAckPacket(&ack); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(0); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0); connection_.OnPacketSent(WriteResult(WRITE_STATUS_OK, 0)); EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet()); } @@ -2000,7 +2000,7 @@ TEST_P(QuicConnectionTest, NoLimitPacketsPerNack) { EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _)) .WillOnce(Return(lost_packets)); EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(14); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(14); ProcessAckPacket(&nack); } @@ -2035,7 +2035,7 @@ TEST_P(QuicConnectionTest, MultipleAcks) { TEST_P(QuicConnectionTest, DontLatchUnackedPacket) { SendStreamDataToPeer(1, "foo", 0, !kFin, NULL); // Packet 1; // From now on, we send acks, so the send algorithm won't mark them pending. - ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)) + ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) .WillByDefault(Return(false)); SendAckPacketToPeer(); // Packet 2 @@ -2067,18 +2067,18 @@ TEST_P(QuicConnectionTest, DontLatchUnackedPacket) { frame = InitAckFrame(3, 0); ProcessAckPacket(&frame); - ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)) + ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) .WillByDefault(Return(true)); SendStreamDataToPeer(1, "bar", 3, false, NULL); // Packet 4 EXPECT_EQ(4u, outgoing_ack()->sent_info.least_unacked); - ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)) + ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) .WillByDefault(Return(false)); SendAckPacketToPeer(); // Packet 5 EXPECT_EQ(4u, least_unacked()); // Send two data packets at the end, and ensure if the last one is acked, // the least unacked is raised above the ack packets. - ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)) + ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) .WillByDefault(Return(true)); SendStreamDataToPeer(1, "bar", 6, false, NULL); // Packet 6 SendStreamDataToPeer(1, "bar", 9, false, NULL); // Packet 7 @@ -2239,7 +2239,7 @@ TEST_P(QuicConnectionTest, RTO) { // Simulate the retransmission alarm firing. clock_.AdvanceTime(DefaultRetransmissionTime()); EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 2u, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 2u, _, _)); connection_.GetRetransmissionAlarm()->Fire(); EXPECT_EQ(2u, writer_->header().packet_sequence_number); // We do not raise the high water mark yet. @@ -2267,8 +2267,8 @@ TEST_P(QuicConnectionTest, RTOWithSameEncryptionLevel) { { InSequence s; EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 3, _, _)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 4, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 3, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 4, _, _)); } // Simulate the retransmission alarm firing. @@ -2323,7 +2323,7 @@ TEST_P(QuicConnectionTest, connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(0); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0); QuicTime default_retransmission_time = clock_.ApproximateNow().Add( DefaultRetransmissionTime()); @@ -2346,7 +2346,7 @@ TEST_P(QuicConnectionTest, RetransmitPacketsWithInitialEncryption) { connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL); SendStreamDataToPeer(2, "bar", 0, !kFin, NULL); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(1); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1); connection_.RetransmitUnackedPackets(INITIAL_ENCRYPTION_ONLY); } @@ -2380,13 +2380,13 @@ TEST_P(QuicConnectionTest, BufferNonDecryptablePackets) { TEST_P(QuicConnectionTest, TestRetransmitOrder) { QuicByteCount first_packet_size; - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).WillOnce( - DoAll(SaveArg<2>(&first_packet_size), Return(true))); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).WillOnce( + DoAll(SaveArg<3>(&first_packet_size), Return(true))); connection_.SendStreamDataWithString(3, "first_packet", 0, !kFin, NULL); QuicByteCount second_packet_size; - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).WillOnce( - DoAll(SaveArg<2>(&second_packet_size), Return(true))); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).WillOnce( + DoAll(SaveArg<3>(&second_packet_size), Return(true))); connection_.SendStreamDataWithString(3, "second_packet", 12, !kFin, NULL); EXPECT_NE(first_packet_size, second_packet_size); // Advance the clock by huge time to make sure packets will be retransmitted. @@ -2395,9 +2395,9 @@ TEST_P(QuicConnectionTest, TestRetransmitOrder) { { InSequence s; EXPECT_CALL(*send_algorithm_, - OnPacketSent(_, _, first_packet_size, _)); + OnPacketSent(_, _, _, first_packet_size, _)); EXPECT_CALL(*send_algorithm_, - OnPacketSent(_, _, second_packet_size, _)); + OnPacketSent(_, _, _, second_packet_size, _)); } connection_.GetRetransmissionAlarm()->Fire(); @@ -2407,9 +2407,9 @@ TEST_P(QuicConnectionTest, TestRetransmitOrder) { { InSequence s; EXPECT_CALL(*send_algorithm_, - OnPacketSent(_, _, first_packet_size, _)); + OnPacketSent(_, _, _, first_packet_size, _)); EXPECT_CALL(*send_algorithm_, - OnPacketSent(_, _, second_packet_size, _)); + OnPacketSent(_, _, _, second_packet_size, _)); } connection_.GetRetransmissionAlarm()->Fire(); } @@ -2417,8 +2417,8 @@ TEST_P(QuicConnectionTest, TestRetransmitOrder) { TEST_P(QuicConnectionTest, RetransmissionCountCalculation) { EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); QuicPacketSequenceNumber original_sequence_number; - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)) - .WillOnce(DoAll(SaveArg<1>(&original_sequence_number), Return(true))); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) + .WillOnce(DoAll(SaveArg<2>(&original_sequence_number), Return(true))); connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL); EXPECT_TRUE(QuicConnectionPeer::IsSavedForRetransmission( @@ -2429,8 +2429,8 @@ TEST_P(QuicConnectionTest, RetransmissionCountCalculation) { clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10)); EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true)); QuicPacketSequenceNumber rto_sequence_number; - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)) - .WillOnce(DoAll(SaveArg<1>(&rto_sequence_number), Return(true))); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) + .WillOnce(DoAll(SaveArg<2>(&rto_sequence_number), Return(true))); connection_.GetRetransmissionAlarm()->Fire(); EXPECT_FALSE(QuicConnectionPeer::IsSavedForRetransmission( &connection_, original_sequence_number)); @@ -2447,10 +2447,10 @@ TEST_P(QuicConnectionTest, RetransmissionCountCalculation) { QuicPacketSequenceNumber nack_sequence_number = 0; // Ack packets might generate some other packets, which are not // retransmissions. (More ack packets). - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)) + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) .Times(AnyNumber()); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)) - .WillOnce(DoAll(SaveArg<1>(&nack_sequence_number), Return(true))); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) + .WillOnce(DoAll(SaveArg<2>(&nack_sequence_number), Return(true))); QuicAckFrame ack = InitAckFrame(rto_sequence_number, 0); // Nack the retransmitted packet. NackPacket(original_sequence_number, &ack); @@ -2480,7 +2480,7 @@ TEST_P(QuicConnectionTest, SetRTOAfterWritingToSocket) { TEST_P(QuicConnectionTest, DelayRTOWithAckReceipt) { EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)) + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) .Times(2); connection_.SendStreamDataWithString(2, "foo", 0, !kFin, NULL); connection_.SendStreamDataWithString(3, "bar", 0, !kFin, NULL); @@ -2505,7 +2505,7 @@ TEST_P(QuicConnectionTest, DelayRTOWithAckReceipt) { EXPECT_TRUE(retransmission_alarm->IsSet()); EXPECT_LT(retransmission_alarm->deadline(), clock_.ApproximateNow()); EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); // Manually cancel the alarm to simulate a real test. connection_.GetRetransmissionAlarm()->Fire(); @@ -2590,7 +2590,7 @@ TEST_P(QuicConnectionTest, DontUpdateQuicCongestionFeedbackFrameForRevived) { TEST_P(QuicConnectionTest, InitialTimeout) { EXPECT_TRUE(connection_.connected()); EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_CONNECTION_TIMED_OUT, false)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); QuicTime default_timeout = clock_.ApproximateNow().Add( QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs)); @@ -2683,7 +2683,7 @@ TEST_P(QuicConnectionTest, TimeoutAfterSend) { // This time, we should time out. EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_CONNECTION_TIMED_OUT, false)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5)); EXPECT_EQ(default_timeout.Add(QuicTime::Delta::FromMilliseconds(5)), clock_.ApproximateNow()); @@ -2698,7 +2698,7 @@ TEST_P(QuicConnectionTest, SendScheduler) { EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).WillOnce( testing::Return(QuicTime::Delta::Zero())); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); connection_.SendPacket( ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA); EXPECT_EQ(0u, connection_.NumQueuedPackets()); @@ -2710,7 +2710,7 @@ TEST_P(QuicConnectionTest, SendSchedulerDelay) { EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).WillOnce( testing::Return(QuicTime::Delta::FromMicroseconds(1))); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 1, _, _)).Times(0); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0); connection_.SendPacket( ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA); EXPECT_EQ(1u, connection_.NumQueuedPackets()); @@ -2722,7 +2722,7 @@ TEST_P(QuicConnectionTest, SendSchedulerEAGAIN) { EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).WillOnce( testing::Return(QuicTime::Delta::Zero())); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 1, _, _)).Times(0); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0); connection_.SendPacket( ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA); EXPECT_EQ(1u, connection_.NumQueuedPackets()); @@ -2744,7 +2744,7 @@ TEST_P(QuicConnectionTest, SendSchedulerDelayThenSend) { TimeUntilSend(_, _, _)).WillRepeatedly( testing::Return(QuicTime::Delta::Zero())); clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(1)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); connection_.GetSendAlarm()->Fire(); EXPECT_EQ(0u, connection_.NumQueuedPackets()); } @@ -2752,7 +2752,7 @@ TEST_P(QuicConnectionTest, SendSchedulerDelayThenSend) { TEST_P(QuicConnectionTest, SendSchedulerDelayThenRetransmit) { EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)) .WillRepeatedly(testing::Return(QuicTime::Delta::Zero())); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 1, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)); connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL); EXPECT_EQ(0u, connection_.NumQueuedPackets()); // Advance the time for retransmission of lost packet. @@ -2773,7 +2773,7 @@ TEST_P(QuicConnectionTest, SendSchedulerDelayThenRetransmit) { WillRepeatedly(testing::Return(QuicTime::Delta::Zero())); // Ensure the scheduler is notified this is a retransmit. - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(1)); connection_.GetSendAlarm()->Fire(); EXPECT_EQ(0u, connection_.NumQueuedPackets()); @@ -2812,7 +2812,7 @@ TEST_P(QuicConnectionTest, SendSchedulerDelayThenAckAndSend) { TimeUntilSend(_, _, _)).WillRepeatedly( testing::Return(QuicTime::Delta::Zero())); EXPECT_CALL(*send_algorithm_, - OnPacketSent(_, _, _, _)); + OnPacketSent(_, _, _, _, _)); ProcessAckPacket(&frame); EXPECT_EQ(0u, connection_.NumQueuedPackets()); @@ -2886,7 +2886,7 @@ TEST_P(QuicConnectionTest, LoopThroughSendingPackets) { NOT_IN_FEC_GROUP, &payload_length); // Queue the first packet. - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(7); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(7); // The first stream frame will consume 2 fewer bytes than the other six. const string payload(payload_length * 7 - 12, 'a'); EXPECT_EQ(payload.size(), @@ -3074,7 +3074,7 @@ TEST_P(QuicConnectionTest, NoAckSentForClose) { EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); ProcessPacket(1); EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_PEER_GOING_AWAY, true)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(0); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0); ProcessClosePacket(2, 0); } @@ -3084,7 +3084,7 @@ TEST_P(QuicConnectionTest, SendWhenDisconnected) { connection_.CloseConnection(QUIC_PEER_GOING_AWAY, false); EXPECT_FALSE(connection_.connected()); QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 1, _, _)).Times(0); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0); connection_.SendPacket( ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA); } @@ -3473,18 +3473,17 @@ TEST_P(QuicConnectionTest, BadVersionNegotiation) { } TEST_P(QuicConnectionTest, CheckSendStats) { - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); connection_.SendStreamDataWithString(3, "first", 0, !kFin, NULL); size_t first_packet_size = writer_->last_packet_size(); - EXPECT_CALL(*send_algorithm_, - OnPacketSent(_, _, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); connection_.SendStreamDataWithString(5, "second", 0, !kFin, NULL); size_t second_packet_size = writer_->last_packet_size(); // 2 retransmissions due to rto, 1 due to explicit nack. EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(3); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3); // Retransmit due to RTO. clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10)); @@ -3717,7 +3716,7 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackAfterRetransmission) { EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _)) .WillOnce(Return(lost_packets)); EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); ProcessAckPacket(&frame); // Now we get an ACK for packet 5 (retransmitted packet 2), which should @@ -3750,7 +3749,7 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackForAckAfterRTO) { // Simulate the retransmission alarm firing. clock_.AdvanceTime(DefaultRetransmissionTime()); EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 2u, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 2u, _, _)); connection_.GetRetransmissionAlarm()->Fire(); EXPECT_EQ(2u, writer_->header().packet_sequence_number); // We do not raise the high water mark yet. @@ -3794,7 +3793,7 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackForAckOfNackedPacket) { EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _)) .WillOnce(Return(lost_packets)); EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); ProcessAckPacket(&frame); // Now we get an ACK for packet 2, which was previously nacked. diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc index 47c8a1e..557e976 100644 --- a/net/quic/quic_http_stream_test.cc +++ b/net/quic/quic_http_stream_test.cc @@ -184,7 +184,7 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> { EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _)). Times(AnyNumber()); EXPECT_CALL(*send_algorithm_, - OnPacketSent(_, _, _, _)).WillRepeatedly(Return(true)); + OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true)); EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( Return(QuicTime::Delta::Zero())); EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly( diff --git a/net/quic/quic_sent_packet_manager.cc b/net/quic/quic_sent_packet_manager.cc index 88017c4..0085f90 100644 --- a/net/quic/quic_sent_packet_manager.cc +++ b/net/quic/quic_sent_packet_manager.cc @@ -126,7 +126,7 @@ void QuicSentPacketManager::OnIncomingAck( largest_observed_ = received_info.largest_observed; bool largest_observed_acked = MaybeUpdateRTT(received_info, ack_receive_time); HandleAckForSentPackets(received_info); - MaybeRetransmitOnAckFrame(received_info, ack_receive_time); + InvokeLossDetection(ack_receive_time); MaybeInvokeCongestionEvent(largest_observed_acked, bytes_in_flight); // Anytime we are making forward progress and have a new RTT estimate, reset @@ -175,6 +175,17 @@ void QuicSentPacketManager::HandleAckForSentPackets( if (QuicUnackedPacketMap::IsSentAndNotPending(it->second)) { it = MarkPacketHandled(sequence_number, delta_largest_observed); } else { + // 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. + // The nack count only increases when the largest observed increases. + size_t min_nacks = received_info.largest_observed - sequence_number; + // Truncated acks can nack the largest observed, so use a min of 1. + if (min_nacks == 0) { + min_nacks = 1; + } + unacked_packets_.NackPacket(sequence_number, min_nacks); ++it; } continue; @@ -240,19 +251,19 @@ void QuicSentPacketManager::RetransmitUnackedPackets( } } -void QuicSentPacketManager::NeuterUnencryptedPackets() { +void QuicSentPacketManager::DiscardUnencryptedPackets() { QuicUnackedPacketMap::const_iterator unacked_it = unacked_packets_.begin(); while (unacked_it != unacked_packets_.end()) { const RetransmittableFrames* frames = unacked_it->second.retransmittable_frames; if (frames != NULL && frames->encryption_level() == ENCRYPTION_NONE) { - // Since once you're forward secure, no unencrypted packets will be sent, - // crypto or otherwise. Unencrypted packets are neutered and abandoned, to - // ensure they are not retransmitted or considered lost from a congestion - // control perspective. + // Once you're forward secure, no unencrypted packets will be sent. + // Additionally, it's likely the peer will be forward secure, and no acks + // for these packets will be received, so mark the packet as handled. pending_retransmissions_.erase(unacked_it->first); - unacked_packets_.NeuterPacket(unacked_it->first); - unacked_packets_.SetNotPending(unacked_it->first); + unacked_it = MarkPacketHandled(unacked_it->first, + QuicTime::Delta::Zero()); + continue; } ++unacked_it; } @@ -326,11 +337,7 @@ void QuicSentPacketManager::MarkPacketRevived( sequence_number, delta_largest_observed); } - if (!transmission_info.pending) { - unacked_packets_.RemovePacket(sequence_number); - } else { - unacked_packets_.NeuterPacket(sequence_number); - } + unacked_packets_.NeuterIfPendingOrRemovePacket(sequence_number); } QuicUnackedPacketMap::const_iterator QuicSentPacketManager::MarkPacketHandled( @@ -365,8 +372,6 @@ QuicUnackedPacketMap::const_iterator QuicSentPacketManager::MarkPacketHandled( unacked_packets_.GetTransmissionInfo(newest_transmission)); while (all_transmissions_it != all_transmissions.rend()) { QuicPacketSequenceNumber previous_transmission = *all_transmissions_it; - const TransmissionInfo& transmission_info = - unacked_packets_.GetTransmissionInfo(previous_transmission); // If this packet was marked for retransmission, don't bother retransmitting // it anymore. pending_retransmissions_.erase(previous_transmission); @@ -375,11 +380,7 @@ QuicUnackedPacketMap::const_iterator QuicSentPacketManager::MarkPacketHandled( // since they won't be acked now that one has been processed. unacked_packets_.SetNotPending(previous_transmission); } - if (!transmission_info.pending) { - unacked_packets_.RemovePacket(previous_transmission); - } else { - unacked_packets_.NeuterPacket(previous_transmission); - } + unacked_packets_.NeuterIfPendingOrRemovePacket(previous_transmission); ++all_transmissions_it; } @@ -420,7 +421,10 @@ bool QuicSentPacketManager::OnPacketSent( } // Only track packets as pending that the send algorithm wants us to track. - if (!send_algorithm_->OnPacketSent(sent_time, sequence_number, bytes, + if (!send_algorithm_->OnPacketSent(sent_time, + unacked_packets_.bytes_in_flight(), + sequence_number, + bytes, has_retransmittable_data)) { unacked_packets_.SetSent(sequence_number, sent_time, bytes, false); // Do not reset the retransmission timer, since the packet isn't tracked. @@ -562,38 +566,6 @@ void QuicSentPacketManager::OnIncomingQuicCongestionFeedbackFrame( frame, feedback_receive_time); } -void QuicSentPacketManager::MaybeRetransmitOnAckFrame( - const ReceivedPacketInfo& received_info, - const QuicTime& ack_receive_time) { - // Go through all pending packets up to the largest observed and count nacks. - // TODO(ianswett): Now that the SendAlgorithmInterface has changed, it may - // make sense to merge this with HandleAckForSentPackets. - for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); - it != unacked_packets_.end() && - it->first <= received_info.largest_observed; ++it) { - if (!it->second.pending) { - continue; - } - QuicPacketSequenceNumber sequence_number = it->first; - DVLOG(1) << "still missing packet " << sequence_number; - // Acks must be handled previously, so ensure it's missing and not acked. - DCHECK(IsAwaitingPacket(received_info, 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. - // The nack count only increases when the largest observed increases. - size_t min_nacks = received_info.largest_observed - sequence_number; - // Truncated acks can nack the largest observed, so set the nack count to 1. - if (min_nacks == 0) { - min_nacks = 1; - } - unacked_packets_.NackPacket(sequence_number, min_nacks); - } - - InvokeLossDetection(ack_receive_time); -} - void QuicSentPacketManager::InvokeLossDetection(QuicTime time) { SequenceNumberSet lost_packets = loss_algorithm_->DetectLostPackets(unacked_packets_, @@ -619,7 +591,7 @@ void QuicSentPacketManager::InvokeLossDetection(QuicTime time) { // unacked_packets_. This is either the current transmission of // a packet whose previous transmission has been acked, or it // is a packet that has been TLP retransmitted. - unacked_packets_.RemovePacket(sequence_number); + unacked_packets_.NeuterIfPendingOrRemovePacket(sequence_number); } } } diff --git a/net/quic/quic_sent_packet_manager.h b/net/quic/quic_sent_packet_manager.h index fd01eee..1af85c4 100644 --- a/net/quic/quic_sent_packet_manager.h +++ b/net/quic/quic_sent_packet_manager.h @@ -96,7 +96,7 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager { // Removes the retransmittable frames from all unencrypted packets to ensure // they don't get retransmitted. - void NeuterUnencryptedPackets(); + void DiscardUnencryptedPackets(); // Returns true if the unacked packet |sequence_number| has retransmittable // frames. This will only return false if the packet has been acked, if a @@ -216,11 +216,6 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager { bool MaybeUpdateRTT(const ReceivedPacketInfo& received_info, const QuicTime& ack_receive_time); - // Chooses whether to nack retransmit any packets based on the receipt info. - // All acks have been handled before this method is invoked. - void MaybeRetransmitOnAckFrame(const ReceivedPacketInfo& received_info, - const QuicTime& ack_receive_time); - // Invokes the loss detection algorithm and loses and retransmits packets if // necessary. void InvokeLossDetection(QuicTime time); diff --git a/net/quic/quic_sent_packet_manager_test.cc b/net/quic/quic_sent_packet_manager_test.cc index 9f4d084..e44dca5 100644 --- a/net/quic/quic_sent_packet_manager_test.cc +++ b/net/quic/quic_sent_packet_manager_test.cc @@ -23,6 +23,11 @@ namespace net { namespace test { namespace { +// Default packet length. +const uint32 kDefaultLength = 1000; + +// Matcher to check the key of the key-value pair it receives as first argument +// equals its second argument. MATCHER(KeyEq, "") { return std::tr1::get<0>(arg).first == std::tr1::get<1>(arg); } @@ -43,6 +48,9 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> { STLDeleteElements(&packets_); } + QuicByteCount BytesInFlight() { + return QuicSentPacketManagerPeer::GetBytesInFlight(&manager_); + } void VerifyUnackedPackets(QuicPacketSequenceNumber* packets, size_t num_packets) { if (num_packets == 0) { @@ -135,11 +143,14 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> { void RetransmitAndSendPacket(QuicPacketSequenceNumber old_sequence_number, QuicPacketSequenceNumber new_sequence_number) { RetransmitPacket(old_sequence_number, new_sequence_number); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, new_sequence_number, _, _)) + + EXPECT_CALL(*send_algorithm_, + OnPacketSent(_, BytesInFlight(), new_sequence_number, + kDefaultLength, HAS_RETRANSMITTABLE_DATA)) .WillOnce(Return(true)); manager_.OnPacketSent(new_sequence_number, clock_.Now(), - 1000, + kDefaultLength, LOSS_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); } @@ -151,7 +162,7 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> { SerializedPacket CreatePacket(QuicPacketSequenceNumber sequence_number, bool retransmittable) { packets_.push_back(QuicPacket::NewDataPacket( - NULL, 1000, false, PACKET_8BYTE_CONNECTION_ID, false, + NULL, kDefaultLength, false, PACKET_8BYTE_CONNECTION_ID, false, PACKET_6BYTE_SEQUENCE_NUMBER)); return SerializedPacket( sequence_number, PACKET_6BYTE_SEQUENCE_NUMBER, @@ -161,14 +172,15 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> { SerializedPacket CreateFecPacket(QuicPacketSequenceNumber sequence_number) { packets_.push_back(QuicPacket::NewFecPacket( - NULL, 1000, false, PACKET_8BYTE_CONNECTION_ID, false, + NULL, kDefaultLength, false, PACKET_8BYTE_CONNECTION_ID, false, PACKET_6BYTE_SEQUENCE_NUMBER)); return SerializedPacket(sequence_number, PACKET_6BYTE_SEQUENCE_NUMBER, packets_.back(), 0u, NULL); } void SendDataPacket(QuicPacketSequenceNumber sequence_number) { - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, sequence_number, _, _)) + EXPECT_CALL(*send_algorithm_, + OnPacketSent(_, BytesInFlight(), sequence_number, _, _)) .Times(1).WillOnce(Return(true)); SerializedPacket packet(CreateDataPacket(sequence_number)); manager_.OnSerializedPacket(packet); @@ -178,11 +190,14 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> { } void SendCryptoPacket(QuicPacketSequenceNumber sequence_number) { - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, sequence_number, _, _)) + EXPECT_CALL(*send_algorithm_, + OnPacketSent(_, BytesInFlight(), sequence_number, + kDefaultLength, HAS_RETRANSMITTABLE_DATA)) .Times(1).WillOnce(Return(true)); SerializedPacket packet(CreateDataPacket(sequence_number)); packet.retransmittable_frames->AddStreamFrame( new QuicStreamFrame(1, false, 0, IOVector())); + packet.retransmittable_frames->set_encryption_level(ENCRYPTION_NONE); manager_.OnSerializedPacket(packet); manager_.OnPacketSent(sequence_number, clock_.ApproximateNow(), packet.packet->length(), NOT_RETRANSMISSION, @@ -190,7 +205,9 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> { } void SendFecPacket(QuicPacketSequenceNumber sequence_number) { - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, sequence_number, _, _)) + EXPECT_CALL(*send_algorithm_, + OnPacketSent(_, BytesInFlight(), sequence_number, + kDefaultLength, NO_RETRANSMITTABLE_DATA)) .Times(1).WillOnce(Return(true)); SerializedPacket packet(CreateFecPacket(sequence_number)); manager_.OnSerializedPacket(packet); @@ -200,7 +217,9 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> { } void SendAckPacket(QuicPacketSequenceNumber sequence_number) { - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, sequence_number, _, _)) + EXPECT_CALL(*send_algorithm_, + OnPacketSent(_, BytesInFlight(), sequence_number, + kDefaultLength, NO_RETRANSMITTABLE_DATA)) .Times(1).WillOnce(Return(false)); SerializedPacket packet(CreatePacket(sequence_number, false)); manager_.OnSerializedPacket(packet); @@ -214,15 +233,16 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> { QuicPacketSequenceNumber retransmission_sequence_number) { EXPECT_TRUE(manager_.HasPendingRetransmissions()); EXPECT_CALL(*send_algorithm_, - OnPacketSent(_, retransmission_sequence_number, _, _)) + OnPacketSent(_, _, retransmission_sequence_number, + kDefaultLength, HAS_RETRANSMITTABLE_DATA)) .Times(1).WillOnce(Return(true)); const QuicSentPacketManager::PendingRetransmission pending = manager_.NextPendingRetransmission(); manager_.OnRetransmittedPacket( pending.sequence_number, retransmission_sequence_number); - manager_.OnPacketSent(retransmission_sequence_number, - clock_.ApproximateNow(), 1000, - pending.transmission_type, HAS_RETRANSMITTABLE_DATA); + manager_.OnPacketSent(retransmission_sequence_number, clock_.Now(), + kDefaultLength, pending.transmission_type, + HAS_RETRANSMITTABLE_DATA); } QuicSentPacketManager manager_; @@ -342,9 +362,9 @@ TEST_F(QuicSentPacketManagerTest, RetransmitAndSendThenAckPrevious) { TEST_F(QuicSentPacketManagerTest, RetransmitThenAckPreviousThenNackRetransmit) { SendDataPacket(1); RetransmitPacket(1, 2); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 2, _, _)) + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 2, _, _)) .WillOnce(Return(true)); - manager_.OnPacketSent(2, clock_.ApproximateNow(), 1000, + manager_.OnPacketSent(2, clock_.ApproximateNow(), kDefaultLength, LOSS_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(15); clock_.AdvanceTime(rtt); @@ -649,18 +669,18 @@ TEST_F(QuicSentPacketManagerTest, GetSentTime) { SerializedPacket serialized_packet(CreateFecPacket(1)); manager_.OnSerializedPacket(serialized_packet); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 1, _, _)) + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)) .Times(1).WillOnce(Return(true)); - manager_.OnPacketSent( - 1, QuicTime::Zero(), 1000, NOT_RETRANSMISSION, NO_RETRANSMITTABLE_DATA); + manager_.OnPacketSent(1, QuicTime::Zero(), kDefaultLength, NOT_RETRANSMISSION, + NO_RETRANSMITTABLE_DATA); SerializedPacket serialized_packet2(CreateFecPacket(2)); QuicTime sent_time = QuicTime::Zero().Add(QuicTime::Delta::FromSeconds(1)); manager_.OnSerializedPacket(serialized_packet2); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 2, _, _)) + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 2, _, _)) .Times(1).WillOnce(Return(true)); - manager_.OnPacketSent( - 2, sent_time, 1000, NOT_RETRANSMISSION, NO_RETRANSMITTABLE_DATA); + manager_.OnPacketSent(2, sent_time, kDefaultLength, NOT_RETRANSMISSION, + NO_RETRANSMITTABLE_DATA); QuicPacketSequenceNumber unacked[] = { 1, 2 }; VerifyUnackedPackets(unacked, arraysize(unacked)); @@ -968,6 +988,25 @@ TEST_F(QuicSentPacketManagerTest, EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_)); } +TEST_F(QuicSentPacketManagerTest, + CryptoHandshakeRetransmissionThenAbandonAll) { + // Send 1 crypto packet. + SendCryptoPacket(1); + EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_)); + + // Retransmit the crypto packet as 2. + manager_.OnRetransmissionTimeout(); + RetransmitNextPacket(2); + + // Now discard all unacked unencrypted packets, which occurs when the + // connection goes forward secure. + manager_.DiscardUnencryptedPackets(); + VerifyUnackedPackets(NULL, 0); + EXPECT_FALSE(manager_.HasPendingRetransmissions()); + EXPECT_FALSE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_)); + EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_)); +} + TEST_F(QuicSentPacketManagerTest, TailLossProbeTimeoutUnsentDataPacket) { QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2); // Serialize two data packets and send the latter. diff --git a/net/quic/quic_session.cc b/net/quic/quic_session.cc index 6d749ec..66f150b 100644 --- a/net/quic/quic_session.cc +++ b/net/quic/quic_session.cc @@ -422,7 +422,7 @@ void QuicSession::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) { << "Handshake confirmed without parameter negotiation."; // Discard originally encrypted packets, since they can't be decrypted by // the peer. - connection_->NeuterUnencryptedPackets(); + connection_->DiscardUnencryptedPackets(); connection_->SetOverallConnectionTimeout(QuicTime::Delta::Infinite()); max_open_streams_ = config_.max_streams_per_connection(); break; diff --git a/net/quic/quic_session_test.cc b/net/quic/quic_session_test.cc index 25545ca..b2dfa0e 100644 --- a/net/quic/quic_session_test.cc +++ b/net/quic/quic_session_test.cc @@ -381,7 +381,7 @@ TEST_P(QuicSessionTest, OnCanWriteBundlesStreams) { QuicConnectionPeer::GetWriter(session_.connection())); EXPECT_CALL(*writer, WritePacket(_, _, _, _)).WillOnce( Return(WriteResult(WRITE_STATUS_OK, 0))); - EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _)); + EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _)); session_.OnCanWrite(); EXPECT_FALSE(session_.HasPendingWrites()); } diff --git a/net/quic/quic_stream_sequencer_test.cc b/net/quic/quic_stream_sequencer_test.cc index 1875e68..4abd94b 100644 --- a/net/quic/quic_stream_sequencer_test.cc +++ b/net/quic/quic_stream_sequencer_test.cc @@ -381,8 +381,7 @@ TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) { while (!list_.empty()) { int index = OneToN(list_.size()) - 1; - LOG(ERROR) << "Sending index " << index << " " - << list_[index].second.data(); + LOG(ERROR) << "Sending index " << index << " " << list_[index].second; EXPECT_TRUE(sequencer_->OnFrame(list_[index].first, list_[index].second.data())); diff --git a/net/quic/quic_unacked_packet_map.cc b/net/quic/quic_unacked_packet_map.cc index ddf30ec..d75991ed 100644 --- a/net/quic/quic_unacked_packet_map.cc +++ b/net/quic/quic_unacked_packet_map.cc @@ -91,7 +91,7 @@ void QuicUnackedPacketMap::ClearPreviousRetransmissions(size_t num_to_clear) { } ++it; - RemovePacket(sequence_number); + NeuterIfPendingOrRemovePacket(sequence_number); --num_to_clear; } } @@ -119,30 +119,7 @@ void QuicUnackedPacketMap::NackPacket(QuicPacketSequenceNumber sequence_number, it->second.nack_count = max(min_nacks, it->second.nack_count); } -void QuicUnackedPacketMap::RemovePacket( - QuicPacketSequenceNumber sequence_number) { - UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); - if (it == unacked_packets_.end()) { - LOG(DFATAL) << "packet is not unacked: " << sequence_number; - return; - } - const TransmissionInfo& transmission_info = it->second; - transmission_info.all_transmissions->erase(sequence_number); - if (transmission_info.all_transmissions->empty()) { - delete transmission_info.all_transmissions; - } - if (transmission_info.retransmittable_frames != NULL) { - if (transmission_info.retransmittable_frames->HasCryptoHandshake() - == IS_HANDSHAKE) { - --pending_crypto_packet_count_; - } - delete transmission_info.retransmittable_frames; - } - DCHECK(!transmission_info.pending); - unacked_packets_.erase(it); -} - -void QuicUnackedPacketMap::NeuterPacket( +void QuicUnackedPacketMap::NeuterIfPendingOrRemovePacket( QuicPacketSequenceNumber sequence_number) { UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); if (it == unacked_packets_.end()) { @@ -150,11 +127,6 @@ void QuicUnackedPacketMap::NeuterPacket( return; } TransmissionInfo* transmission_info = &it->second; - if (transmission_info->all_transmissions->size() > 1) { - transmission_info->all_transmissions->erase(sequence_number); - transmission_info->all_transmissions = new SequenceNumberSet(); - transmission_info->all_transmissions->insert(sequence_number); - } if (transmission_info->retransmittable_frames != NULL) { if (transmission_info->retransmittable_frames->HasCryptoHandshake() == IS_HANDSHAKE) { @@ -163,6 +135,21 @@ void QuicUnackedPacketMap::NeuterPacket( delete transmission_info->retransmittable_frames; transmission_info->retransmittable_frames = NULL; } + if (transmission_info->pending) { + // Neuter it so it can't be retransmitted. + if (transmission_info->all_transmissions->size() > 1) { + transmission_info->all_transmissions->erase(sequence_number); + transmission_info->all_transmissions = new SequenceNumberSet(); + transmission_info->all_transmissions->insert(sequence_number); + } + } else { + // Remove it. + transmission_info->all_transmissions->erase(sequence_number); + if (transmission_info->all_transmissions->empty()) { + delete transmission_info->all_transmissions; + } + unacked_packets_.erase(it); + } } // static diff --git a/net/quic/quic_unacked_packet_map.h b/net/quic/quic_unacked_packet_map.h index eab4f36..011760a 100644 --- a/net/quic/quic_unacked_packet_map.h +++ b/net/quic/quic_unacked_packet_map.h @@ -120,14 +120,10 @@ class NET_EXPORT_PRIVATE QuicUnackedPacketMap { // Returns true if there are any pending crypto packets. bool HasPendingCryptoPackets() const; - // Removes entries from the unacked packet map, and deletes - // the retransmittable frames associated with the packet. + // Deletes the retransmittable frames associated with the packet and removes + // it from unacked packets if it's not pending. // Does not remove any previous or subsequent transmissions of this packet. - void RemovePacket(QuicPacketSequenceNumber sequence_number); - - // Neuters the specified packet. Deletes any retransmittable - // frames, and sets all_transmissions to only include itself. - void NeuterPacket(QuicPacketSequenceNumber sequence_number); + void NeuterIfPendingOrRemovePacket(QuicPacketSequenceNumber sequence_number); // Returns true if the packet has been marked as sent by SetSent. static bool IsSentAndNotPending(const TransmissionInfo& transmission_info); diff --git a/net/quic/test_tools/delayed_verify_strike_register_client.cc b/net/quic/test_tools/delayed_verify_strike_register_client.cc index eec16b1..b14a118 100644 --- a/net/quic/test_tools/delayed_verify_strike_register_client.cc +++ b/net/quic/test_tools/delayed_verify_strike_register_client.cc @@ -29,7 +29,7 @@ void DelayedVerifyStrikeRegisterClient::VerifyNonceIsValidAndUnique( QuicWallTime now, ResultCallback* cb) { if (delay_verifications_) { - pending_verifications_.push_back(VerifyArgs(nonce.as_string(), now, cb)); + pending_verifications_.push_back(VerifyArgs(nonce, now, cb)); } else { LocalStrikeRegisterClient::VerifyNonceIsValidAndUnique(nonce, now, cb); } diff --git a/net/quic/test_tools/quic_sent_packet_manager_peer.cc b/net/quic/test_tools/quic_sent_packet_manager_peer.cc index 9984243..479711b 100644 --- a/net/quic/test_tools/quic_sent_packet_manager_peer.cc +++ b/net/quic/test_tools/quic_sent_packet_manager_peer.cc @@ -118,5 +118,11 @@ SequenceNumberSet QuicSentPacketManagerPeer::GetUnackedPackets( return sent_packet_manager->unacked_packets_.GetUnackedPackets(); } +// static +QuicByteCount QuicSentPacketManagerPeer::GetBytesInFlight( + const QuicSentPacketManager* sent_packet_manager) { + return sent_packet_manager->unacked_packets_.bytes_in_flight(); +} + } // namespace test } // namespace net diff --git a/net/quic/test_tools/quic_sent_packet_manager_peer.h b/net/quic/test_tools/quic_sent_packet_manager_peer.h index c4db12a..105388d 100644 --- a/net/quic/test_tools/quic_sent_packet_manager_peer.h +++ b/net/quic/test_tools/quic_sent_packet_manager_peer.h @@ -63,6 +63,9 @@ class QuicSentPacketManagerPeer { static SequenceNumberSet GetUnackedPackets( const QuicSentPacketManager* sent_packet_manager); + static QuicByteCount GetBytesInFlight( + const QuicSentPacketManager* sent_packet_manager); + private: DISALLOW_COPY_AND_ASSIGN(QuicSentPacketManagerPeer); }; diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h index f4074a5..4582a0e 100644 --- a/net/quic/test_tools/quic_test_utils.h +++ b/net/quic/test_tools/quic_test_utils.h @@ -404,9 +404,9 @@ class MockSendAlgorithm : public SendAlgorithmInterface { QuicByteCount bytes_in_flight, const CongestionMap& acked_packets, const CongestionMap& lost_packets)); - MOCK_METHOD4(OnPacketSent, - bool(QuicTime sent_time, QuicPacketSequenceNumber, QuicByteCount, - HasRetransmittableData)); + MOCK_METHOD5(OnPacketSent, + bool(QuicTime, QuicByteCount, QuicPacketSequenceNumber, + QuicByteCount, HasRetransmittableData)); MOCK_METHOD1(OnRetransmissionTimeout, void(bool)); MOCK_METHOD3(TimeUntilSend, QuicTime::Delta(QuicTime now, QuicByteCount bytes_in_flight, |