diff options
author | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-10 10:05:14 +0000 |
---|---|---|
committer | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-10 10:05:14 +0000 |
commit | fb9e3ce5226ea2cb6bf2db6070db16dea26ae138 (patch) | |
tree | 5da23b1d02d9a4c6556fdb918710109499034e9b | |
parent | e99b99496d9ccb88517c4916552ee8af713a9956 (diff) | |
download | chromium_src-fb9e3ce5226ea2cb6bf2db6070db16dea26ae138.zip chromium_src-fb9e3ce5226ea2cb6bf2db6070db16dea26ae138.tar.gz chromium_src-fb9e3ce5226ea2cb6bf2db6070db16dea26ae138.tar.bz2 |
Revert 167074 - Change from re-transmitting an packet with a retransmit number to sending a new packet with a new sequence number.
merge internal change: 37647530
Review URL: https://chromiumcodereview.appspot.com/11332004
TBR=rch@chromium.org
Review URL: https://codereview.chromium.org/11366185
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@167082 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/quic/congestion_control/send_algorithm_interface.h | 2 | ||||
-rw-r--r-- | net/quic/quic_connection.cc | 99 | ||||
-rw-r--r-- | net/quic/quic_connection.h | 19 | ||||
-rw-r--r-- | net/quic/quic_connection_helper_test.cc | 21 | ||||
-rw-r--r-- | net/quic/quic_connection_test.cc | 56 | ||||
-rw-r--r-- | net/quic/quic_data_writer.cc | 19 | ||||
-rw-r--r-- | net/quic/quic_data_writer.h | 4 | ||||
-rw-r--r-- | net/quic/quic_framer.cc | 40 | ||||
-rw-r--r-- | net/quic/quic_framer.h | 11 | ||||
-rw-r--r-- | net/quic/quic_framer_test.cc | 131 | ||||
-rw-r--r-- | net/quic/quic_packet_creator.cc | 20 | ||||
-rw-r--r-- | net/quic/quic_packet_creator.h | 4 | ||||
-rw-r--r-- | net/quic/quic_protocol.h | 26 | ||||
-rw-r--r-- | net/quic/test_tools/quic_test_utils.cc | 8 | ||||
-rw-r--r-- | net/quic/test_tools/quic_test_utils.h | 5 |
15 files changed, 246 insertions, 219 deletions
diff --git a/net/quic/congestion_control/send_algorithm_interface.h b/net/quic/congestion_control/send_algorithm_interface.h index b263354..1447c7c 100644 --- a/net/quic/congestion_control/send_algorithm_interface.h +++ b/net/quic/congestion_control/send_algorithm_interface.h @@ -35,7 +35,7 @@ class NET_EXPORT_PRIVATE SendAlgorithmInterface { virtual void OnIncomingLoss(int number_of_lost_packets) = 0; - // Inform that we sent x bytes to the wire, and if that was a retransmission. + // Inform that we sent x bytest to the wire, and if that was a retransmission. // Note: this function must be called for every packet sent to the wire. virtual void SentPacket(QuicPacketSequenceNumber sequence_number, size_t bytes, diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc index 89fff10..4d03ea9 100644 --- a/net/quic/quic_connection.cc +++ b/net/quic/quic_connection.cc @@ -4,8 +4,6 @@ #include "net/quic/quic_connection.h" -#include <algorithm> - #include "base/logging.h" #include "base/stl_util.h" #include "net/base/net_errors.h" @@ -17,7 +15,6 @@ using base::hash_map; using base::hash_set; using base::StringPiece; using std::list; -using std::min; using std::vector; using std::set; @@ -192,18 +189,23 @@ void QuicConnection::UpdatePacketInformationReceivedByPeer( const QuicAckFrame& incoming_ack) { QuicConnectionVisitorInterface::AckedPackets acked_packets; - // Initialize the lowest unacked packet to the lower of the next outgoing - // sequence number and the largest received packed in the incoming ack. - QuicPacketSequenceNumber lowest_unacked = min( - packet_creator_.sequence_number() + 1, - incoming_ack.received_info.largest_received + 1); + // For tracking the lowest unacked packet, pick one we have not sent yet. + QuicPacketSequenceNumber lowest_unacked = + packet_creator_.sequence_number() + 1; + + // If there's a packet between the next one we're sending and the + // highest one the peer has seen, that's our new lowest unacked. + if (incoming_ack.received_info.largest_received + 1 < lowest_unacked) { + lowest_unacked = incoming_ack.received_info.largest_received + 1; + } // Go through the packets we have not received an ack for and see if this // incoming_ack shows they've been seen by the peer. UnackedPacketMap::iterator it = unacked_packets_.begin(); while (it != unacked_packets_.end()) { if ((it->first < incoming_ack.received_info.largest_received && - !ContainsKey(incoming_ack.received_info.missing_packets, it->first)) || + incoming_ack.received_info.missing_packets.find(it->first) == + incoming_ack.received_info.missing_packets.end()) || it->first == incoming_ack.received_info.largest_received) { // This was either explicitly or implicitly acked. Remove it from our // unacked packet list. @@ -217,11 +219,12 @@ void QuicConnection::UpdatePacketInformationReceivedByPeer( break; } } - acked_packets.insert(it->first); delete it->second; - UnackedPacketMap::iterator it_tmp = it; - ++it; - unacked_packets_.erase(it_tmp); + UnackedPacketMap::iterator tmp_it = it; + acked_packets.insert(it->first); + ++tmp_it; + unacked_packets_.erase(it); + it = tmp_it; } else { // This is a packet which we planned on resending and has not been // seen at the time of this ack being sent out. See if it's our new @@ -260,11 +263,12 @@ void QuicConnection::UpdatePacketInformationSentByPeer( const QuicAckFrame& incoming_ack) { // Iteratate through the packets which will the peer will not resend and // remove them from our missing list. - for (hash_set<QuicPacketSequenceNumber>::const_iterator it = - incoming_ack.sent_info.non_retransmiting.begin(); - it != incoming_ack.sent_info.non_retransmiting.end(); ++it) { - DVLOG(1) << "no longer expecting " << *it; - outgoing_ack_.received_info.missing_packets.erase(*it); + hash_set<QuicPacketSequenceNumber>::const_iterator it = + incoming_ack.sent_info.non_retransmiting.begin(); + while (it != incoming_ack.sent_info.non_retransmiting.end()) { + outgoing_ack_.received_info.missing_packets.erase(*it); + DVLOG(1) << "no longer expecting " << *it; + ++it; } // Make sure we also don't expect any packets lower than the peer's @@ -272,7 +276,8 @@ void QuicConnection::UpdatePacketInformationSentByPeer( if (incoming_ack.sent_info.least_unacked > largest_seen_least_packet_awaiting_ack_) { for (QuicPacketSequenceNumber i = largest_seen_least_packet_awaiting_ack_; - i < incoming_ack.sent_info.least_unacked; ++i) { + i < incoming_ack.sent_info.least_unacked; + ++i) { outgoing_ack_.received_info.missing_packets.erase(i); } largest_seen_least_packet_awaiting_ack_ = @@ -343,12 +348,7 @@ size_t QuicConnection::SendStreamData( DCHECK_LT(0u, packets.size()); for (size_t i = 0; i < packets.size(); ++i) { - // Resend is false for FEC packets. - SendPacket(packets[i].first, - packets[i].second, - !packets[i].second->IsFecPacket(), - false, - false); + SendPacket(packets[i].first, packets[i].second, true, false); // TODO(alyssar) either only buffer this up if we send successfully, // and make the upper levels deal with backup, or handle backup here. unacked_packets_.insert(packets[i]); @@ -365,7 +365,7 @@ void QuicConnection::SendRstStream(QuicStreamId id, QuicStreamOffset offset) { PacketPair packetpair = packet_creator_.ResetStream(id, offset, error); - SendPacket(packetpair.first, packetpair.second, true, false, false); + SendPacket(packetpair.first, packetpair.second, true, false); unacked_packets_.insert(packetpair); } @@ -391,7 +391,7 @@ bool QuicConnection::OnCanWrite() { num_queued_packets = queued_packets_.size(); QueuedPacket p = queued_packets_.front(); queued_packets_.pop_front(); - SendPacket(p.sequence_number, p.packet, p.resend, false, p.retransmit); + SendPacket(p.sequence_number, p.packet, p.resend, false); } return !write_blocked_; } @@ -427,15 +427,8 @@ void QuicConnection::MaybeResendPacket( if (it != unacked_packets_.end()) { DVLOG(1) << "Resending unacked packet " << sequence_number; - QuicPacket* packet = it->second; - unacked_packets_.erase(it); - // Re-frame the packet with a new sequence number for resend. - QuicPacketSequenceNumber new_sequence_number = - packet_creator_.SetNewSequenceNumber(packet); - // Clear the FEC group. - framer_.WriteFecGroup(0u, packet); - unacked_packets_[new_sequence_number] = packet; - SendPacket(new_sequence_number, packet, true, false, true); + framer_.IncrementRetransmitCount(it->second); + SendPacket(sequence_number, it->second, true, false); } else { DVLOG(2) << "alarm fired for " << sequence_number << " but it has been acked"; @@ -444,29 +437,26 @@ void QuicConnection::MaybeResendPacket( bool QuicConnection::SendPacket(QuicPacketSequenceNumber sequence_number, QuicPacket* packet, - bool should_resend, - bool force, - bool is_retransmit) { + bool resend, + bool force) { // If this packet is being forced, don't bother checking to see if we should // write, just write. if (!force) { // If we can't write, then simply queue the packet. if (write_blocked_ || helper_->IsSendAlarmSet()) { - queued_packets_.push_back( - QueuedPacket(sequence_number, packet, should_resend, is_retransmit)); + queued_packets_.push_back(QueuedPacket(sequence_number, packet, resend)); return false; } - int delay = scheduler_->TimeUntilSend(should_resend); + int delay = scheduler_->TimeUntilSend(resend); // If the scheduler requires a delay, then we can not send this packet now. if (delay > 0) { helper_->SetSendAlarm(delay); - queued_packets_.push_back( - QueuedPacket(sequence_number, packet, should_resend, is_retransmit)); + queued_packets_.push_back(QueuedPacket(sequence_number, packet, resend)); return false; } } - if (should_resend) { + if (resend) { helper_->SetResendAlarm(sequence_number, kDefaultResendTimeMs * 1000); // The second case should never happen in the real world, but does here // because we sometimes send out of order to validate corner cases. @@ -486,16 +476,12 @@ bool QuicConnection::SendPacket(QuicPacketSequenceNumber sequence_number, scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPacket(*packet)); int error; - int rv = helper_->WritePacketToWire(sequence_number, *encrypted, - should_resend, &error); - DLOG(INFO) << "Sending packet : " - << (should_resend ? "data bearing " : " ack only ") - << "packet " << sequence_number; + int rv = helper_->WritePacketToWire(sequence_number, *encrypted, resend, + &error); if (rv == -1) { if (error == ERR_IO_PENDING) { write_blocked_ = true; - queued_packets_.push_front( - QueuedPacket(sequence_number, packet, should_resend, is_retransmit)); + queued_packets_.push_front(QueuedPacket(sequence_number, packet, resend)); return false; } } @@ -503,8 +489,9 @@ bool QuicConnection::SendPacket(QuicPacketSequenceNumber sequence_number, time_of_last_packet_us_ = clock_->NowInUsec(); DVLOG(1) << "last packet: " << time_of_last_packet_us_; - scheduler_->SentPacket(sequence_number, packet->length(), is_retransmit); - if (!should_resend) delete packet; + scheduler_->SentPacket(sequence_number, packet->length(), + framer_.GetRetransmitCount(packet) != 0); + if (!resend) delete packet; return true; } @@ -524,7 +511,7 @@ void QuicConnection::SendAck() { DVLOG(1) << "Sending ack " << outgoing_ack_; PacketPair packetpair = packet_creator_.AckPacket(&outgoing_ack_); - SendPacket(packetpair.first, packetpair.second, false, false, false); + SendPacket(packetpair.first, packetpair.second, false, false); } void QuicConnection::MaybeProcessRevivedPacket() { @@ -566,7 +553,7 @@ void QuicConnection::SendConnectionClose(QuicErrorCode error) { PacketPair packetpair = packet_creator_.CloseConnection(&frame); // There's no point in resending this: we're closing the connection. - SendPacket(packetpair.first, packetpair.second, false, true, false); + SendPacket(packetpair.first, packetpair.second, false, true); connected_ = false; visitor_->ConnectionClose(error, false); } diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h index 5a13a61..51604db 100644 --- a/net/quic/quic_connection.h +++ b/net/quic/quic_connection.h @@ -186,16 +186,14 @@ class NET_EXPORT_PRIVATE QuicConnection : public QuicFramerVisitorInterface { bool ShouldSimulateLostPacket(); protected: - // Send a packet to the peer. If should_resend is true, this packet contains - // data, and contents will be resent with a new sequence number if we don't - // get an ack. If force is true, then the packet will be sent immediately and - // the send scheduler will not be consulted. If is_retransmit is true, this - // packet is being retransmitted with a new sequence number. + // Send a packet to the peer. If resend is true, this packet contains data, + // and will be resent if we don't get an ack. If force is true, then the + // packet will be sent immediately and the send scheduler will not be + // consulted. virtual bool SendPacket(QuicPacketSequenceNumber number, QuicPacket* packet, - bool should_resend, - bool force, - bool is_retransmit); + bool resend, + bool force); // Make sure an ack we got from our peer is sane. bool ValidateAckFrame(const QuicAckFrame& incoming_ack); @@ -262,16 +260,13 @@ class NET_EXPORT_PRIVATE QuicConnection : public QuicFramerVisitorInterface { QuicPacketSequenceNumber sequence_number; QuicPacket* packet; bool resend; - bool retransmit; QueuedPacket(QuicPacketSequenceNumber sequence_number, QuicPacket* packet, - bool resend, - bool retransmit) { + bool resend) { this->sequence_number = sequence_number; this->packet = packet; this->resend = resend; - this->retransmit = retransmit; } }; typedef std::list<QueuedPacket> QueuedPacketList; diff --git a/net/quic/quic_connection_helper_test.cc b/net/quic/quic_connection_helper_test.cc index b965563..aa7d436 100644 --- a/net/quic/quic_connection_helper_test.cc +++ b/net/quic/quic_connection_helper_test.cc @@ -54,11 +54,9 @@ class TestConnection : public QuicConnection { bool SendPacket(QuicPacketSequenceNumber sequence_number, QuicPacket* packet, - bool should_resend, - bool force, - bool is_retransmit) { - return QuicConnection::SendPacket( - sequence_number, packet, should_resend, force, is_retransmit); + bool resend, + bool force) { + return QuicConnection::SendPacket(sequence_number, packet, resend, force); } }; @@ -113,6 +111,7 @@ class QuicConnectionHelperTest : public ::testing::Test { header_.guid = guid_; header_.packet_sequence_number = number; header_.transmission_time = 0; + header_.retransmission_count = 0; header_.flags = PACKET_FLAGS_NONE; header_.fec_group = fec_group; @@ -120,7 +119,7 @@ class QuicConnectionHelperTest : public ::testing::Test { QuicFrame frame(&frame1_); frames.push_back(frame); QuicPacket* packet; - framer_.ConstructFrameDataPacket(header_, frames, &packet); + framer_.ConstructFragementDataPacket(header_, frames, &packet); return packet; } @@ -166,10 +165,12 @@ TEST_F(QuicConnectionHelperTest, TestResend) { const uint64 kDefaultResendTimeMs = 500; connection_.SendStreamData(1, "foo", 0, false, NULL); + EXPECT_EQ(0u, helper_->header()->retransmission_count); EXPECT_EQ(0u, helper_->header()->transmission_time); runner_->RunNextTask(); - EXPECT_EQ(2u, helper_->header()->packet_sequence_number); + + EXPECT_EQ(1u, helper_->header()->retransmission_count); EXPECT_EQ(kDefaultResendTimeMs * 1000, helper_->header()->transmission_time); } @@ -216,11 +217,9 @@ TEST_F(QuicConnectionHelperTest, SendSchedulerDelayThenSend) { // Test that if we send a packet with a delay, it ends up queued. scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0)); EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(1)); - - bool should_resend = true; + bool resend = true; bool force = false; - bool is_retransmit = false; - connection_.SendPacket(1, packet.get(), should_resend, force, is_retransmit); + connection_.SendPacket(1, packet.get(), resend, force); EXPECT_EQ(1u, connection_.NumQueuedPackets()); // Advance the clock to fire the alarm, and configure the scheduler diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc index cd1591e..d4c4354 100644 --- a/net/quic/quic_connection_test.cc +++ b/net/quic/quic_connection_test.cc @@ -169,11 +169,9 @@ class TestConnection : public QuicConnection { bool SendPacket(QuicPacketSequenceNumber sequence_number, QuicPacket* packet, - bool should_resend, - bool force, - bool is_retransmit) { - return QuicConnection::SendPacket( - sequence_number, packet, should_resend, force, is_retransmit); + bool resend, + bool force) { + return QuicConnection::SendPacket(sequence_number, packet, resend, force); } }; @@ -297,6 +295,7 @@ class QuicConnectionTest : public ::testing::Test { QuicFecGroupNumber fec_group) { header_.guid = guid_; header_.packet_sequence_number = number; + header_.retransmission_count = 0; header_.transmission_time = 0; header_.flags = PACKET_FLAGS_NONE; header_.fec_group = fec_group; @@ -305,7 +304,7 @@ class QuicConnectionTest : public ::testing::Test { QuicFrame frame(&frame1_); frames.push_back(frame); QuicPacket* packet = NULL; - EXPECT_TRUE(framer_.ConstructFrameDataPacket(header_, frames, &packet)); + EXPECT_TRUE(framer_.ConstructFragementDataPacket(header_, frames, &packet)); return packet; } @@ -689,7 +688,7 @@ TEST_F(QuicConnectionTest, TestResend) { const uint64 kDefaultResendTimeMs = 500u; connection_.SendStreamData(1, "foo", 0, false, NULL); - EXPECT_EQ(1u, last_header()->packet_sequence_number); + EXPECT_EQ(0u, last_header()->retransmission_count); EXPECT_EQ(0u, last_header()->transmission_time); EXPECT_EQ(1u, helper_->resend_alarms().size()); EXPECT_EQ(kDefaultResendTimeMs * 1000, @@ -697,11 +696,12 @@ TEST_F(QuicConnectionTest, TestResend) { // Simulate the resend alarm firing clock_.AdvanceTimeInMicroseconds(kDefaultResendTimeMs * 1000); connection_.MaybeResendPacket(1); - EXPECT_EQ(2u, last_header()->packet_sequence_number); + EXPECT_EQ(1u, last_header()->retransmission_count); EXPECT_EQ(kDefaultResendTimeMs * 1000, last_header()->transmission_time); } + TEST_F(QuicConnectionTest, TestQueued) { EXPECT_EQ(0u, connection_.NumQueuedPackets()); helper_->set_blocked(true); @@ -806,12 +806,11 @@ TEST_F(QuicConnectionTest, TimeoutAfterSend) { EXPECT_FALSE(connection_.connected()); } -// TODO(ianswett): Add scheduler tests when resend is false. TEST_F(QuicConnectionTest, SendScheduler) { // Test that if we send a packet without delay, it is not queued. scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0)); EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(0)); - connection_.SendPacket(1, packet.get(), true, false, false); + connection_.SendPacket(1, packet.get(), true, false); EXPECT_EQ(0u, connection_.NumQueuedPackets()); } @@ -820,7 +819,7 @@ TEST_F(QuicConnectionTest, SendSchedulerDelay) { scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0)); EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(1)); EXPECT_CALL(*scheduler_, SentPacket(1, _, _)).Times(0); - connection_.SendPacket(1, packet.get(), true, false, false); + connection_.SendPacket(1, packet.get(), true, false); EXPECT_EQ(1u, connection_.NumQueuedPackets()); } @@ -828,7 +827,7 @@ TEST_F(QuicConnectionTest, SendSchedulerForce) { // Test that if we force send a packet, it is not queued. scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0)); EXPECT_CALL(*scheduler_, TimeUntilSend(true)).Times(0); - connection_.SendPacket(1, packet.get(), true, true, false); + connection_.SendPacket(1, packet.get(), true, true); EXPECT_EQ(0u, connection_.NumQueuedPackets()); } @@ -837,7 +836,7 @@ TEST_F(QuicConnectionTest, SendSchedulerEAGAIN) { helper_->set_blocked(true); EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(0)); EXPECT_CALL(*scheduler_, SentPacket(1, _, _)).Times(0); - connection_.SendPacket(1, packet.get(), true, false, false); + connection_.SendPacket(1, packet.get(), true, false); EXPECT_EQ(1u, connection_.NumQueuedPackets()); } @@ -845,7 +844,7 @@ TEST_F(QuicConnectionTest, SendSchedulerDelayThenSend) { // Test that if we send a packet with a delay, it ends up queued. scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0)); EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(1)); - connection_.SendPacket(1, packet.get(), true, false, false); + connection_.SendPacket(1, packet.get(), true, false); EXPECT_EQ(1u, connection_.NumQueuedPackets()); // Advance the clock to fire the alarm, and configure the scheduler @@ -856,40 +855,21 @@ TEST_F(QuicConnectionTest, SendSchedulerDelayThenSend) { EXPECT_EQ(0u, connection_.NumQueuedPackets()); } -TEST_F(QuicConnectionTest, SendSchedulerDelayThenRetransmit) { - // Test that if we send a retransmit with a delay, it ends up queued. - scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0)); - EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(1)); - connection_.SendPacket(1, packet.get(), true, false, true); - EXPECT_EQ(1u, connection_.NumQueuedPackets()); - - // Advance the clock to fire the alarm, and configure the scheduler - // to permit the packet to be sent. - EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(0)); - clock_.AdvanceTimeInMicroseconds(1); - - // Ensure the scheduler is notified this is a retransmit. - EXPECT_CALL(*scheduler_, SentPacket(1, _, true)); - clock_.AdvanceTimeInMicroseconds(1); - connection_.OnCanWrite(); - EXPECT_EQ(0u, connection_.NumQueuedPackets()); -} - TEST_F(QuicConnectionTest, SendSchedulerDelayAndQueue) { scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0)); EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(1)); - connection_.SendPacket(1, packet.get(), true, false, false); + connection_.SendPacket(1, packet.get(), true, false); EXPECT_EQ(1u, connection_.NumQueuedPackets()); // Attempt to send another packet and make sure that it gets queued. - connection_.SendPacket(2, packet.get(), true, false, false); + connection_.SendPacket(2, packet.get(), true, false); EXPECT_EQ(2u, connection_.NumQueuedPackets()); } TEST_F(QuicConnectionTest, SendSchedulerDelayThenAckAndSend) { scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0)); EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(10)); - connection_.SendPacket(1, packet.get(), true, false, false); + connection_.SendPacket(1, packet.get(), true, false); EXPECT_EQ(1u, connection_.NumQueuedPackets()); // Now send non-retransmitting information, that we're not going to resend 3. @@ -909,7 +889,7 @@ TEST_F(QuicConnectionTest, SendSchedulerDelayThenAckAndSend) { TEST_F(QuicConnectionTest, SendSchedulerDelayThenAckAndHold) { scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0)); EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(10)); - connection_.SendPacket(1, packet.get(), true, false, false); + connection_.SendPacket(1, packet.get(), true, false); EXPECT_EQ(1u, connection_.NumQueuedPackets()); // Now send non-resending information, that we're not going to resend 3. @@ -926,7 +906,7 @@ TEST_F(QuicConnectionTest, SendSchedulerDelayThenAckAndHold) { TEST_F(QuicConnectionTest, SendSchedulerDelayThenOnCanWrite) { scoped_ptr<QuicPacket> packet(ConstructDataPacket(1, 0)); EXPECT_CALL(*scheduler_, TimeUntilSend(true)).WillOnce(testing::Return(10)); - connection_.SendPacket(1, packet.get(), true, false, false); + connection_.SendPacket(1, packet.get(), true, false); EXPECT_EQ(1u, connection_.NumQueuedPackets()); // OnCanWrite should not send the packet (because of the delay) diff --git a/net/quic/quic_data_writer.cc b/net/quic/quic_data_writer.cc index b635b38..91d8868 100644 --- a/net/quic/quic_data_writer.cc +++ b/net/quic/quic_data_writer.cc @@ -94,25 +94,6 @@ bool QuicDataWriter::WriteBytes(const void* data, uint32 data_len) { return true; } -void QuicDataWriter::WriteUint8ToBuffer(uint8 value, char* buffer) { - memcpy(buffer, &value, sizeof(value)); -} - -void QuicDataWriter::WriteUint16ToBuffer(uint16 value, char* buffer) { - memcpy(buffer, &value, sizeof(value)); -} - -void QuicDataWriter::WriteUint32ToBuffer(uint32 value, char* buffer) { - memcpy(buffer, &value, sizeof(value)); -} - -void QuicDataWriter::WriteUint48ToBuffer(uint64 value, char* buffer) { - uint16 hi = value >> 32; - uint32 lo = value & 0x00000000FFFFFFFF; - WriteUint32ToBuffer(lo, buffer); - WriteUint16ToBuffer(hi, buffer + sizeof(lo)); -} - void QuicDataWriter::WriteUint64ToBuffer(uint64 value, char* buffer) { memcpy(buffer, &value, sizeof(value)); } diff --git a/net/quic/quic_data_writer.h b/net/quic/quic_data_writer.h index 0171e52..25a215a 100644 --- a/net/quic/quic_data_writer.h +++ b/net/quic/quic_data_writer.h @@ -47,10 +47,6 @@ class NET_EXPORT_PRIVATE QuicDataWriter { bool WriteStringPiece16(base::StringPiece val); bool WriteBytes(const void* data, uint32 data_len); - static void WriteUint8ToBuffer(uint8 value, char* buffer); - static void WriteUint16ToBuffer(uint16 value, char* buffer); - static void WriteUint32ToBuffer(uint32 value, char* buffer); - static void WriteUint48ToBuffer(uint64 value, char* buffer); static void WriteUint64ToBuffer(uint64 value, char* buffer); static void WriteUint128ToBuffer(uint128 value, char* buffer); diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc index ab47407..0148783 100644 --- a/net/quic/quic_framer.cc +++ b/net/quic/quic_framer.cc @@ -26,7 +26,7 @@ QuicFramer::QuicFramer(QuicDecrypter* decrypter, QuicEncrypter* encrypter) QuicFramer::~QuicFramer() {} -bool QuicFramer::ConstructFrameDataPacket( +bool QuicFramer::ConstructFragementDataPacket( const QuicPacketHeader& header, const QuicFrames& frames, QuicPacket** packet) { @@ -89,9 +89,8 @@ bool QuicFramer::ConstructFrameDataPacket( return RaiseError(QUIC_INVALID_FRAME_DATA); } } - DCHECK_EQ(len, writer.length()); - *packet = new QuicPacket(writer.take(), len, true, PACKET_FLAGS_NONE); + *packet = new QuicPacket(writer.take(), len, true); if (fec_builder_) { fec_builder_->OnBuiltFecProtectedPayload(header, (*packet)->FecProtectedData()); @@ -123,11 +122,23 @@ bool QuicFramer::ConstructFecPacket(const QuicPacketHeader& header, return false; } - *packet = new QuicPacket(writer.take(), len, true, PACKET_FLAGS_FEC); + *packet = new QuicPacket(writer.take(), len, true); return true; } +void QuicFramer::IncrementRetransmitCount(QuicPacket* packet) { + CHECK_GT(packet->length(), kPacketHeaderSize); + + ++packet->mutable_data()[kRetransmissionOffset]; +} + +uint8 QuicFramer::GetRetransmitCount(QuicPacket* packet) { + CHECK_GT(packet->length(), kPacketHeaderSize); + + return packet->mutable_data()[kRetransmissionOffset]; +} + bool QuicFramer::ProcessPacket(const IPEndPoint& self_address, const IPEndPoint& peer_address, const QuicEncryptedPacket& packet) { @@ -217,6 +228,10 @@ bool QuicFramer::WritePacketHeader(const QuicPacketHeader& header, return false; } + if (!writer->WriteBytes(&header.retransmission_count, 1)) { + return false; + } + // CongestionMonitoredHeader if (!writer->WriteUInt64(header.transmission_time)) { return false; @@ -247,6 +262,11 @@ bool QuicFramer::ProcessPacketHeader(QuicPacketHeader* header, return false; } + if (!reader_->ReadBytes(&header->retransmission_count, 1)) { + set_detailed_error("Unable to read retransmission count."); + return false; + } + // CongestionMonitoredHeader if (!reader_->ReadUInt64(&header->transmission_time)) { set_detailed_error("Unable to read transmission time."); @@ -537,18 +557,6 @@ void QuicFramer::WriteTransmissionTime(QuicTransmissionTime time, time, packet->mutable_data() + kTransmissionTimeOffset); } -void QuicFramer::WriteSequenceNumber(QuicPacketSequenceNumber sequence_number, - QuicPacket* packet) { - QuicDataWriter::WriteUint48ToBuffer( - sequence_number, packet->mutable_data() + kSequenceNumberOffset); -} - -void QuicFramer::WriteFecGroup(QuicFecGroupNumber fec_group, - QuicPacket* packet) { - QuicDataWriter::WriteUint8ToBuffer( - fec_group, packet->mutable_data() + kFecGroupOffset); -} - QuicEncryptedPacket* QuicFramer::EncryptPacket(const QuicPacket& packet) { scoped_ptr<QuicData> out(encrypter_->Encrypt(packet.AssociatedData(), packet.Plaintext())); diff --git a/net/quic/quic_framer.h b/net/quic/quic_framer.h index 7bb4a2f..7fe95ef 100644 --- a/net/quic/quic_framer.h +++ b/net/quic/quic_framer.h @@ -129,7 +129,7 @@ class NET_EXPORT_PRIVATE QuicFramer { // Creates a new QuicPacket populated with the fields in |header| and // |frames|. Assigns |*packet| to the address of the new object. // Returns true upon success. - bool ConstructFrameDataPacket(const QuicPacketHeader& header, + bool ConstructFragementDataPacket(const QuicPacketHeader& header, const QuicFrames& frames, QuicPacket** packet); @@ -140,12 +140,13 @@ class NET_EXPORT_PRIVATE QuicFramer { const QuicFecData& fec, QuicPacket** packet); - void WriteTransmissionTime(QuicTransmissionTime time, QuicPacket* packet); + // Increments the retransmission count by one, and updates the authentication + // hash accordingly. + void IncrementRetransmitCount(QuicPacket* packet); - void WriteSequenceNumber(QuicPacketSequenceNumber sequence_number, - QuicPacket* packet); + uint8 GetRetransmitCount(QuicPacket* packet); - void WriteFecGroup(QuicFecGroupNumber fec_group, QuicPacket* packet); + void WriteTransmissionTime(QuicTransmissionTime time, QuicPacket* packet); // Returns a new encrypted packet, owned by the caller. QuicEncryptedPacket* EncryptPacket(const QuicPacket& packet); diff --git a/net/quic/quic_framer_test.cc b/net/quic/quic_framer_test.cc index 6191f10..158ec61 100644 --- a/net/quic/quic_framer_test.cc +++ b/net/quic/quic_framer_test.cc @@ -230,6 +230,8 @@ TEST_F(QuicFramerTest, LargePacket) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -261,6 +263,8 @@ TEST_F(QuicFramerTest, PacketHeader) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -276,6 +280,7 @@ TEST_F(QuicFramerTest, PacketHeader) { EXPECT_EQ(QUIC_INVALID_FRAME_DATA, framer_.error()); ASSERT_TRUE(visitor_.header_.get()); EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210), visitor_.header_->guid); + EXPECT_EQ(0x1, visitor_.header_->retransmission_count); EXPECT_EQ(GG_UINT64_C(0x123456789ABC), visitor_.header_->packet_sequence_number); EXPECT_EQ(GG_UINT64_C(0xF0E1D2C3B4A59687), @@ -284,17 +289,19 @@ TEST_F(QuicFramerTest, PacketHeader) { EXPECT_EQ(0x00, visitor_.header_->fec_group); // Now test framing boundaries - for (int i = 0; i < 24; ++i) { + for (int i = 0; i < 25; ++i) { string expected_error; if (i < 8) { expected_error = "Unable to read GUID."; } else if (i < 14) { expected_error = "Unable to read sequence number."; - } else if (i < 22) { - expected_error = "Unable to read transmission time."; + } else if (i < 15) { + expected_error = "Unable to read retransmission count."; } else if (i < 23) { - expected_error = "Unable to read flags."; + expected_error = "Unable to read transmission time."; } else if (i < 24) { + expected_error = "Unable to read flags."; + } else if (i < 25) { expected_error = "Unable to read fec group."; } @@ -314,6 +321,8 @@ TEST_F(QuicFramerTest, StreamFrame) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -394,6 +403,8 @@ TEST_F(QuicFramerTest, RejectPacket) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -456,6 +467,7 @@ TEST_F(QuicFramerTest, RevivedStreamFrame) { QuicPacketHeader header; header.guid = GG_UINT64_C(0xFEDCBA9876543210); + header.retransmission_count = 0x01; header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687); header.flags = PACKET_FLAGS_NONE; @@ -470,6 +482,7 @@ TEST_F(QuicFramerTest, RevivedStreamFrame) { ASSERT_EQ(1, visitor_.revived_packets_); ASSERT_TRUE(visitor_.header_.get()); EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210), visitor_.header_->guid); + EXPECT_EQ(0x1, visitor_.header_->retransmission_count); EXPECT_EQ(GG_UINT64_C(0x123456789ABC), visitor_.header_->packet_sequence_number); EXPECT_EQ(GG_UINT64_C(0xF0E1D2C3B4A59687), @@ -495,6 +508,8 @@ TEST_F(QuicFramerTest, StreamFrameInFecGroup) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x12, 0x34, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -551,6 +566,8 @@ TEST_F(QuicFramerTest, AckFrame) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -665,6 +682,8 @@ TEST_F(QuicFramerTest, AckFrameTCP) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -772,6 +791,8 @@ TEST_F(QuicFramerTest, AckFrameInterArrival) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -883,6 +904,8 @@ TEST_F(QuicFramerTest, AckFrameFixRate) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -985,6 +1008,8 @@ TEST_F(QuicFramerTest, AckFrameInvalidFeedback) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -1043,6 +1068,8 @@ TEST_F(QuicFramerTest, RstStreamFrame) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -1114,6 +1141,8 @@ TEST_F(QuicFramerTest, ConnectionCloseFrame) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -1242,6 +1271,8 @@ TEST_F(QuicFramerTest, FecPacket) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -1279,6 +1310,7 @@ TEST_F(QuicFramerTest, FecPacket) { TEST_F(QuicFramerTest, ConstructStreamFramePacket) { QuicPacketHeader header; header.guid = GG_UINT64_C(0xFEDCBA9876543210); + header.retransmission_count = 0x01; header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687); header.flags = PACKET_FLAGS_NONE; @@ -1304,6 +1336,8 @@ TEST_F(QuicFramerTest, ConstructStreamFramePacket) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -1332,7 +1366,7 @@ TEST_F(QuicFramerTest, ConstructStreamFramePacket) { }; QuicPacket* data; - ASSERT_TRUE(framer_.ConstructFrameDataPacket(header, frames, &data)); + ASSERT_TRUE(framer_.ConstructFragementDataPacket(header, frames, &data)); test::CompareCharArraysWithHexError("constructed packet", data->data(), data->length(), @@ -1344,6 +1378,7 @@ TEST_F(QuicFramerTest, ConstructStreamFramePacket) { TEST_F(QuicFramerTest, ConstructAckFramePacket) { QuicPacketHeader header; header.guid = GG_UINT64_C(0xFEDCBA9876543210); + header.retransmission_count = 0x01; header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687); header.flags = PACKET_FLAGS_NONE; @@ -1379,6 +1414,8 @@ TEST_F(QuicFramerTest, ConstructAckFramePacket) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -1445,7 +1482,7 @@ TEST_F(QuicFramerTest, ConstructAckFramePacket) { }; QuicPacket* data; - EXPECT_TRUE(framer_.ConstructFrameDataPacket(header, frames, &data)); + EXPECT_TRUE(framer_.ConstructFragementDataPacket(header, frames, &data)); test::CompareCharArraysWithHexError("constructed packet", data->data(), data->length(), @@ -1457,6 +1494,7 @@ TEST_F(QuicFramerTest, ConstructAckFramePacket) { TEST_F(QuicFramerTest, ConstructAckFramePacketTCP) { QuicPacketHeader header; header.guid = GG_UINT64_C(0xFEDCBA9876543210); + header.retransmission_count = 0x01; header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687); header.flags = PACKET_FLAGS_NONE; @@ -1494,6 +1532,8 @@ TEST_F(QuicFramerTest, ConstructAckFramePacketTCP) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -1564,7 +1604,7 @@ TEST_F(QuicFramerTest, ConstructAckFramePacketTCP) { }; QuicPacket* data; - EXPECT_TRUE(framer_.ConstructFrameDataPacket(header, frames, &data)); + EXPECT_TRUE(framer_.ConstructFragementDataPacket(header, frames, &data)); test::CompareCharArraysWithHexError("constructed packet", data->data(), data->length(), @@ -1576,6 +1616,7 @@ TEST_F(QuicFramerTest, ConstructAckFramePacketTCP) { TEST_F(QuicFramerTest, ConstructAckFramePacketInterArrival) { QuicPacketHeader header; header.guid = GG_UINT64_C(0xFEDCBA9876543210); + header.retransmission_count = 0x01; header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687); header.flags = PACKET_FLAGS_NONE; @@ -1615,6 +1656,8 @@ TEST_F(QuicFramerTest, ConstructAckFramePacketInterArrival) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -1687,7 +1730,7 @@ TEST_F(QuicFramerTest, ConstructAckFramePacketInterArrival) { }; QuicPacket* data; - EXPECT_TRUE(framer_.ConstructFrameDataPacket(header, frames, &data)); + EXPECT_TRUE(framer_.ConstructFragementDataPacket(header, frames, &data)); test::CompareCharArraysWithHexError("constructed packet", data->data(), data->length(), @@ -1699,6 +1742,7 @@ TEST_F(QuicFramerTest, ConstructAckFramePacketInterArrival) { TEST_F(QuicFramerTest, ConstructAckFramePacketFixRate) { QuicPacketHeader header; header.guid = GG_UINT64_C(0xFEDCBA9876543210); + header.retransmission_count = 0x01; header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687); header.flags = PACKET_FLAGS_NONE; @@ -1736,6 +1780,8 @@ TEST_F(QuicFramerTest, ConstructAckFramePacketFixRate) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -1804,7 +1850,7 @@ TEST_F(QuicFramerTest, ConstructAckFramePacketFixRate) { }; QuicPacket* data; - EXPECT_TRUE(framer_.ConstructFrameDataPacket(header, frames, &data)); + EXPECT_TRUE(framer_.ConstructFragementDataPacket(header, frames, &data)); test::CompareCharArraysWithHexError("constructed packet", data->data(), data->length(), @@ -1816,6 +1862,7 @@ TEST_F(QuicFramerTest, ConstructAckFramePacketFixRate) { TEST_F(QuicFramerTest, ConstructAckFramePacketInvalidFeedback) { QuicPacketHeader header; header.guid = GG_UINT64_C(0xFEDCBA9876543210); + header.retransmission_count = 0x01; header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687); header.flags = PACKET_FLAGS_NONE; @@ -1846,15 +1893,15 @@ TEST_F(QuicFramerTest, ConstructAckFramePacketInvalidFeedback) { frames.push_back(frame); QuicPacket* data; - EXPECT_FALSE(framer_.ConstructFrameDataPacket(header, frames, &data)); + EXPECT_FALSE(framer_.ConstructFragementDataPacket(header, frames, &data)); } TEST_F(QuicFramerTest, ConstructRstFramePacket) { QuicPacketHeader header; header.guid = GG_UINT64_C(0xFEDCBA9876543210); - header.guid = 0xFEDCBA9876543210; - header.packet_sequence_number = 0x123456789ABC; - header.transmission_time = 0xF0E1D2C3B4A59687; + header.retransmission_count = 0x01; + header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); + header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687); header.flags = PACKET_FLAGS_NONE; header.fec_group = 0; @@ -1871,6 +1918,8 @@ TEST_F(QuicFramerTest, ConstructRstFramePacket) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -1905,7 +1954,7 @@ TEST_F(QuicFramerTest, ConstructRstFramePacket) { frames.push_back(frame); QuicPacket* data; - EXPECT_TRUE(framer_.ConstructFrameDataPacket(header, frames, &data)); + EXPECT_TRUE(framer_.ConstructFragementDataPacket(header, frames, &data)); test::CompareCharArraysWithHexError("constructed packet", data->data(), data->length(), @@ -1917,6 +1966,7 @@ TEST_F(QuicFramerTest, ConstructRstFramePacket) { TEST_F(QuicFramerTest, ConstructCloseFramePacket) { QuicPacketHeader header; header.guid = GG_UINT64_C(0xFEDCBA9876543210); + header.retransmission_count = 0x01; header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687); header.flags = PACKET_FLAGS_NONE; @@ -1958,6 +2008,8 @@ TEST_F(QuicFramerTest, ConstructCloseFramePacket) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -2042,7 +2094,7 @@ TEST_F(QuicFramerTest, ConstructCloseFramePacket) { }; QuicPacket* data; - EXPECT_TRUE(framer_.ConstructFrameDataPacket(header, frames, &data)); + EXPECT_TRUE(framer_.ConstructFragementDataPacket(header, frames, &data)); test::CompareCharArraysWithHexError("constructed packet", data->data(), data->length(), @@ -2054,6 +2106,7 @@ TEST_F(QuicFramerTest, ConstructCloseFramePacket) { TEST_F(QuicFramerTest, ConstructFecPacket) { QuicPacketHeader header; header.guid = GG_UINT64_C(0xFEDCBA9876543210); + header.retransmission_count = 0x01; header.packet_sequence_number = (GG_UINT64_C(0x123456789ABC)); header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687); header.flags = PACKET_FLAGS_FEC; @@ -2072,6 +2125,8 @@ TEST_F(QuicFramerTest, ConstructFecPacket) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -2099,6 +2154,48 @@ TEST_F(QuicFramerTest, ConstructFecPacket) { delete data; } +TEST_F(QuicFramerTest, IncrementRetransmitCount) { + QuicPacketHeader header; + header.guid = GG_UINT64_C(0xFEDCBA9876543210); + header.retransmission_count = 1; + header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); + header.transmission_time = GG_UINT64_C(0xF0E1D2C3B4A59687); + header.flags = PACKET_FLAGS_NONE; + header.fec_group = 0; + + QuicStreamFrame stream_frame; + stream_frame.stream_id = 0x01020304; + stream_frame.fin = true; + stream_frame.offset = GG_UINT64_C(0xBA98FEDC32107654); + stream_frame.data = "hello world!"; + + QuicFrame frame; + frame.type = STREAM_FRAME; + frame.stream_frame = &stream_frame; + + QuicFrames frames; + frames.push_back(frame); + + QuicPacket *original; + ASSERT_TRUE(framer_.ConstructFragementDataPacket( + header, frames, &original)); + EXPECT_EQ(header.retransmission_count, framer_.GetRetransmitCount(original)); + + header.retransmission_count = 2; + QuicPacket *retransmitted; + ASSERT_TRUE(framer_.ConstructFragementDataPacket( + header, frames, &retransmitted)); + + framer_.IncrementRetransmitCount(original); + EXPECT_EQ(header.retransmission_count, framer_.GetRetransmitCount(original)); + + test::CompareCharArraysWithHexError( + "constructed packet", original->data(), original->length(), + retransmitted->data(), retransmitted->length()); + delete original; + delete retransmitted; +} + TEST_F(QuicFramerTest, EncryptPacket) { unsigned char packet[] = { // guid @@ -2107,6 +2204,8 @@ TEST_F(QuicFramerTest, EncryptPacket) { // packet id 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, + // retransmission count + 0x01, // transmission time 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, @@ -2124,7 +2223,7 @@ TEST_F(QuicFramerTest, EncryptPacket) { 'm', 'n', 'o', 'p', }; - QuicPacket raw(AsChars(packet), arraysize(packet), false, PACKET_FLAGS_NONE); + QuicPacket raw(AsChars(packet), arraysize(packet), false); scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPacket(raw)); ASSERT_TRUE(encrypted.get() != NULL); diff --git a/net/quic/quic_packet_creator.cc b/net/quic/quic_packet_creator.cc index 2b00e2e..deef83d 100644 --- a/net/quic/quic_packet_creator.cc +++ b/net/quic/quic_packet_creator.cc @@ -81,7 +81,7 @@ void QuicPacketCreator::DataToStream(QuicStreamId id, data_to_send -= frame_len; // Produce the data packet (which might fin the stream). - framer_->ConstructFrameDataPacket(header, frames, &packet); + framer_->ConstructFragementDataPacket(header, frames, &packet); DCHECK_GE(options_.max_packet_length, packet->length()); packets->push_back(make_pair(header.packet_sequence_number, packet)); frames.clear(); @@ -93,7 +93,7 @@ void QuicPacketCreator::DataToStream(QuicStreamId id, FillPacketHeader(current_fec_group, PACKET_FLAGS_NONE, &header); QuicStreamFrame frame(id, true, offset, ""); frames.push_back(QuicFrame(&frame)); - framer_->ConstructFrameDataPacket(header, frames, &packet); + framer_->ConstructFragementDataPacket(header, frames, &packet); packets->push_back(make_pair(header.packet_sequence_number, packet)); frames.clear(); } @@ -138,7 +138,7 @@ QuicPacketCreator::PacketPair QuicPacketCreator::ResetStream( QuicPacket* packet; QuicFrames frames; frames.push_back(QuicFrame(&close_frame)); - framer_->ConstructFrameDataPacket(header, frames, &packet); + framer_->ConstructFragementDataPacket(header, frames, &packet); return make_pair(header.packet_sequence_number, packet); } @@ -151,7 +151,7 @@ QuicPacketCreator::PacketPair QuicPacketCreator::CloseConnection( QuicPacket* packet; QuicFrames frames; frames.push_back(QuicFrame(close_frame)); - framer_->ConstructFrameDataPacket(header, frames, &packet); + framer_->ConstructFragementDataPacket(header, frames, &packet); return make_pair(header.packet_sequence_number, packet); } @@ -164,17 +164,10 @@ QuicPacketCreator::PacketPair QuicPacketCreator::AckPacket( QuicPacket* packet; QuicFrames frames; frames.push_back(QuicFrame(ack_frame)); - framer_->ConstructFrameDataPacket(header, frames, &packet); + framer_->ConstructFragementDataPacket(header, frames, &packet); return make_pair(header.packet_sequence_number, packet); } -QuicPacketSequenceNumber QuicPacketCreator::SetNewSequenceNumber( - QuicPacket* packet) { - ++sequence_number_; - framer_->WriteSequenceNumber(sequence_number_, packet); - return sequence_number_; -} - void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group, QuicPacketFlags flags, QuicPacketHeader* header) { @@ -183,6 +176,9 @@ void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group, header->packet_sequence_number = ++sequence_number_; header->fec_group = fec_group; + // Default to zero - the sender should increment this as packets are + // retransmitted. + header->retransmission_count = 0; header->transmission_time = 0; } diff --git a/net/quic/quic_packet_creator.h b/net/quic/quic_packet_creator.h index 38874ad..2aa26b9 100644 --- a/net/quic/quic_packet_creator.h +++ b/net/quic/quic_packet_creator.h @@ -62,10 +62,6 @@ class NET_EXPORT_PRIVATE QuicPacketCreator : public QuicFecBuilderInterface { PacketPair AckPacket(QuicAckFrame* ack_frame); - // Increments the current sequence number in QuicPacketCreator and sets it - // into the packet and returns the new sequence number. - QuicPacketSequenceNumber SetNewSequenceNumber(QuicPacket* packet); - QuicPacketSequenceNumber sequence_number() const { return sequence_number_; } diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h index b91377a..e49b623 100644 --- a/net/quic/quic_protocol.h +++ b/net/quic/quic_protocol.h @@ -35,21 +35,18 @@ const size_t kMaxPacketSize = 1200; // Maximum size in bytes of a QUIC packet. const size_t kDefaultMaxStreamsPerConnection = 100; // Size in bytes of the packet header common across all packets. -const size_t kPacketHeaderSize = 24; +const size_t kPacketHeaderSize = 25; // Index of the first byte in a QUIC packet of FEC protected data. const size_t kStartOfFecProtectedData = kPacketHeaderSize; // Index of the first byte in a QUIC packet of encrypted data. const size_t kStartOfEncryptedData = kPacketHeaderSize - 1; // Index of the first byte in a QUIC packet which is hashed. const size_t kStartOfHashData = 0; -// Index into the sequence number offset in the header. -const int kSequenceNumberOffset = 8; +// Index into the retransmission offset in the header. +// (After GUID and sequence number.) +const int kRetransmissionOffset = 14; // Index into the transmission time offset in the header. -const int kTransmissionTimeOffset = 14; -// Index into the flags offset in the header. -const int kFlagsOffset = 22; -// Index into the fec group offset in the header. -const int kFecGroupOffset = 23; +const int kTransmissionTimeOffset = 15; // Size in bytes of all stream frame fields. const size_t kMinStreamFrameLength = 15; @@ -148,6 +145,7 @@ struct NET_EXPORT_PRIVATE QuicPacketHeader { // from the design docs, as well as some elements of DecryptedData. QuicGuid guid; QuicPacketSequenceNumber packet_sequence_number; + uint8 retransmission_count; QuicTransmissionTime transmission_time; QuicPacketFlags flags; QuicFecGroupNumber fec_group; @@ -354,11 +352,9 @@ class NET_EXPORT_PRIVATE QuicData { class NET_EXPORT_PRIVATE QuicPacket : public QuicData { public: - QuicPacket( - char* buffer, size_t length, bool owns_buffer, QuicPacketFlags flags) + QuicPacket(char* buffer, size_t length, bool owns_buffer) : QuicData(buffer, length, owns_buffer), - buffer_(buffer), - flags_(flags) { } + buffer_(buffer) { } base::StringPiece FecProtectedData() const { return base::StringPiece(data() + kStartOfFecProtectedData, @@ -373,16 +369,10 @@ class NET_EXPORT_PRIVATE QuicPacket : public QuicData { return base::StringPiece(data() + kStartOfEncryptedData, length() - kStartOfEncryptedData); } - - bool IsFecPacket() const { - return flags_ == PACKET_FLAGS_FEC; - } - char* mutable_data() { return buffer_; } private: char* buffer_; - const QuicPacketFlags flags_; DISALLOW_COPY_AND_ASSIGN(QuicPacket); }; diff --git a/net/quic/test_tools/quic_test_utils.cc b/net/quic/test_tools/quic_test_utils.cc index 022cdd0..3e3171f 100644 --- a/net/quic/test_tools/quic_test_utils.cc +++ b/net/quic/test_tools/quic_test_utils.cc @@ -150,6 +150,7 @@ QuicPacket* ConstructHandshakePacket(QuicGuid guid, CryptoTag tag) { QuicPacketHeader header; header.guid = guid; + header.retransmission_count = 0; header.packet_sequence_number = 1; header.transmission_time = 0; header.flags = PACKET_FLAGS_NONE; @@ -162,7 +163,7 @@ QuicPacket* ConstructHandshakePacket(QuicGuid guid, CryptoTag tag) { QuicFrames frames; frames.push_back(frame); QuicPacket* packet; - quic_framer.ConstructFrameDataPacket(header, frames, &packet); + quic_framer.ConstructFragementDataPacket(header, frames, &packet); return packet; } @@ -183,9 +184,8 @@ PacketSavingConnection::~PacketSavingConnection() { bool PacketSavingConnection::SendPacket(QuicPacketSequenceNumber number, QuicPacket* packet, - bool should_resend, - bool force, - bool is_retransmit) { + bool resend, + bool force) { packets_.push_back(packet); return true; } diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h index ead8db8..acabd7c 100644 --- a/net/quic/test_tools/quic_test_utils.h +++ b/net/quic/test_tools/quic_test_utils.h @@ -149,9 +149,8 @@ class PacketSavingConnection : public MockConnection { virtual bool SendPacket(QuicPacketSequenceNumber number, QuicPacket* packet, - bool should_resend, - bool force, - bool is_retransmit) OVERRIDE; + bool resend, + bool force) OVERRIDE; std::vector<QuicPacket*> packets_; }; |