diff options
author | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-18 04:52:34 +0000 |
---|---|---|
committer | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-18 04:52:34 +0000 |
commit | c068020aaff82bcc4f36ff7a65f1f2fe4adef7b7 (patch) | |
tree | 1f0f284d51b9b994b89ef3a4407bea8d9ec53d71 | |
parent | 1f6a0aa92f0206545223d1c830b0867f01f273d0 (diff) | |
download | chromium_src-c068020aaff82bcc4f36ff7a65f1f2fe4adef7b7.zip chromium_src-c068020aaff82bcc4f36ff7a65f1f2fe4adef7b7.tar.gz chromium_src-c068020aaff82bcc4f36ff7a65f1f2fe4adef7b7.tar.bz2 |
Land Recent QUIC Changes.
Cleanup. Saner QuicConnectionTest around entropy hashes; initialize all
fields in QuicAckFrame.
Merge internal change: 58299852
https://codereview.chromium.org/107573005/
QUIC Cleanup to use GetRetransmissionTime() instead of
GetRetransmissionDelay() in SentPacketManager to allow the
SentPacketManager more future control over the retransmission timer.
Merge internal change: 58289241
https://codereview.chromium.org/116953002/
Added GetIncomingReliableStream method to QuicSessionPeer and other
cosmetic changes.
This is part of "Change the ownership model for ...QuicStream and
QuicFasterStatsGatherer" internal change.
Merge internal change: 58281240
https://codereview.chromium.org/114973006/
QuicSentPacketManager cleanup CL to move the handling of acks into one
place.
Merge internal change: 58181919
https://codereview.chromium.org/115933004/
R=rch@chromium.org
Review URL: https://codereview.chromium.org/100543004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@241489 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/quic/congestion_control/inter_arrival_sender_test.cc | 2 | ||||
-rw-r--r-- | net/quic/congestion_control/send_algorithm_interface.h | 9 | ||||
-rw-r--r-- | net/quic/quic_connection.cc | 59 | ||||
-rw-r--r-- | net/quic/quic_connection.h | 46 | ||||
-rw-r--r-- | net/quic/quic_connection_test.cc | 246 | ||||
-rw-r--r-- | net/quic/quic_framer.cc | 2 | ||||
-rw-r--r-- | net/quic/quic_http_stream_test.cc | 2 | ||||
-rw-r--r-- | net/quic/quic_protocol.cc | 10 | ||||
-rw-r--r-- | net/quic/quic_sent_packet_manager.cc | 144 | ||||
-rw-r--r-- | net/quic/quic_sent_packet_manager.h | 46 | ||||
-rw-r--r-- | net/quic/quic_sent_packet_manager_test.cc | 222 | ||||
-rw-r--r-- | net/quic/test_tools/quic_sent_packet_manager_peer.cc | 6 | ||||
-rw-r--r-- | net/quic/test_tools/quic_sent_packet_manager_peer.h | 3 | ||||
-rw-r--r-- | net/quic/test_tools/quic_session_peer.cc | 7 | ||||
-rw-r--r-- | net/quic/test_tools/quic_session_peer.h | 3 | ||||
-rw-r--r-- | net/quic/test_tools/reliable_quic_stream_peer.cc | 5 | ||||
-rw-r--r-- | net/quic/test_tools/reliable_quic_stream_peer.h | 1 | ||||
-rw-r--r-- | net/tools/quic/quic_server_session.h | 4 |
18 files changed, 351 insertions, 466 deletions
diff --git a/net/quic/congestion_control/inter_arrival_sender_test.cc b/net/quic/congestion_control/inter_arrival_sender_test.cc index fe8dd3c..7d9c39c 100644 --- a/net/quic/congestion_control/inter_arrival_sender_test.cc +++ b/net/quic/congestion_control/inter_arrival_sender_test.cc @@ -41,7 +41,7 @@ class InterArrivalSenderTest : public ::testing::Test { QuicByteCount bytes_in_packet = kDefaultMaxPacketSize; sent_packets_[sequence_number_] = new class SendAlgorithmInterface::SentPacket( - bytes_in_packet, send_clock_.Now(), HAS_RETRANSMITTABLE_DATA); + bytes_in_packet, send_clock_.Now()); sender_.OnPacketSent(send_clock_.Now(), sequence_number_, bytes_in_packet, NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); diff --git a/net/quic/congestion_control/send_algorithm_interface.h b/net/quic/congestion_control/send_algorithm_interface.h index 87a5f9c..44c943f 100644 --- a/net/quic/congestion_control/send_algorithm_interface.h +++ b/net/quic/congestion_control/send_algorithm_interface.h @@ -24,19 +24,13 @@ class NET_EXPORT_PRIVATE SendAlgorithmInterface { public: class SentPacket { public: - SentPacket(QuicByteCount bytes, - QuicTime timestamp, - HasRetransmittableData has_retransmittable_data) + SentPacket(QuicByteCount bytes, QuicTime timestamp) : bytes_sent_(bytes), send_timestamp_(timestamp), - has_retransmittable_data_(has_retransmittable_data), nack_count_(0) { } QuicByteCount bytes_sent() const { return bytes_sent_; } const QuicTime& send_timestamp() const { return send_timestamp_; } - HasRetransmittableData has_retransmittable_data() const { - return has_retransmittable_data_; - } size_t nack_count() const { return nack_count_; } void Nack(size_t min_nacks) { @@ -46,7 +40,6 @@ class NET_EXPORT_PRIVATE SendAlgorithmInterface { private: QuicByteCount bytes_sent_; QuicTime send_timestamp_; - HasRetransmittableData has_retransmittable_data_; size_t nack_count_; }; diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc index 51a83cc..5cc630d 100644 --- a/net/quic/quic_connection.cc +++ b/net/quic/quic_connection.cc @@ -506,12 +506,10 @@ void QuicConnection::ProcessAckFrame(const QuicAckFrame& incoming_ack) { if (reset_retransmission_alarm) { retransmission_alarm_->Cancel(); - // Reset the RTO and FEC alarms if the are unacked packets. - if (sent_packet_manager_.HasUnackedPackets()) { - QuicTime::Delta retransmission_delay = - sent_packet_manager_.GetRetransmissionDelay(); - retransmission_alarm_->Set( - clock_->ApproximateNow().Add(retransmission_delay)); + QuicTime retransmission_time = + sent_packet_manager_.GetRetransmissionTime(); + if (retransmission_time != QuicTime::Zero()) { + retransmission_alarm_->Set(retransmission_time); } } } @@ -1084,25 +1082,6 @@ bool QuicConnection::CanWrite(TransmissionType transmission_type, return true; } -void QuicConnection::SetupRetransmissionAlarm( - QuicPacketSequenceNumber sequence_number) { - if (!sent_packet_manager_.HasRetransmittableFrames(sequence_number)) { - DVLOG(1) << ENDPOINT << "Will not retransmit packet " << sequence_number; - return; - } - - // Do not set the retransmission alarm if we're already handling one, since - // it will be reset when OnRetransmissionTimeout completes. - if (retransmission_alarm_->IsSet()) { - return; - } - - QuicTime::Delta retransmission_delay = - sent_packet_manager_.GetRetransmissionDelay(); - retransmission_alarm_->Set( - clock_->ApproximateNow().Add(retransmission_delay)); -} - bool QuicConnection::WritePacket(EncryptionLevel level, QuicPacketSequenceNumber sequence_number, QuicPacket* packet, @@ -1297,13 +1276,6 @@ bool QuicConnection::OnPacketSent(WriteResult result) { DVLOG(1) << ENDPOINT << "time of last sent packet: " << now.ToDebuggingValue(); - // Set the retransmit alarm only when we have sent the packet to the client - // and not when it goes to the pending queue, otherwise we will end up adding - // an entry to retransmission_timeout_ every time we attempt a write. - if (retransmittable == HAS_RETRANSMITTABLE_DATA || is_fec_packet) { - SetupRetransmissionAlarm(sequence_number); - } - // TODO(ianswett): Change the sequence number length and other packet creator // options by a more explicit API than setting a struct value directly. packet_creator_.UpdateSequenceNumberLength( @@ -1314,6 +1286,19 @@ bool QuicConnection::OnPacketSent(WriteResult result) { sent_packet_manager_.OnPacketSent(sequence_number, now, length, transmission_type, retransmittable); + // Set the retransmit alarm only when we have sent the packet to the client + // and not when it goes to the pending queue, otherwise we will end up adding + // an entry to retransmission_timeout_ every time we attempt a write. + // Do not set the retransmission alarm if we're already handling one, since + // it will be reset when OnRetransmissionTimeout completes. + if ((retransmittable == HAS_RETRANSMITTABLE_DATA || is_fec_packet) && + !retransmission_alarm_->IsSet()) { + QuicTime retransmission_time = + sent_packet_manager_.GetRetransmissionTime(); + DCHECK(retransmission_time != QuicTime::Zero()); + retransmission_alarm_->Set(retransmission_time); + } + stats_.bytes_sent += result.bytes_written; ++stats_.packets_sent; @@ -1399,11 +1384,11 @@ void QuicConnection::OnRetransmissionTimeout() { WriteIfNotBlocked(); // Ensure the retransmission alarm is always set if there are unacked packets. - if (sent_packet_manager_.HasUnackedPackets() && !HasQueuedData() && - !retransmission_alarm_->IsSet()) { - QuicTime rto_timeout = clock_->ApproximateNow().Add( - sent_packet_manager_.GetRetransmissionDelay()); - retransmission_alarm_->Set(rto_timeout); + if (!HasQueuedData() && !retransmission_alarm_->IsSet()) { + QuicTime rto_timeout = sent_packet_manager_.GetRetransmissionTime(); + if (rto_timeout != QuicTime::Zero()) { + retransmission_alarm_->Set(rto_timeout); + } } } diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h index beb8985..b7cf2d2 100644 --- a/net/quic/quic_connection.h +++ b/net/quic/quic_connection.h @@ -502,37 +502,6 @@ class NET_EXPORT_PRIVATE QuicConnection Force forced; }; - struct RetransmissionInfo { - RetransmissionInfo(QuicPacketSequenceNumber sequence_number, - QuicSequenceNumberLength sequence_number_length, - QuicTime sent_time) - : sequence_number(sequence_number), - sequence_number_length(sequence_number_length), - sent_time(sent_time), - number_nacks(0), - number_retransmissions(0) { - } - - QuicPacketSequenceNumber sequence_number; - QuicSequenceNumberLength sequence_number_length; - QuicTime sent_time; - size_t number_nacks; - size_t number_retransmissions; - }; - - struct RetransmissionTime { - RetransmissionTime(QuicPacketSequenceNumber sequence_number, - const QuicTime& scheduled_time, - bool for_fec) - : sequence_number(sequence_number), - scheduled_time(scheduled_time), - for_fec(for_fec) { } - - QuicPacketSequenceNumber sequence_number; - QuicTime scheduled_time; - bool for_fec; - }; - struct PendingWrite { PendingWrite(QuicPacketSequenceNumber sequence_number, TransmissionType transmission_type, @@ -555,27 +524,12 @@ class NET_EXPORT_PRIVATE QuicConnection size_t length; }; - class RetransmissionTimeComparator { - public: - bool operator()(const RetransmissionTime& lhs, - const RetransmissionTime& rhs) const { - DCHECK(lhs.scheduled_time.IsInitialized() && - rhs.scheduled_time.IsInitialized()); - return lhs.scheduled_time > rhs.scheduled_time; - } - }; - typedef std::list<QueuedPacket> QueuedPacketList; typedef std::map<QuicFecGroupNumber, QuicFecGroup*> FecGroupMap; - typedef std::priority_queue<RetransmissionTime, - std::vector<RetransmissionTime>, - RetransmissionTimeComparator> - RetransmissionTimeouts; // Sends a version negotiation packet to the peer. void SendVersionNegotiationPacket(); - void SetupRetransmissionAlarm(QuicPacketSequenceNumber sequence_number); bool IsRetransmission(QuicPacketSequenceNumber sequence_number); void SetupAbandonFecTimer(QuicPacketSequenceNumber sequence_number); diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc index 39655d0..108cf04 100644 --- a/net/quic/quic_connection_test.cc +++ b/net/quic/quic_connection_test.cc @@ -31,6 +31,7 @@ using std::vector; using testing::_; using testing::AnyNumber; using testing::ContainerEq; +using testing::Contains; using testing::DoAll; using testing::InSequence; using testing::InvokeWithoutArgs; @@ -781,6 +782,40 @@ class QuicConnectionTest : public ::testing::TestWithParam<bool> { return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs/2); } + // Initialize a frame acknowledging all packets up to largest_observed. + const QuicAckFrame InitAckFrame(QuicPacketSequenceNumber largest_observed, + QuicPacketSequenceNumber least_unacked) { + QuicAckFrame frame(largest_observed, QuicTime::Zero(), least_unacked); + if (largest_observed > 0) { + frame.received_info.entropy_hash = + QuicConnectionPeer::GetSentEntropyHash(&connection_, largest_observed); + } + return frame; + } + + // Explicitly nack a packet. + void NackPacket(QuicPacketSequenceNumber missing, QuicAckFrame* frame) { + frame->received_info.missing_packets.insert(missing); + frame->received_info.entropy_hash ^= + QuicConnectionPeer::GetSentEntropyHash(&connection_, missing); + if (missing > 1) { + frame->received_info.entropy_hash ^= + QuicConnectionPeer::GetSentEntropyHash(&connection_, missing - 1); + } + } + + // Undo nacking a packet within the frame. + void AckPacket(QuicPacketSequenceNumber arrived, QuicAckFrame* frame) { + EXPECT_THAT(frame->received_info.missing_packets, Contains(arrived)); + frame->received_info.missing_packets.erase(arrived); + frame->received_info.entropy_hash ^= + QuicConnectionPeer::GetSentEntropyHash(&connection_, arrived); + if (arrived > 1) { + frame->received_info.entropy_hash ^= + QuicConnectionPeer::GetSentEntropyHash(&connection_, arrived - 1); + } + } + QuicGuid guid_; QuicFramer framer_; QuicPacketCreator creator_; @@ -892,7 +927,7 @@ TEST_F(QuicConnectionTest, PacketsOutOfOrderWithAdditionsAndLeastAwaiting) { // awaiting' is 4. The connection should then realize 1 will not be // retransmitted, and will remove it from the missing list. creator_.set_sequence_number(5); - QuicAckFrame frame(0, QuicTime::Zero(), 4); + QuicAckFrame frame = InitAckFrame(0, 4); ProcessAckPacket(&frame); // Force an ack to be sent. @@ -914,12 +949,11 @@ TEST_F(QuicConnectionTest, TruncatedAck) { SendStreamDataToPeer(1, "foo", i * 3, !kFin, NULL); } - QuicAckFrame frame(num_packets, QuicTime::Zero(), 1); + QuicAckFrame frame = InitAckFrame(num_packets, 1); // Create an ack with 256 nacks, none adjacent to one another. for (QuicPacketSequenceNumber i = 1; i <= 256; ++i) { - frame.received_info.missing_packets.insert(i * 2); + NackPacket(i * 2, &frame); } - frame.received_info.entropy_hash = 0; EXPECT_CALL(entropy_calculator_, EntropyHash(511)).WillOnce(testing::Return(0)); EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(256); @@ -933,8 +967,7 @@ TEST_F(QuicConnectionTest, TruncatedAck) { EXPECT_GT(num_packets, received_packet_manager->peer_largest_observed_packet()); - frame.received_info.missing_packets.erase(192); - frame.received_info.entropy_hash = 2; + AckPacket(192, &frame); // Removing one missing packet allows us to ack 192 and one more range. EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(2); @@ -962,7 +995,7 @@ TEST_F(QuicConnectionTest, AckReceiptCausesAckSendBadEntropy) { testing::Return(QuicTime::Delta::Zero())); // Skip a packet and then record an ack. creator_.set_sequence_number(2); - QuicAckFrame frame(0, QuicTime::Zero(), 3); + QuicAckFrame frame = InitAckFrame(0, 3); ProcessAckPacket(&frame); } @@ -996,10 +1029,8 @@ TEST_F(QuicConnectionTest, AckReceiptCausesAckSend) { Return(true))); EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1); connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL); - QuicAckFrame frame(original, QuicTime::Zero(), 1); - frame.received_info.missing_packets.insert(original); - frame.received_info.entropy_hash = QuicConnectionPeer::GetSentEntropyHash( - &connection_, original - 1); + QuicAckFrame frame = InitAckFrame(original, 1); + NackPacket(original, &frame); // First nack triggers early retransmit. QuicPacketSequenceNumber retransmission; EXPECT_CALL(*send_algorithm_, @@ -1009,11 +1040,8 @@ TEST_F(QuicConnectionTest, AckReceiptCausesAckSend) { ProcessAckPacket(&frame); - QuicAckFrame frame2(retransmission, QuicTime::Zero(), 1); - frame2.received_info.missing_packets.insert(original); - frame2.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, retransmission) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, original); + QuicAckFrame frame2 = InitAckFrame(retransmission, 1); + NackPacket(original, &frame2); EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)); ProcessAckPacket(&frame2); @@ -1024,9 +1052,7 @@ TEST_F(QuicConnectionTest, AckReceiptCausesAckSend) { ProcessAckPacket(&frame2); // But an ack with no missing packets will not send an ack. - frame2.received_info.missing_packets.clear(); - frame2.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, retransmission); + AckPacket(original, &frame2); ProcessAckPacket(&frame2); ProcessAckPacket(&frame2); } @@ -1040,13 +1066,13 @@ TEST_F(QuicConnectionTest, LeastUnackedLower) { // Start out saying the least unacked is 2. creator_.set_sequence_number(5); - QuicAckFrame frame(0, QuicTime::Zero(), 2); + QuicAckFrame frame = InitAckFrame(0, 2); ProcessAckPacket(&frame); // Change it to 1, but lower the sequence number to fake out-of-order packets. // This should be fine. creator_.set_sequence_number(1); - QuicAckFrame frame2(0, QuicTime::Zero(), 1); + QuicAckFrame frame2 = InitAckFrame(0, 1); // The scheduler will not process out of order acks. EXPECT_CALL(visitor_, OnCanWrite()).Times(0); ProcessAckPacket(&frame2); @@ -1068,16 +1094,14 @@ TEST_F(QuicConnectionTest, LargestObservedLower) { EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(2); // Start out saying the largest observed is 2. - QuicAckFrame frame(2, QuicTime::Zero(), 0); - frame.received_info.entropy_hash = QuicConnectionPeer::GetSentEntropyHash( - &connection_, 2); - ProcessAckPacket(&frame); + QuicAckFrame frame1 = InitAckFrame(1, 0); + QuicAckFrame frame2 = InitAckFrame(2, 0); + ProcessAckPacket(&frame2); // Now change it to 1, and it should cause a connection error. - QuicAckFrame frame2(1, QuicTime::Zero(), 0); EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_INVALID_ACK_DATA, false)); EXPECT_CALL(visitor_, OnCanWrite()).Times(0); - ProcessAckPacket(&frame2); + ProcessAckPacket(&frame1); } TEST_F(QuicConnectionTest, AckUnsentData) { @@ -1095,7 +1119,7 @@ TEST_F(QuicConnectionTest, AckAll) { ProcessPacket(1); creator_.set_sequence_number(1); - QuicAckFrame frame1(0, QuicTime::Zero(), 1); + QuicAckFrame frame1 = InitAckFrame(0, 1); ProcessAckPacket(&frame1); } @@ -1218,9 +1242,7 @@ TEST_F(QuicConnectionTest, BasicSending) { EXPECT_EQ(1u, last_ack()->sent_info.least_unacked); // Peer acks up to packet 3. - QuicAckFrame frame(3, QuicTime::Zero(), 0); - frame.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, 3); + QuicAckFrame frame = InitAckFrame(3, 0); ProcessAckPacket(&frame); SendAckPacketToPeer(); // Packet 6 @@ -1229,9 +1251,7 @@ TEST_F(QuicConnectionTest, BasicSending) { EXPECT_EQ(4u, last_ack()->sent_info.least_unacked); // Peer acks up to packet 4, the last packet. - QuicAckFrame frame2(6, QuicTime::Zero(), 0); - frame2.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, 6); + QuicAckFrame frame2 = InitAckFrame(6, 0); ProcessAckPacket(&frame2); // Acks don't instigate acks. // Verify that we did not send an ack. @@ -1248,7 +1268,7 @@ TEST_F(QuicConnectionTest, BasicSending) { SendStreamDataToPeer(1, "eep", 6, !kFin, &last_packet); // Packet 8 EXPECT_EQ(8u, last_packet); SendAckPacketToPeer(); // Packet 9 - EXPECT_EQ(8u, last_ack()->sent_info.least_unacked); + EXPECT_EQ(7u, last_ack()->sent_info.least_unacked); } TEST_F(QuicConnectionTest, FECSending) { @@ -1318,19 +1338,14 @@ TEST_F(QuicConnectionTest, DontAbandonAckedFEC) { connection_.SendStreamDataWithString(1, "foo", 3, !kFin, NULL); connection_.SendStreamDataWithString(1, "foo", 6, !kFin, NULL); - QuicAckFrame ack_fec(2, QuicTime::Zero(), 1); + QuicAckFrame ack_fec = InitAckFrame(2, 1); // Data packet missing. // TODO(ianswett): Note that this is not a sensible ack, since if the FEC was // received, it would cause the covered packet to be acked as well. - ack_fec.received_info.missing_packets.insert(1); - ack_fec.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, 2) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, 1); + NackPacket(1, &ack_fec); EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(1); - ProcessAckPacket(&ack_fec); - clock_.AdvanceTime(DefaultRetransmissionTime()); // Don't abandon the acked FEC packet, but it will abandon 2 the subsequent @@ -1354,16 +1369,10 @@ TEST_F(QuicConnectionTest, DontAbandonAllFEC) { clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); connection_.SendStreamDataWithString(1, "foo", 6, !kFin, NULL); - QuicAckFrame ack_fec(5, QuicTime::Zero(), 1); + QuicAckFrame ack_fec = InitAckFrame(5, 1); // Ack all data packets, but no fec packets. - ack_fec.received_info.missing_packets.insert(2); - ack_fec.received_info.missing_packets.insert(4); - ack_fec.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, 5) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, 4) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, 3) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, 2) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, 1); + NackPacket(2, &ack_fec); + NackPacket(4, &ack_fec); // Lose the first FEC packet and ack the three data packets. EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(3); @@ -1520,7 +1529,7 @@ TEST_F(QuicConnectionTest, FramePackingAckResponse) { // Process an ack to cause the visitor's OnCanWrite to be invoked. creator_.set_sequence_number(2); - QuicAckFrame ack_one(0, QuicTime::Zero(), 0); + QuicAckFrame ack_one = InitAckFrame(0, 0); ProcessAckPacket(&ack_one); EXPECT_EQ(0u, connection_.NumQueuedPackets()); @@ -1644,21 +1653,15 @@ TEST_F(QuicConnectionTest, RetransmitOnNack) { // Peer acks one but not two or three. Right now we only retransmit on // explicit nack, so it should not trigger a retransmission. - QuicAckFrame ack_one(1, QuicTime::Zero(), 0); - ack_one.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, 1); + QuicAckFrame ack_one = InitAckFrame(1, 0); ProcessAckPacket(&ack_one); ProcessAckPacket(&ack_one); ProcessAckPacket(&ack_one); // Peer acks up to 3 with two explicitly missing. // Early retransmit causes 2 to be retransmitted on the first ack. - QuicAckFrame nack_two(3, QuicTime::Zero(), 0); - nack_two.received_info.missing_packets.insert(2); - nack_two.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, 3) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, 2) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, 1); + QuicAckFrame nack_two = InitAckFrame(3, 0); + NackPacket(2, &nack_two); // The third nack should trigger a retransmission. EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, second_packet_size - kQuicVersionSize, @@ -1679,21 +1682,15 @@ TEST_F(QuicConnectionTest, DiscardRetransmit) { // Peer acks one but not two or three. Right now we only retransmit on // explicit nack, so it should not trigger a retransmission. - QuicAckFrame ack_one(1, QuicTime::Zero(), 0); - ack_one.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, 1); + QuicAckFrame ack_one = InitAckFrame(1, 0); ProcessAckPacket(&ack_one); ProcessAckPacket(&ack_one); ProcessAckPacket(&ack_one); // Peer acks up to 3 with two explicitly missing. Two nacks should cause no // change. - QuicAckFrame nack_two(3, QuicTime::Zero(), 0); - nack_two.received_info.missing_packets.insert(2); - nack_two.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, 3) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, 2) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, 1); + QuicAckFrame nack_two = InitAckFrame(3, 0); + NackPacket(2, &nack_two); // The first nack should trigger a fast retransmission, but we'll be // write blocked, so the packet will be queued. writer_->set_blocked(true); @@ -1702,9 +1699,7 @@ TEST_F(QuicConnectionTest, DiscardRetransmit) { EXPECT_EQ(1u, connection_.NumQueuedPackets()); // Now, ack the previous transmission. - QuicAckFrame ack_all(3, QuicTime::Zero(), 0); - ack_all.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, 3); + QuicAckFrame ack_all = InitAckFrame(3, 0); ProcessAckPacket(&ack_all); // Unblock the socket and attempt to send the queued packets. However, @@ -1729,10 +1724,8 @@ TEST_F(QuicConnectionTest, RetransmitNackedLargestObserved) { Return(true))); EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1); connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL); - QuicAckFrame frame(1, QuicTime::Zero(), largest_observed); - frame.received_info.missing_packets.insert(largest_observed); - frame.received_info.entropy_hash = QuicConnectionPeer::GetSentEntropyHash( - &connection_, largest_observed - 1); + QuicAckFrame frame = InitAckFrame(1, largest_observed); + NackPacket(largest_observed, &frame); // The first nack should retransmit the largest observed packet. EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, packet_size - kQuicVersionSize, @@ -1802,15 +1795,11 @@ TEST_F(QuicConnectionTest, LimitPacketsPerNack) { } // Ack 15, nack 1-14. - QuicAckFrame nack(15, QuicTime::Zero(), 0); + QuicAckFrame nack = InitAckFrame(15, 0); for (int i = 1; i < 15; ++i) { - nack.received_info.missing_packets.insert(i); + NackPacket(i, &nack); } - nack.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, 15) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, 14); - // 13 packets have been NACK'd 3 times, but we limit retransmissions to 2. EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(2); EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2); @@ -1839,34 +1828,26 @@ TEST_F(QuicConnectionTest, MultipleAcks) { EXPECT_EQ(6u, last_packet); // Client will ack packets 1, 2, [!3], 4, 5. - QuicAckFrame frame1(5, QuicTime::Zero(), 0); - frame1.received_info.missing_packets.insert(3); - frame1.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, 5) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, 3) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, 2); - + QuicAckFrame frame1 = InitAckFrame(5, 0); + NackPacket(3, &frame1); EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); - ProcessAckPacket(&frame1); // Now the client implicitly acks 3, and explicitly acks 6. - QuicAckFrame frame2(6, QuicTime::Zero(), 0); - frame2.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, 6); - + QuicAckFrame frame2 = InitAckFrame(6, 0); ProcessAckPacket(&frame2); } TEST_F(QuicConnectionTest, DontLatchUnackedPacket) { EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(1); SendStreamDataToPeer(1, "foo", 0, !kFin, NULL); // Packet 1; + // From now on, we send acks, so the send algorithm won't save them. + ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) + .WillByDefault(Return(false)); SendAckPacketToPeer(); // Packet 2 EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); - QuicAckFrame frame(1, QuicTime::Zero(), 0); - frame.received_info.entropy_hash = QuicConnectionPeer::GetSentEntropyHash( - &connection_, 1); + QuicAckFrame frame = InitAckFrame(1, 0); ProcessAckPacket(&frame); // Verify that our internal state has least-unacked as 3. @@ -1881,8 +1862,12 @@ TEST_F(QuicConnectionTest, DontLatchUnackedPacket) { // Check that the outgoing ack had its sequence number as least_unacked. EXPECT_EQ(3u, last_ack()->sent_info.least_unacked); + 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(_, _, _, _, _)) + .WillByDefault(Return(false)); SendAckPacketToPeer(); // Packet 5 EXPECT_EQ(4u, last_ack()->sent_info.least_unacked); } @@ -2175,15 +2160,10 @@ TEST_F(QuicConnectionTest, RetransmissionCountCalculation) { .Times(AnyNumber()); EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, NACK_RETRANSMISSION, _)) .WillOnce(DoAll(SaveArg<1>(&nack_sequence_number), Return(true))); - QuicAckFrame ack(rto_sequence_number, QuicTime::Zero(), 0); + QuicAckFrame ack = InitAckFrame(rto_sequence_number, 0); // Ack the retransmitted packet. - ack.received_info.missing_packets.insert(original_sequence_number); - ack.received_info.missing_packets.insert(rto_sequence_number); - ack.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, - rto_sequence_number - 1) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, - original_sequence_number); + NackPacket(original_sequence_number, &ack); + NackPacket(rto_sequence_number, &ack); for (int i = 0; i < 3; i++) { ProcessAckPacket(&ack); } @@ -2221,9 +2201,7 @@ TEST_F(QuicConnectionTest, DelayRTOWithAckReceipt) { // packet to delay the RTO. clock_.AdvanceTime(DefaultRetransmissionTime()); EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(1); - QuicAckFrame ack(1, QuicTime::Zero(), 0); - ack.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, 1); + QuicAckFrame ack = InitAckFrame(1, 0); ProcessAckPacket(&ack); EXPECT_TRUE(retransmission_alarm->IsSet()); @@ -2276,7 +2254,7 @@ TEST_F(QuicConnectionTest, CloseFecGroup) { ASSERT_EQ(1u, connection_.NumFecGroups()); // Now send non-fec protected ack packet and close the group. - QuicAckFrame frame(0, QuicTime::Zero(), 5); + QuicAckFrame frame = InitAckFrame(0, 5); creator_.set_sequence_number(4); ProcessAckPacket(&frame); ASSERT_EQ(0u, connection_.NumFecGroups()); @@ -2504,7 +2482,7 @@ TEST_F(QuicConnectionTest, SendSchedulerDelayThenAckAndSend) { // Now send non-retransmitting information, that we're not going to // retransmit 3. The far end should stop waiting for it. - QuicAckFrame frame(0, QuicTime::Zero(), 1); + QuicAckFrame frame = InitAckFrame(0, 1); EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, NOT_RETRANSMISSION, _, _)).WillRepeatedly( testing::Return(QuicTime::Delta::Zero())); @@ -2529,7 +2507,7 @@ TEST_F(QuicConnectionTest, SendSchedulerDelayThenAckAndHold) { // Now send non-retransmitting information, that we're not going to // retransmit 3. The far end should stop waiting for it. - QuicAckFrame frame(0, QuicTime::Zero(), 1); + QuicAckFrame frame = InitAckFrame(0, 1); EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, NOT_RETRANSMISSION, _, _)).WillOnce( testing::Return(QuicTime::Delta::FromMicroseconds(1))); @@ -2715,7 +2693,7 @@ TEST_F(QuicConnectionTest, InvalidPacket) { } TEST_F(QuicConnectionTest, MissingPacketsBeforeLeastUnacked) { - QuicAckFrame ack(0, QuicTime::Zero(), 4); + QuicAckFrame ack = InitAckFrame(0, 4); // Set the sequence number of the ack packet to be least unacked (4). creator_.set_sequence_number(3); EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); @@ -2741,7 +2719,7 @@ TEST_F(QuicConnectionTest, UpdateEntropyForReceivedPackets) { ProcessDataPacket(4, 1, !kEntropyFlag); EXPECT_EQ(34u, outgoing_ack()->received_info.entropy_hash); // Make 4th packet my least unacked, and update entropy for 2, 3 packets. - QuicAckFrame ack(0, QuicTime::Zero(), 4); + QuicAckFrame ack = InitAckFrame(0, 4); QuicPacketEntropyHash kRandomEntropyHash = 129u; ack.sent_info.entropy_hash = kRandomEntropyHash; creator_.set_sequence_number(5); @@ -2764,7 +2742,7 @@ TEST_F(QuicConnectionTest, UpdateEntropyHashUptoCurrentPacket) { creator_.set_sequence_number(22); QuicPacketEntropyHash kRandomEntropyHash = 85u; // Current packet is the least unacked packet. - QuicAckFrame ack(0, QuicTime::Zero(), 23); + QuicAckFrame ack = InitAckFrame(0, 23); ack.sent_info.entropy_hash = kRandomEntropyHash; QuicPacketEntropyHash ack_entropy_hash = ProcessAckPacket(&ack); EXPECT_EQ((kRandomEntropyHash + ack_entropy_hash), @@ -3034,14 +3012,9 @@ TEST_F(QuicConnectionTest, CheckSendStats) { connection_.GetRetransmissionAlarm()->Fire(); // Retransmit due to explicit nacks. - QuicAckFrame nack_three(4, QuicTime::Zero(), 0); - nack_three.received_info.missing_packets.insert(3); - nack_three.received_info.missing_packets.insert(1); - nack_three.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, 4) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, 3) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, 2) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, 1); + QuicAckFrame nack_three = InitAckFrame(4, 0); + NackPacket(3, &nack_three); + NackPacket(1, &nack_three); QuicFrame frame(&nack_three); EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(1); EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(1); @@ -3222,9 +3195,7 @@ TEST_F(QuicConnectionTest, AckNotifierTriggerCallback) { // Process an ACK from the server which should trigger the callback. EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(1); - QuicAckFrame frame(1, QuicTime::Zero(), 0); - frame.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, 1); + QuicAckFrame frame = InitAckFrame(1, 0); ProcessAckPacket(&frame); } @@ -3247,11 +3218,8 @@ TEST_F(QuicConnectionTest, AckNotifierFailToTriggerCallback) { // Now we receive ACK for packets 2 and 3, but importantly missing packet 1 // which we registered to be notified about. - QuicAckFrame frame(3, QuicTime::Zero(), 0); - frame.received_info.missing_packets.insert(1); - frame.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, 3) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, 1); + QuicAckFrame frame = InitAckFrame(3, 0); + NackPacket(1, &frame); EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)); EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)); ProcessAckPacket(&frame); @@ -3274,12 +3242,8 @@ TEST_F(QuicConnectionTest, AckNotifierCallbackAfterRetransmission) { connection_.SendStreamDataWithString(1, "qux", 0, !kFin, NULL); // Now we receive ACK for packets 1, 3, and 4, which invokes fast retransmit. - QuicAckFrame frame(4, QuicTime::Zero(), 0); - frame.received_info.missing_packets.insert(2); - frame.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, 4) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, 2) ^ - QuicConnectionPeer::GetSentEntropyHash(&connection_, 1); + QuicAckFrame frame = InitAckFrame(4, 0); + NackPacket(2, &frame); EXPECT_CALL(*send_algorithm_, OnPacketLost(2, _)); EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(2, _)); EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); @@ -3287,9 +3251,7 @@ TEST_F(QuicConnectionTest, AckNotifierCallbackAfterRetransmission) { // Now we get an ACK for packet 5 (retransmitted packet 2), which should // trigger the callback. - QuicAckFrame second_ack_frame(5, QuicTime::Zero(), 0); - second_ack_frame.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, 5); + QuicAckFrame second_ack_frame = InitAckFrame(5, 0); ProcessAckPacket(&second_ack_frame); } @@ -3313,9 +3275,7 @@ TEST_F(QuicConnectionTest, AckNotifierCallbackAfterFECRecovery) { // Should recover the Ack packet and trigger the notification callback. QuicFrames frames; - QuicAckFrame ack_frame(1, QuicTime::Zero(), 0); - ack_frame.received_info.entropy_hash = - QuicConnectionPeer::GetSentEntropyHash(&connection_, 1); + QuicAckFrame ack_frame = InitAckFrame(1, 0); frames.push_back(QuicFrame(&ack_frame)); // Dummy stream frame to satisfy expectations set elsewhere. diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc index cc02882..610dc57 100644 --- a/net/quic/quic_framer.cc +++ b/net/quic/quic_framer.cc @@ -2070,7 +2070,7 @@ bool QuicFramer::AppendGoAwayFramePayload(const QuicGoAwayFrame& frame, } bool QuicFramer::RaiseError(QuicErrorCode error) { - DVLOG(1) << detailed_error_; + DVLOG(1) << "Error detail: " << detailed_error_; set_error(error); visitor_->OnError(this); reader_.reset(NULL); diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc index 97ae972..ad14ee1 100644 --- a/net/quic/quic_http_stream_test.cc +++ b/net/quic/quic_http_stream_test.cc @@ -190,7 +190,7 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<bool> { EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _, _)). Times(AnyNumber()); EXPECT_CALL(*send_algorithm_, - OnPacketSent(_, _, _, _, _)).Times(AnyNumber()); + OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true)); EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( Return(QuicTime::Delta::Zero())); EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)). diff --git a/net/quic/quic_protocol.cc b/net/quic/quic_protocol.cc index cc37c11..e53daec 100644 --- a/net/quic/quic_protocol.cc +++ b/net/quic/quic_protocol.cc @@ -210,10 +210,10 @@ ostream& operator<<(ostream& os, const QuicPacketHeader& header) { } ReceivedPacketInfo::ReceivedPacketInfo() - : largest_observed(0), + : entropy_hash(0), + largest_observed(0), delta_time_largest_observed(QuicTime::Delta::Infinite()), - is_truncated(false) { -} + is_truncated(false) {} ReceivedPacketInfo::~ReceivedPacketInfo() {} @@ -231,7 +231,9 @@ void InsertMissingPacketsBetween(ReceivedPacketInfo* received_info, } } -SentPacketInfo::SentPacketInfo() {} +SentPacketInfo::SentPacketInfo() + : entropy_hash(0), + least_unacked(0) {} SentPacketInfo::~SentPacketInfo() {} diff --git a/net/quic/quic_sent_packet_manager.cc b/net/quic/quic_sent_packet_manager.cc index bda30c7..bb7f496 100644 --- a/net/quic/quic_sent_packet_manager.cc +++ b/net/quic/quic_sent_packet_manager.cc @@ -104,16 +104,14 @@ void QuicSentPacketManager::SetMaxPacketSize(QuicByteCount max_packet_size) { send_algorithm_->SetMaxPacketSize(max_packet_size); } +// TODO(ianswett): Combine this method with OnPacketSent once packets are always +// sent in order and the connection tracks RetransmittableFrames for longer. void QuicSentPacketManager::OnSerializedPacket( const SerializedPacket& serialized_packet) { - if (serialized_packet.retransmittable_frames == NULL && - !serialized_packet.packet->is_fec_packet()) { - // Don't track ack/congestion feedback packets. - return; + if (serialized_packet.retransmittable_frames) { + ack_notifier_manager_.OnSerializedPacket(serialized_packet); } - ack_notifier_manager_.OnSerializedPacket(serialized_packet); - DCHECK(unacked_packets_.empty() || unacked_packets_.rbegin()->first < serialized_packet.sequence_number); unacked_packets_[serialized_packet.sequence_number] = @@ -130,6 +128,7 @@ void QuicSentPacketManager::OnRetransmittedPacket( unacked_packets_.rbegin()->first < new_sequence_number); pending_retransmissions_.erase(old_sequence_number); + // TODO(ianswett): Discard and lose the packet lazily instead of immediately. UnackedPacketMap::iterator unacked_it = unacked_packets_.find(old_sequence_number); @@ -172,16 +171,9 @@ bool QuicSentPacketManager::OnIncomingAck( bool new_least_unacked = !IsAwaitingPacket(received_info, least_unacked_sent_before); + MaybeUpdateRTT(received_info, ack_receive_time); HandleAckForSentPackets(received_info); - - SequenceNumberSet retransmission_packets = - OnIncomingAckFrame(received_info, ack_receive_time); - - for (SequenceNumberSet::const_iterator it = retransmission_packets.begin(); - it != retransmission_packets.end(); ++it) { - DCHECK(!ContainsKey(pending_packets_, *it)); - MarkForRetransmission(*it, NACK_RETRANSMISSION); - } + MaybeRetransmitOnAckFrame(received_info, ack_receive_time); if (new_least_unacked) { consecutive_rto_count_ = 0; @@ -192,7 +184,7 @@ bool QuicSentPacketManager::OnIncomingAck( void QuicSentPacketManager::DiscardUnackedPacket( QuicPacketSequenceNumber sequence_number) { - MarkPacketReceivedByPeer(sequence_number); + MarkPacketHandled(sequence_number, NOT_RECEIVED_BY_PEER); } void QuicSentPacketManager::HandleAckForSentPackets( @@ -216,7 +208,7 @@ void QuicSentPacketManager::HandleAckForSentPackets( DVLOG(1) << ENDPOINT <<"Got an ack for packet " << sequence_number; // If data is associated with the most recent transmission of this // packet, then inform the caller. - it = MarkPacketReceivedByPeer(sequence_number); + it = MarkPacketHandled(sequence_number, RECEIVED_BY_PEER); // The AckNotifierManager is informed of every ACKed sequence number. ack_notifier_manager_.OnPacketAcked(sequence_number); @@ -287,29 +279,28 @@ void QuicSentPacketManager::RetransmitUnackedPackets( // TODO(satyamshekhar): Think about congestion control here. // Specifically, about the retransmission count of packets being sent // proactively to achieve 0 (minimal) RTT. - OnPacketAbandoned(unacked_it->first); - if (!MarkForRetransmission(unacked_it->first, NACK_RETRANSMISSION)) { + if (unacked_it->second.retransmittable_frames) { + OnPacketAbandoned(unacked_it->first); + MarkForRetransmission(unacked_it->first, NACK_RETRANSMISSION); + } else { DiscardUnackedPacket(unacked_it->first); } } } } -bool QuicSentPacketManager::MarkForRetransmission( +void QuicSentPacketManager::MarkForRetransmission( QuicPacketSequenceNumber sequence_number, TransmissionType transmission_type) { DCHECK(ContainsKey(unacked_packets_, sequence_number)); - if (!HasRetransmittableFrames(sequence_number)) { - return false; - } - // If it's already in the retransmission map, don't add it again, just let - // the prior retransmission request win out. + DCHECK(HasRetransmittableFrames(sequence_number)); + // TODO(ianswett): Currently the RTO can fire while there are pending NACK + // retransmissions for the same data, which is not ideal. if (ContainsKey(pending_retransmissions_, sequence_number)) { - return true; + return; } pending_retransmissions_[sequence_number] = transmission_type; - return true; } bool QuicSentPacketManager::HasPendingRetransmissions() const { @@ -347,10 +338,21 @@ bool QuicSentPacketManager::IsPreviousTransmission( } QuicSentPacketManager::UnackedPacketMap::iterator -QuicSentPacketManager::MarkPacketReceivedByPeer( - QuicPacketSequenceNumber sequence_number) { +QuicSentPacketManager::MarkPacketHandled( + QuicPacketSequenceNumber sequence_number, ReceivedByPeer received_by_peer) { DCHECK(ContainsKey(unacked_packets_, sequence_number)); + // If this packet is pending, remove it and inform the send algorithm. + if (pending_packets_.erase(sequence_number)) { + size_t bytes_sent = packet_history_map_[sequence_number]->bytes_sent(); + if (received_by_peer == RECEIVED_BY_PEER) { + send_algorithm_->OnPacketAcked(sequence_number, bytes_sent, rtt_sample_); + } else { + // It's been abandoned. + send_algorithm_->OnPacketAbandoned(sequence_number, bytes_sent); + } + } + // If this packet has never been retransmitted, then simply drop it. UnackedPacketMap::const_iterator previous_it = unacked_packets_.find(sequence_number); @@ -470,18 +472,20 @@ void QuicSentPacketManager::OnPacketSent( HasRetransmittableData has_retransmittable_data) { DCHECK_LT(0u, sequence_number); DCHECK(!ContainsKey(pending_packets_, sequence_number)); - if (ContainsKey(unacked_packets_, sequence_number)) { - unacked_packets_[sequence_number].sent_time = sent_time; - } + DCHECK(ContainsKey(unacked_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)) { + DCHECK(unacked_packets_[sequence_number].retransmittable_frames == NULL); + unacked_packets_.erase(sequence_number); return; } - packet_history_map_[sequence_number] = new SendAlgorithmInterface::SentPacket( - bytes, sent_time, has_retransmittable_data); + + unacked_packets_[sequence_number].sent_time = sent_time; + packet_history_map_[sequence_number] = + new SendAlgorithmInterface::SentPacket(bytes, sent_time); pending_packets_.insert(sequence_number); CleanupPacketHistory(); } @@ -492,23 +496,6 @@ void QuicSentPacketManager::OnRetransmissionTimeout() { QuicTime::Delta retransmission_delay = GetRetransmissionDelay(); QuicTime max_send_time = clock_->ApproximateNow().Subtract(retransmission_delay); - for (SequenceNumberSet::iterator it = pending_packets_.begin(); - it != pending_packets_.end();) { - QuicPacketSequenceNumber sequence_number = *it; - DCHECK(ContainsKey(packet_history_map_, sequence_number)); - DCHECK(ContainsKey(unacked_packets_, sequence_number)); - const TransmissionInfo& transmission_info = - unacked_packets_.find(sequence_number)->second; - // Abandon retransmittable packet and old non-retransmittable packets. - if (transmission_info.retransmittable_frames || - transmission_info.sent_time <= max_send_time) { - pending_packets_.erase(it++); - send_algorithm_->OnPacketAbandoned( - sequence_number, packet_history_map_[sequence_number]->bytes_sent()); - } else { - ++it; - } - } // Attempt to send all the unacked packets when the RTO fires, let the // congestion manager decide how many to send immediately and the remaining @@ -516,13 +503,16 @@ void QuicSentPacketManager::OnRetransmissionTimeout() { DVLOG(1) << "OnRetransmissionTimeout() fired with " << unacked_packets_.size() << " unacked packets."; - // Retransmit any packet with retransmittable frames. + // Retransmit any packet with retransmittable frames and abandon the rest. bool packets_retransmitted = false; for (UnackedPacketMap::const_iterator it = unacked_packets_.begin(); it != unacked_packets_.end(); ++it) { if (it->second.retransmittable_frames != NULL) { + OnPacketAbandoned(it->first); packets_retransmitted = true; MarkForRetransmission(it->first, RTO_RETRANSMISSION); + } else if (it->second.sent_time <= max_send_time) { + OnPacketAbandoned(it->first); } } @@ -551,38 +541,28 @@ void QuicSentPacketManager::OnIncomingQuicCongestionFeedbackFrame( frame, feedback_receive_time, packet_history_map_); } -SequenceNumberSet QuicSentPacketManager::OnIncomingAckFrame( +void QuicSentPacketManager::MaybeRetransmitOnAckFrame( const ReceivedPacketInfo& received_info, const QuicTime& ack_receive_time) { - MaybeUpdateRTT(received_info, ack_receive_time); - - // We want to. - // * Get all packets lower(including) than largest_observed - // from pending_packets_. - // * Remove all packets no longer being waited for(ie: acked). - // * Send each ACK in the list to send_algorithm_. + // Go through all pending packets up to the largest observed and see if any + // need to be retransmitted or lost. SequenceNumberSet::iterator it = pending_packets_.begin(); SequenceNumberSet::iterator it_upper = pending_packets_.upper_bound(received_info.largest_observed); - SequenceNumberSet retransmission_packets; + size_t num_retransmitted = 0; SequenceNumberSet lost_packets; while (it != it_upper) { QuicPacketSequenceNumber sequence_number = *it; + 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)); + DCHECK(ContainsKey(packet_history_map_, sequence_number)); const SendAlgorithmInterface::SentPacket* sent_packet = packet_history_map_[sequence_number]; - if (!IsAwaitingPacket(received_info, sequence_number)) { - // Not missing, hence implicitly acked. - size_t bytes_sent = sent_packet->bytes_sent(); - send_algorithm_->OnPacketAcked(sequence_number, bytes_sent, rtt_sample_); - pending_packets_.erase(it++); // Must be incremented post to work. - continue; - } + const TransmissionInfo& transmission_info = + unacked_packets_[sequence_number]; - // 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)); // 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. @@ -595,8 +575,8 @@ SequenceNumberSet QuicSentPacketManager::OnIncomingAckFrame( // 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() == received_info.largest_observed) { + transmission_info.retransmittable_frames && + packet_history_map_.rbegin()->first == received_info.largest_observed) { num_nacks_needed = received_info.largest_observed - sequence_number; } @@ -607,14 +587,15 @@ SequenceNumberSet QuicSentPacketManager::OnIncomingAckFrame( // If the number of retransmissions has maxed out, don't lose or retransmit // any more packets. - if (retransmission_packets.size() >= kMaxRetransmissionsPerAck) { + if (num_retransmitted >= kMaxRetransmissionsPerAck) { ++it; continue; } lost_packets.insert(sequence_number); - if (sent_packet->has_retransmittable_data() == HAS_RETRANSMITTABLE_DATA) { - retransmission_packets.insert(sequence_number); + if (transmission_info.retransmittable_frames) { + ++num_retransmitted; + MarkForRetransmission(*it, NACK_RETRANSMISSION); } ++it; @@ -632,8 +613,6 @@ SequenceNumberSet QuicSentPacketManager::OnIncomingAckFrame( send_algorithm_->OnPacketLost(*it, ack_receive_time); OnPacketAbandoned(*it); } - - return retransmission_packets; } void QuicSentPacketManager::MaybeUpdateRTT( @@ -687,6 +666,13 @@ const QuicTime::Delta QuicSentPacketManager::DelayedAckTime() { return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs/2); } +const QuicTime QuicSentPacketManager::GetRetransmissionTime() const { + if (pending_packets_.empty()) { + return QuicTime::Zero(); + } + return clock_->ApproximateNow().Add(GetRetransmissionDelay()); +} + const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const { size_t number_retransmissions = consecutive_rto_count_; if (FLAGS_limit_rto_increase_for_tests) { diff --git a/net/quic/quic_sent_packet_manager.h b/net/quic/quic_sent_packet_manager.h index 71c61e9..70129c8 100644 --- a/net/quic/quic_sent_packet_manager.h +++ b/net/quic/quic_sent_packet_manager.h @@ -94,7 +94,8 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager { // Discards any information for the packet corresponding to |sequence_number|. // If this packet has been retransmitted, information on those packets - // will be discarded as well. + // will be discarded as well. Also discards it from the congestion window if + // it is present. void DiscardUnackedPacket(QuicPacketSequenceNumber sequence_number); // Returns true if the non-FEC packet |sequence_number| is unacked. @@ -133,15 +134,6 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager { // Returns true if |sequence_number| is a previous transmission of packet. bool IsPreviousTransmission(QuicPacketSequenceNumber sequence_number) const; - // TODO(ianswett): Combine the congestion control related methods below with - // some of the methods above and cleanup the resulting code. - // 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 ReceivedPacketInfo& received_info, - const QuicTime& ack_receive_time); - // Called when a congestion feedback frame is received from peer. virtual void OnIncomingQuicCongestionFeedbackFrame( const QuicCongestionFeedbackFrame& frame, @@ -175,6 +167,11 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager { // Returns amount of time for delayed ack timer. const QuicTime::Delta DelayedAckTime(); + // Returns the current delay for the retransmission timer, which may send + // either a tail loss probe or do a full RTO. Retrans QuicTime::Zero() if + // there are no outstanding packets to abandon or retransmit. + const QuicTime GetRetransmissionTime() const; + // Returns the current RTO delay. const QuicTime::Delta GetRetransmissionDelay() const; @@ -200,6 +197,11 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager { friend class test::QuicConnectionPeer; friend class test::QuicSentPacketManagerPeer; + enum ReceivedByPeer { + RECEIVED_BY_PEER, + NOT_RECEIVED_BY_PEER, + }; + struct TransmissionInfo { TransmissionInfo() : retransmittable_frames(NULL), @@ -227,8 +229,6 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager { TransmissionInfo> UnackedPacketMap; typedef linked_hash_map<QuicPacketSequenceNumber, TransmissionType> PendingRetransmissionMap; - typedef base::hash_map<QuicPacketSequenceNumber, SequenceNumberSet*> - PreviousTransmissionMap; // Process the incoming ack looking for newly ack'd data packets. void HandleAckForSentPackets(const ReceivedPacketInfo& received_info); @@ -237,19 +237,25 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager { void MaybeUpdateRTT(const ReceivedPacketInfo& received_info, const QuicTime& ack_receive_time); - // Marks |sequence_number| as having been seen by the peer. Returns an + // 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); + + // Marks |sequence_number| as being fully handled, either due to receipt + // by the peer, or having been discarded as indecipherable. Returns an // iterator to the next remaining unacked packet. - UnackedPacketMap::iterator MarkPacketReceivedByPeer( - QuicPacketSequenceNumber sequence_number); + UnackedPacketMap::iterator MarkPacketHandled( + QuicPacketSequenceNumber sequence_number, + ReceivedByPeer received_by_peer); - // Simply removes the entries, if any, from the unacked packet map - // and the retransmission map. + // Removes entries from the unacked packet map. void DiscardPacket(QuicPacketSequenceNumber sequence_number); // Request that |sequence_number| be retransmitted after the other pending - // retransmissions. Returns false if there are no retransmittable frames for - // |sequence_number| and true if it will be retransmitted. - bool MarkForRetransmission(QuicPacketSequenceNumber sequence_number, + // retransmissions. Does not add it to the retransmissions if it's already + // a pending retransmission. + void MarkForRetransmission(QuicPacketSequenceNumber sequence_number, TransmissionType transmission_type); // Returns the length of the serialized sequence number for diff --git a/net/quic/quic_sent_packet_manager_test.cc b/net/quic/quic_sent_packet_manager_test.cc index 168cbf3..a0b78ec 100644 --- a/net/quic/quic_sent_packet_manager_test.cc +++ b/net/quic/quic_sent_packet_manager_test.cc @@ -96,12 +96,19 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> { &manager_, new_sequence_number)); } - SerializedPacket CreatePacket(QuicPacketSequenceNumber sequence_number) { + SerializedPacket CreateDataPacket(QuicPacketSequenceNumber sequence_number) { + return CreatePacket(sequence_number, true); + } + + SerializedPacket CreatePacket(QuicPacketSequenceNumber sequence_number, + bool retransmittable) { packets_.push_back(QuicPacket::NewDataPacket( NULL, 0, false, PACKET_8BYTE_GUID, false, PACKET_6BYTE_SEQUENCE_NUMBER)); - return SerializedPacket(sequence_number, PACKET_6BYTE_SEQUENCE_NUMBER, - packets_.back(), 0u, new RetransmittableFrames()); + return SerializedPacket( + sequence_number, PACKET_6BYTE_SEQUENCE_NUMBER, + packets_.back(), 0u, + retransmittable ? new RetransmittableFrames() : NULL); } SerializedPacket CreateFecPacket(QuicPacketSequenceNumber sequence_number) { @@ -115,9 +122,9 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> { void SendDataPacket(QuicPacketSequenceNumber sequence_number) { EXPECT_CALL(*send_algorithm_, OnPacketSent(_, sequence_number, _, _, _)) .Times(1).WillOnce(Return(true)); - SerializedPacket packet(CreatePacket(sequence_number)); + SerializedPacket packet(CreateDataPacket(sequence_number)); manager_.OnSerializedPacket(packet); - manager_.OnPacketSent(sequence_number, clock_.ApproximateNow(), + manager_.OnPacketSent(sequence_number, clock_.Now(), packet.packet->length(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); } @@ -148,7 +155,7 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> { TEST_F(QuicSentPacketManagerTest, IsUnacked) { VerifyUnackedPackets(NULL, 0); - SerializedPacket serialized_packet(CreatePacket(1)); + SerializedPacket serialized_packet(CreateDataPacket(1)); manager_.OnSerializedPacket(serialized_packet); @@ -159,7 +166,7 @@ TEST_F(QuicSentPacketManagerTest, IsUnacked) { } TEST_F(QuicSentPacketManagerTest, IsUnAckedRetransmit) { - SerializedPacket serialized_packet(CreatePacket(1)); + SerializedPacket serialized_packet(CreateDataPacket(1)); manager_.OnSerializedPacket(serialized_packet); RetransmitPacket(1, 2); @@ -172,7 +179,7 @@ TEST_F(QuicSentPacketManagerTest, IsUnAckedRetransmit) { } TEST_F(QuicSentPacketManagerTest, RetransmitThenAck) { - SerializedPacket serialized_packet(CreatePacket(1)); + SerializedPacket serialized_packet(CreateDataPacket(1)); manager_.OnSerializedPacket(serialized_packet); RetransmitPacket(1, 2); @@ -189,7 +196,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitThenAck) { } TEST_F(QuicSentPacketManagerTest, RetransmitThenAckBeforeSend) { - SerializedPacket serialized_packet(CreatePacket(1)); + SerializedPacket serialized_packet(CreateDataPacket(1)); manager_.OnSerializedPacket(serialized_packet); QuicSentPacketManagerPeer::MarkForRetransmission( @@ -210,7 +217,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitThenAckBeforeSend) { } TEST_F(QuicSentPacketManagerTest, RetransmitThenAckPrevious) { - SerializedPacket serialized_packet(CreatePacket(1)); + SerializedPacket serialized_packet(CreateDataPacket(1)); manager_.OnSerializedPacket(serialized_packet); RetransmitPacket(1, 2); @@ -234,7 +241,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitThenAckPrevious) { } TEST_F(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) { - SerializedPacket serialized_packet(CreatePacket(1)); + SerializedPacket serialized_packet(CreateDataPacket(1)); manager_.OnSerializedPacket(serialized_packet); RetransmitPacket(1, 2); @@ -259,7 +266,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) { } TEST_F(QuicSentPacketManagerTest, TruncatedAck) { - SerializedPacket serialized_packet(CreatePacket(1)); + SerializedPacket serialized_packet(CreateDataPacket(1)); manager_.OnSerializedPacket(serialized_packet); RetransmitPacket(1, 2); @@ -282,9 +289,9 @@ TEST_F(QuicSentPacketManagerTest, TruncatedAck) { } TEST_F(QuicSentPacketManagerTest, SendDropAckRetransmitManyPackets) { - manager_.OnSerializedPacket(CreatePacket(1)); - manager_.OnSerializedPacket(CreatePacket(2)); - manager_.OnSerializedPacket(CreatePacket(3)); + manager_.OnSerializedPacket(CreateDataPacket(1)); + manager_.OnSerializedPacket(CreateDataPacket(2)); + manager_.OnSerializedPacket(CreateDataPacket(3)); { // Ack packets 1 and 3. @@ -299,8 +306,8 @@ TEST_F(QuicSentPacketManagerTest, SendDropAckRetransmitManyPackets) { VerifyRetransmittablePackets(retransmittable, arraysize(retransmittable)); } - manager_.OnSerializedPacket(CreatePacket(4)); - manager_.OnSerializedPacket(CreatePacket(5)); + manager_.OnSerializedPacket(CreateDataPacket(4)); + manager_.OnSerializedPacket(CreateDataPacket(5)); { // Ack packets 5. @@ -316,8 +323,8 @@ TEST_F(QuicSentPacketManagerTest, SendDropAckRetransmitManyPackets) { VerifyRetransmittablePackets(retransmittable, arraysize(retransmittable)); } - manager_.OnSerializedPacket(CreatePacket(6)); - manager_.OnSerializedPacket(CreatePacket(7)); + manager_.OnSerializedPacket(CreateDataPacket(6)); + manager_.OnSerializedPacket(CreateDataPacket(7)); { // Ack packets 7. @@ -335,8 +342,8 @@ TEST_F(QuicSentPacketManagerTest, SendDropAckRetransmitManyPackets) { } RetransmitPacket(2, 8); - manager_.OnSerializedPacket(CreatePacket(9)); - manager_.OnSerializedPacket(CreatePacket(10)); + manager_.OnSerializedPacket(CreateDataPacket(9)); + manager_.OnSerializedPacket(CreateDataPacket(10)); { // Ack packet 10. @@ -357,8 +364,8 @@ TEST_F(QuicSentPacketManagerTest, SendDropAckRetransmitManyPackets) { RetransmitPacket(4, 11); - manager_.OnSerializedPacket(CreatePacket(12)); - manager_.OnSerializedPacket(CreatePacket(13)); + manager_.OnSerializedPacket(CreateDataPacket(12)); + manager_.OnSerializedPacket(CreateDataPacket(13)); { // Ack packet 13. @@ -380,8 +387,8 @@ TEST_F(QuicSentPacketManagerTest, SendDropAckRetransmitManyPackets) { } RetransmitPacket(6, 14); - manager_.OnSerializedPacket(CreatePacket(15)); - manager_.OnSerializedPacket(CreatePacket(16)); + manager_.OnSerializedPacket(CreateDataPacket(15)); + manager_.OnSerializedPacket(CreateDataPacket(16)); { // Ack packet 16. @@ -411,7 +418,7 @@ TEST_F(QuicSentPacketManagerTest, GetLeastUnackedSentPacket) { } TEST_F(QuicSentPacketManagerTest, GetLeastUnackedSentPacketUnacked) { - SerializedPacket serialized_packet(CreatePacket(1)); + SerializedPacket serialized_packet(CreateDataPacket(1)); manager_.OnSerializedPacket(serialized_packet); EXPECT_EQ(1u, manager_.GetLeastUnackedSentPacket()); @@ -425,7 +432,7 @@ TEST_F(QuicSentPacketManagerTest, GetLeastUnackedSentPacketUnackedFec) { } TEST_F(QuicSentPacketManagerTest, GetLeastUnackedSentPacketDiscardUnacked) { - SerializedPacket serialized_packet(CreatePacket(1)); + SerializedPacket serialized_packet(CreateDataPacket(1)); manager_.OnSerializedPacket(serialized_packet); manager_.DiscardUnackedPacket(1u); @@ -498,10 +505,7 @@ TEST_F(QuicSentPacketManagerTest, 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); + SendDataPacket(i); } // Nack the first packet 3 times with increasing largest observed. @@ -516,9 +520,10 @@ TEST_F(QuicSentPacketManagerTest, NackRetransmit1Packet) { EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _)).Times(1); EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1); } - SequenceNumberSet retransmissions = - manager_.OnIncomingAckFrame(received_info, clock_.Now()); - EXPECT_EQ(i == 3 ? 1u : 0u, retransmissions.size()); + manager_.OnIncomingAck(received_info, clock_.Now()); + EXPECT_EQ( + i == 3 ? 1u : 0u, + QuicSentPacketManagerPeer::GetPendingRetransmissionCount(&manager_)); EXPECT_EQ(i, QuicSentPacketManagerPeer::GetNackCount(&manager_, 1)); } } @@ -529,10 +534,7 @@ TEST_F(QuicSentPacketManagerTest, 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); + SendDataPacket(i); } // Nack the first packet 3 times in a single StretchAck. @@ -544,21 +546,18 @@ TEST_F(QuicSentPacketManagerTest, NackRetransmit1PacketWith1StretchAck) { 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(received_info, clock_.Now()); - EXPECT_EQ(1u, retransmissions.size()); + manager_.OnIncomingAck(received_info, clock_.Now()); + EXPECT_EQ( + 1u, QuicSentPacketManagerPeer::GetPendingRetransmissionCount(&manager_)); EXPECT_EQ(3u, QuicSentPacketManagerPeer::GetNackCount(&manager_, 1)); } // Ack a packet 3 packets ahead, causing a retransmit. TEST_F(QuicSentPacketManagerTest, NackRetransmit1PacketSingleAck) { - const size_t kNumSentPackets = 4; - // Transmit 4 packets. + const size_t kNumSentPackets = 5; + // Transmit 5 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); + SendDataPacket(i); } // Nack the first packet 3 times in an AckFrame with three missing packets. @@ -568,13 +567,13 @@ TEST_F(QuicSentPacketManagerTest, NackRetransmit1PacketSingleAck) { received_info.missing_packets.insert(1); received_info.missing_packets.insert(2); received_info.missing_packets.insert(3); - received_info.largest_observed = kNumSentPackets; - EXPECT_CALL(*send_algorithm_, OnPacketAcked(kNumSentPackets, _, _)).Times(1); + received_info.largest_observed = 4; + EXPECT_CALL(*send_algorithm_, OnPacketAcked(4, _, _)).Times(1); EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _)).Times(1); EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1); - SequenceNumberSet retransmissions = - manager_.OnIncomingAckFrame(received_info, clock_.Now()); - EXPECT_EQ(1u, retransmissions.size()); + manager_.OnIncomingAck(received_info, clock_.Now()); + EXPECT_EQ( + 1u, QuicSentPacketManagerPeer::GetPendingRetransmissionCount(&manager_)); EXPECT_EQ(3u, QuicSentPacketManagerPeer::GetNackCount(&manager_, 1)); } @@ -582,10 +581,7 @@ TEST_F(QuicSentPacketManagerTest, 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); + SendDataPacket(i); } // Early retransmit when the final packet gets acked and the first is nacked. @@ -597,19 +593,16 @@ TEST_F(QuicSentPacketManagerTest, EarlyRetransmit1Packet) { 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(received_info, clock_.Now()); - EXPECT_EQ(1u, retransmissions.size()); + manager_.OnIncomingAck(received_info, clock_.Now()); + EXPECT_EQ( + 1u, QuicSentPacketManagerPeer::GetPendingRetransmissionCount(&manager_)); EXPECT_EQ(1u, QuicSentPacketManagerPeer::GetNackCount(&manager_, 1)); } TEST_F(QuicSentPacketManagerTest, DontEarlyRetransmitPacket) { - const size_t kNumSentPackets = 4; + const size_t kNumSentPackets = 5; 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); + SendDataPacket(i); } // Fast retransmit when the final packet gets acked, but don't early @@ -621,24 +614,22 @@ TEST_F(QuicSentPacketManagerTest, DontEarlyRetransmitPacket) { received_info.missing_packets.insert(1); received_info.missing_packets.insert(2); received_info.missing_packets.insert(3); + received_info.missing_packets.insert(4); 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(received_info, clock_.Now()); - EXPECT_EQ(1u, retransmissions.size()); - EXPECT_EQ(3u, QuicSentPacketManagerPeer::GetNackCount(&manager_, 1)); + EXPECT_CALL(*send_algorithm_, OnPacketAcked(5, _, _)).Times(1); + EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(2); + EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(2); + manager_.OnIncomingAck(received_info, clock_.Now()); + EXPECT_EQ( + 2u, QuicSentPacketManagerPeer::GetPendingRetransmissionCount(&manager_)); + EXPECT_EQ(4u, QuicSentPacketManagerPeer::GetNackCount(&manager_, 1)); } TEST_F(QuicSentPacketManagerTest, NackRetransmit2Packets) { 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); + SendDataPacket(i); } // Nack the first 19 packets 3 times. @@ -653,9 +644,9 @@ TEST_F(QuicSentPacketManagerTest, NackRetransmit2Packets) { OnPacketAcked(kNumSentPackets, _, _)).Times(1); EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(2); EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(2); - SequenceNumberSet retransmissions = - manager_.OnIncomingAckFrame(received_info, clock_.Now()); - EXPECT_EQ(2u, retransmissions.size()); + manager_.OnIncomingAck(received_info, clock_.Now()); + EXPECT_EQ( + 2u, QuicSentPacketManagerPeer::GetPendingRetransmissionCount(&manager_)); for (size_t i = 1; i < kNumSentPackets; ++i) { EXPECT_EQ(kNumSentPackets - i, QuicSentPacketManagerPeer::GetNackCount(&manager_, i)); @@ -669,6 +660,8 @@ TEST_F(QuicSentPacketManagerTest, NackRetransmit2PacketsAlternateAcks) { for (QuicPacketSequenceNumber i = 1; i <= kNumSentPackets; ++i) { EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) .Times(1).WillOnce(Return(i % 2 == 0 ? false : true)); + SerializedPacket packet(CreatePacket(i, i % 2 == 1)); + manager_.OnSerializedPacket(packet); manager_.OnPacketSent( i, clock_.Now(), 1000, NOT_RETRANSMISSION, i % 2 == 0 ? NO_RETRANSMITTABLE_DATA : HAS_RETRANSMITTABLE_DATA); @@ -686,9 +679,9 @@ TEST_F(QuicSentPacketManagerTest, NackRetransmit2PacketsAlternateAcks) { // not saved. EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(2); EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(2); - SequenceNumberSet retransmissions = - manager_.OnIncomingAckFrame(received_info, clock_.Now()); - EXPECT_EQ(2u, retransmissions.size()); + manager_.OnIncomingAck(received_info, clock_.Now()); + ASSERT_EQ( + 2u, QuicSentPacketManagerPeer::GetPendingRetransmissionCount(&manager_)); // Only non-ack packets have a nack count. for (size_t i = 1; i < kNumSentPackets; i += 2) { EXPECT_EQ(kNumSentPackets - i, @@ -697,19 +690,15 @@ TEST_F(QuicSentPacketManagerTest, NackRetransmit2PacketsAlternateAcks) { // 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); - } + EXPECT_EQ(1u, manager_.NextPendingRetransmission().sequence_number); + manager_.OnRetransmittedPacket(1u, kNumSentPackets + 1); + EXPECT_EQ(3u, manager_.NextPendingRetransmission().sequence_number); } TEST_F(QuicSentPacketManagerTest, 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); + SendDataPacket(i); } // Nack the first packet 2 times, then ack it. @@ -724,9 +713,8 @@ TEST_F(QuicSentPacketManagerTest, NackTwiceThenAck) { QuicTime::Delta::FromMilliseconds(5); EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(i == 3 ? 2 : 1); - SequenceNumberSet retransmissions = - manager_.OnIncomingAckFrame(received_info, clock_.Now()); - EXPECT_EQ(0u, retransmissions.size()); + manager_.OnIncomingAck(received_info, clock_.Now()); + EXPECT_FALSE(manager_.HasPendingRetransmissions()); // The nack count remains at 2 when the packet is acked. EXPECT_EQ(i == 3 ? 2u : i, QuicSentPacketManagerPeer::GetNackCount(&manager_, 1)); @@ -736,21 +724,16 @@ TEST_F(QuicSentPacketManagerTest, NackTwiceThenAck) { TEST_F(QuicSentPacketManagerTest, Rtt) { QuicPacketSequenceNumber sequence_number = 1; QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(15); + SendDataPacket(sequence_number); + clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20)); - 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)); - ReceivedPacketInfo received_info; received_info.largest_observed = sequence_number; received_info.delta_time_largest_observed = QuicTime::Delta::FromMilliseconds(5); - manager_.OnIncomingAckFrame(received_info, clock_.Now()); + manager_.OnIncomingAck(received_info, clock_.Now()); EXPECT_EQ(expected_rtt, QuicSentPacketManagerPeer::rtt(&manager_)); } @@ -760,21 +743,16 @@ TEST_F(QuicSentPacketManagerTest, RttWithInvalidDelta) { // and is hence invalid. QuicPacketSequenceNumber sequence_number = 1; QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10); + SendDataPacket(sequence_number); + clock_.AdvanceTime(expected_rtt); - 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)); - + OnPacketAcked(sequence_number, _, expected_rtt)).Times(1); ReceivedPacketInfo received_info; received_info.largest_observed = sequence_number; received_info.delta_time_largest_observed = QuicTime::Delta::FromMilliseconds(11); - manager_.OnIncomingAckFrame(received_info, clock_.Now()); + manager_.OnIncomingAck(received_info, clock_.Now()); EXPECT_EQ(expected_rtt, QuicSentPacketManagerPeer::rtt(&manager_)); } @@ -783,20 +761,15 @@ TEST_F(QuicSentPacketManagerTest, RttWithInfiniteDelta) { // delta_time_largest_observed is infinite, and is hence invalid. QuicPacketSequenceNumber sequence_number = 1; QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10); + SendDataPacket(sequence_number); + clock_.AdvanceTime(expected_rtt); - 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)); - ReceivedPacketInfo received_info; received_info.largest_observed = sequence_number; received_info.delta_time_largest_observed = QuicTime::Delta::Infinite(); - manager_.OnIncomingAckFrame(received_info, clock_.Now()); + manager_.OnIncomingAck(received_info, clock_.Now()); EXPECT_EQ(expected_rtt, QuicSentPacketManagerPeer::rtt(&manager_)); } @@ -805,20 +778,15 @@ TEST_F(QuicSentPacketManagerTest, RttZeroDelta) { // delta_time_largest_observed is zero. QuicPacketSequenceNumber sequence_number = 1; QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10); + SendDataPacket(sequence_number); + clock_.AdvanceTime(expected_rtt); - 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); - ReceivedPacketInfo received_info; received_info.largest_observed = sequence_number; received_info.delta_time_largest_observed = QuicTime::Delta::Zero(); - manager_.OnIncomingAckFrame(received_info, clock_.Now()); + manager_.OnIncomingAck(received_info, clock_.Now()); EXPECT_EQ(expected_rtt, QuicSentPacketManagerPeer::rtt(&manager_)); } @@ -837,6 +805,10 @@ TEST_F(QuicSentPacketManagerTest, RetransmissionTimeout) { manager_.OnRetransmissionTimeout(); } +TEST_F(QuicSentPacketManagerTest, GetTransmissionTime) { + EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime()); +} + TEST_F(QuicSentPacketManagerTest, GetTransmissionDelayMin) { EXPECT_CALL(*send_algorithm_, RetransmissionDelay()) .WillOnce(Return(QuicTime::Delta::FromMilliseconds(1))); 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 e2e7c02..429a405 100644 --- a/net/quic/test_tools/quic_sent_packet_manager_peer.cc +++ b/net/quic/test_tools/quic_sent_packet_manager_peer.cc @@ -28,6 +28,12 @@ size_t QuicSentPacketManagerPeer::GetNackCount( } // static +size_t QuicSentPacketManagerPeer::GetPendingRetransmissionCount( + const QuicSentPacketManager* sent_packet_manager) { + return sent_packet_manager->pending_retransmissions_.size(); +} + +// static QuicTime QuicSentPacketManagerPeer::GetSentTime( const QuicSentPacketManager* sent_packet_manager, QuicPacketSequenceNumber sequence_number) { 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 2ed9b21..9728d43 100644 --- a/net/quic/test_tools/quic_sent_packet_manager_peer.h +++ b/net/quic/test_tools/quic_sent_packet_manager_peer.h @@ -23,6 +23,9 @@ class QuicSentPacketManagerPeer { const QuicSentPacketManager* sent_packet_manager, QuicPacketSequenceNumber sequence_number); + static size_t GetPendingRetransmissionCount( + const QuicSentPacketManager* sent_packet_manager); + static QuicTime GetSentTime(const QuicSentPacketManager* sent_packet_manager, QuicPacketSequenceNumber sequence_number); diff --git a/net/quic/test_tools/quic_session_peer.cc b/net/quic/test_tools/quic_session_peer.cc index c25b42f..c1fe7e0 100644 --- a/net/quic/test_tools/quic_session_peer.cc +++ b/net/quic/test_tools/quic_session_peer.cc @@ -27,5 +27,12 @@ WriteBlockedList<QuicStreamId>* QuicSessionPeer::GetWriteblockedStreams( return &session->write_blocked_streams_; } +// static +QuicDataStream* QuicSessionPeer::GetIncomingReliableStream( + QuicSession* session, + QuicStreamId stream_id) { + return session->GetIncomingReliableStream(stream_id); +} + } // namespace test } // namespace net diff --git a/net/quic/test_tools/quic_session_peer.h b/net/quic/test_tools/quic_session_peer.h index fb4529c..3151d84 100644 --- a/net/quic/test_tools/quic_session_peer.h +++ b/net/quic/test_tools/quic_session_peer.h @@ -10,6 +10,7 @@ namespace net { +class QuicDataStream; class QuicSession; class ReliableQuicStream; @@ -21,6 +22,8 @@ class QuicSessionPeer { static void SetMaxOpenStreams(QuicSession* session, uint32 max_streams); static WriteBlockedList<QuicStreamId>* GetWriteblockedStreams( QuicSession* session); + static QuicDataStream* GetIncomingReliableStream(QuicSession* session, + QuicStreamId stream_id); private: DISALLOW_COPY_AND_ASSIGN(QuicSessionPeer); diff --git a/net/quic/test_tools/reliable_quic_stream_peer.cc b/net/quic/test_tools/reliable_quic_stream_peer.cc index 5119d03..6379c07 100644 --- a/net/quic/test_tools/reliable_quic_stream_peer.cc +++ b/net/quic/test_tools/reliable_quic_stream_peer.cc @@ -22,5 +22,10 @@ void ReliableQuicStreamPeer::SetStreamBytesWritten( stream->stream_bytes_written_ = stream_bytes_written; } +// static +void ReliableQuicStreamPeer::CloseReadSide(ReliableQuicStream* stream) { + stream->CloseReadSide(); +} + } // namespace test } // namespace net diff --git a/net/quic/test_tools/reliable_quic_stream_peer.h b/net/quic/test_tools/reliable_quic_stream_peer.h index da229da..291794f 100644 --- a/net/quic/test_tools/reliable_quic_stream_peer.h +++ b/net/quic/test_tools/reliable_quic_stream_peer.h @@ -19,6 +19,7 @@ class ReliableQuicStreamPeer { static void SetWriteSideClosed(bool value, ReliableQuicStream* stream); static void SetStreamBytesWritten(QuicStreamOffset stream_bytes_written, ReliableQuicStream* stream); + static void CloseReadSide(ReliableQuicStream* stream); private: DISALLOW_COPY_AND_ASSIGN(ReliableQuicStreamPeer); diff --git a/net/tools/quic/quic_server_session.h b/net/tools/quic/quic_server_session.h index f470551..ff921bb 100644 --- a/net/tools/quic/quic_server_session.h +++ b/net/tools/quic/quic_server_session.h @@ -52,7 +52,9 @@ class QuicServerSession : public QuicSession { virtual void InitializeSession(const QuicCryptoServerConfig& crypto_config); - const QuicCryptoServerStream* crypto_stream() { return crypto_stream_.get(); } + const QuicCryptoServerStream* crypto_stream() const { + return crypto_stream_.get(); + } protected: // QuicSession methods: |