Skip to content

Commit

Permalink
Land Recent QUIC changes.
Browse files Browse the repository at this point in the history
Add another empty packet check to QuicPacketCreator.

Merge internal change: 51128171

Change a DCHECK into LOG(DFATAL) so that we can see if this is actually
happening.

Merge internal change: 51096918

Remove hard-coded version from QuicFramerTest

Merge internal change: 51006687

Reserializing packets for retransmission now use the original sequence
number length, as intended, and a test has been added to verify that.

Also, re-calculating the packet's size anytime no frames have been
added.  Once they've been added, the header size will not change, as
before.

Merge internal change: 51153356

Lazily initialize QuicPacketCreator's packet_size to the header size,
so the sequence_number_length and other overhead can be more accurately
calculated.

Merge internal change: 51071397

Enable variable length sequence numbers in the packet header by
dynamically calculating the necessary length.

Merge internal change: 50917379

R=rch@chromium.org

Review URL: https://chromiumcodereview.appspot.com/23368002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@218781 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
rtenneti@chromium.org committed Aug 21, 2013
1 parent 18194bb commit ea825e0
Show file tree
Hide file tree
Showing 19 changed files with 449 additions and 131 deletions.
44 changes: 41 additions & 3 deletions net/quic/quic_connection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1017,9 +1017,15 @@ void QuicConnection::RetransmitPacket(

// Re-packetize the frames with a new sequence number for retransmission.
// Retransmitted data packets do not use FEC, even when it's enabled.
// Retransmitted packets use the same sequence number length as the original.
QuicSequenceNumberLength original_sequence_number_length =
retransmission_it->second.sequence_number_length;
SerializedPacket serialized_packet =
packet_creator_.SerializeAllFrames(unacked->frames());
RetransmissionInfo retransmission_info(serialized_packet.sequence_number);
packet_creator_.ReserializeAllFrames(unacked->frames(),
original_sequence_number_length);
RetransmissionInfo retransmission_info(
serialized_packet.sequence_number,
serialized_packet.sequence_number_length);
retransmission_info.number_retransmissions =
retransmission_it->second.number_retransmissions + 1;
// Remove info with old sequence number.
Expand Down Expand Up @@ -1223,6 +1229,11 @@ bool QuicConnection::WritePacket(EncryptionLevel level,
SetupAbandonFecTimer(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_.options()->send_sequence_number_length =
CalculateSequenceNumberLength(sequence_number);

congestion_manager_.SentPacket(sequence_number, now, packet->length(),
retransmission);

Expand Down Expand Up @@ -1252,6 +1263,31 @@ int QuicConnection::WritePacketToWire(QuicPacketSequenceNumber sequence_number,
return bytes_written;
}

QuicSequenceNumberLength QuicConnection::CalculateSequenceNumberLength(
QuicPacketSequenceNumber sequence_number) {
DCHECK_LE(received_packet_manager_.least_packet_awaited_by_peer(),
sequence_number);
// Since the packet creator will not change sequence number length mid FEC
// group, include the size of an FEC group to be safe.
const QuicPacketSequenceNumber current_delta =
packet_creator_.options()->max_packets_per_fec_group + sequence_number
- received_packet_manager_.least_packet_awaited_by_peer();
const uint64 congestion_window =
congestion_manager_.BandwidthEstimate().ToBytesPerPeriod(
congestion_manager_.SmoothedRtt()) /
packet_creator_.options()->max_packet_length;
const uint64 delta = max(current_delta, congestion_window);

if (delta < 1 << ((PACKET_1BYTE_SEQUENCE_NUMBER * 8) - 2)) {
return PACKET_1BYTE_SEQUENCE_NUMBER;
} else if (delta < 1 << ((PACKET_2BYTE_SEQUENCE_NUMBER * 8) - 2)) {
return PACKET_2BYTE_SEQUENCE_NUMBER;
} else if (delta < 1 << ((PACKET_4BYTE_SEQUENCE_NUMBER * 8) - 2)) {
return PACKET_4BYTE_SEQUENCE_NUMBER;
}
return PACKET_6BYTE_SEQUENCE_NUMBER;
}

bool QuicConnection::OnSerializedPacket(
const SerializedPacket& serialized_packet) {
if (serialized_packet.retransmittable_frames != NULL) {
Expand All @@ -1268,7 +1304,9 @@ bool QuicConnection::OnSerializedPacket(
// All unacked packets might be retransmitted.
retransmission_map_.insert(
make_pair(serialized_packet.sequence_number,
RetransmissionInfo(serialized_packet.sequence_number)));
RetransmissionInfo(
serialized_packet.sequence_number,
serialized_packet.sequence_number_length)));
} else if (serialized_packet.packet->is_fec_packet()) {
unacked_fec_packets_.insert(make_pair(
serialized_packet.sequence_number,
Expand Down
11 changes: 10 additions & 1 deletion net/quic/quic_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -453,13 +453,16 @@ class NET_EXPORT_PRIVATE QuicConnection
};

struct RetransmissionInfo {
explicit RetransmissionInfo(QuicPacketSequenceNumber sequence_number)
RetransmissionInfo(QuicPacketSequenceNumber sequence_number,
QuicSequenceNumberLength sequence_number_length)
: sequence_number(sequence_number),
sequence_number_length(sequence_number_length),
number_nacks(0),
number_retransmissions(0) {
}

QuicPacketSequenceNumber sequence_number;
QuicSequenceNumberLength sequence_number_length;
size_t number_nacks;
size_t number_retransmissions;
};
Expand Down Expand Up @@ -514,6 +517,12 @@ class NET_EXPORT_PRIVATE QuicConnection
// Returns false if the socket has become blocked.
bool DoWrite();

// Calculates the smallest sequence number length that can also represent four
// times the maximum of the congestion window and the difference between the
// least_packet_awaited_by_peer_ and |sequence_number|.
QuicSequenceNumberLength CalculateSequenceNumberLength(
QuicPacketSequenceNumber sequence_number);

// Drop packet corresponding to |sequence_number| by deleting entries from
// |unacked_packets_| and |retransmission_map_|, if present. We need to drop
// all packets with encryption level NONE after the default level has been set
Expand Down
6 changes: 6 additions & 0 deletions net/quic/quic_connection_helper_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ class QuicConnectionHelperTest : public ::testing::Test {
send_algorithm_ = new testing::StrictMock<MockSendAlgorithm>();
EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)).
WillRepeatedly(testing::Return(QuicTime::Delta::Zero()));
EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly(
testing::Return(QuicBandwidth::FromKBitsPerSecond(100)));
EXPECT_CALL(*send_algorithm_, SmoothedRtt()).WillRepeatedly(
testing::Return(QuicTime::Delta::FromMilliseconds(100)));
connection_.reset(new TestConnection(guid_, IPEndPoint(), helper_));
connection_->set_visitor(&visitor_);
connection_->SetSendAlgorithm(send_algorithm_);
Expand Down Expand Up @@ -199,6 +203,7 @@ class QuicConnectionHelperTest : public ::testing::Test {
header_.public_header.guid = guid_;
header_.public_header.reset_flag = false;
header_.public_header.version_flag = true;
header_.public_header.sequence_number_length = PACKET_1BYTE_SEQUENCE_NUMBER;
header_.packet_sequence_number = sequence_number;
header_.entropy_flag = false;
header_.fec_flag = false;
Expand Down Expand Up @@ -312,6 +317,7 @@ TEST_F(QuicConnectionHelperTest, TestRetransmission) {

EXPECT_CALL(*send_algorithm_, SentPacket(_, 1, _, NOT_RETRANSMISSION));
EXPECT_CALL(*send_algorithm_, AbandoningPacket(1, _));

// Send a packet.
connection_->SendStreamData(1, kData, 0, false);
EXPECT_CALL(*send_algorithm_, SentPacket(_, 2, _, IS_RETRANSMISSION));
Expand Down
155 changes: 131 additions & 24 deletions net/quic/quic_connection_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,10 @@ class QuicConnectionTest : public ::testing::Test {
EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(AnyNumber());
EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
Return(QuicTime::Delta::Zero()));
EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly(Return(
QuicBandwidth::FromKBitsPerSecond(100)));
EXPECT_CALL(*send_algorithm_, SmoothedRtt()).WillRepeatedly(Return(
QuicTime::Delta::FromMilliseconds(100)));
}

QuicAckFrame* outgoing_ack() {
Expand Down Expand Up @@ -807,20 +811,20 @@ TEST_F(QuicConnectionTest, TruncatedAck) {
}

QuicAckFrame frame(0, QuicTime::Zero(), 1);
frame.received_info.largest_observed = 192;
InsertMissingPacketsBetween(&frame.received_info, 1, 192);
frame.received_info.largest_observed = 193;
InsertMissingPacketsBetween(&frame.received_info, 1, 193);
frame.received_info.entropy_hash =
QuicConnectionPeer::GetSentEntropyHash(&connection_, 192) ^
QuicConnectionPeer::GetSentEntropyHash(&connection_, 191);
QuicConnectionPeer::GetSentEntropyHash(&connection_, 193) ^
QuicConnectionPeer::GetSentEntropyHash(&connection_, 192);

ProcessAckPacket(&frame, true);

EXPECT_TRUE(QuicConnectionPeer::GetReceivedTruncatedAck(&connection_));

frame.received_info.missing_packets.erase(191);
frame.received_info.missing_packets.erase(192);
frame.received_info.entropy_hash =
QuicConnectionPeer::GetSentEntropyHash(&connection_, 192) ^
QuicConnectionPeer::GetSentEntropyHash(&connection_, 190);
QuicConnectionPeer::GetSentEntropyHash(&connection_, 193) ^
QuicConnectionPeer::GetSentEntropyHash(&connection_, 191);

ProcessAckPacket(&frame, true);
EXPECT_FALSE(QuicConnectionPeer::GetReceivedTruncatedAck(&connection_));
Expand Down Expand Up @@ -958,6 +962,106 @@ TEST_F(QuicConnectionTest, AckAll) {
ProcessAckPacket(&frame1, true);
}

TEST_F(QuicConnectionTest, SendingDifferentSequenceNumberLengthsBandwidth) {
EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillOnce(Return(
QuicBandwidth::FromKBitsPerSecond(1000)));

QuicPacketSequenceNumber last_packet;
SendStreamDataToPeer(1, "foo", 0, !kFin, &last_packet);
EXPECT_EQ(1u, last_packet);
EXPECT_EQ(PACKET_1BYTE_SEQUENCE_NUMBER,
connection_.options()->send_sequence_number_length);
EXPECT_EQ(PACKET_1BYTE_SEQUENCE_NUMBER,
last_header()->public_header.sequence_number_length);

EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillOnce(Return(
QuicBandwidth::FromKBitsPerSecond(1000 * 256)));

SendStreamDataToPeer(1u, "bar", 3, !kFin, &last_packet);
EXPECT_EQ(2u, last_packet);
EXPECT_EQ(PACKET_2BYTE_SEQUENCE_NUMBER,
connection_.options()->send_sequence_number_length);
// The 1 packet lag is due to the sequence number length being recalculated in
// QuicConnection after a packet is sent.
EXPECT_EQ(PACKET_1BYTE_SEQUENCE_NUMBER,
last_header()->public_header.sequence_number_length);

EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillOnce(Return(
QuicBandwidth::FromKBitsPerSecond(1000 * 256 * 256)));

SendStreamDataToPeer(1, "foo", 6, !kFin, &last_packet);
EXPECT_EQ(3u, last_packet);
EXPECT_EQ(PACKET_4BYTE_SEQUENCE_NUMBER,
connection_.options()->send_sequence_number_length);
EXPECT_EQ(PACKET_2BYTE_SEQUENCE_NUMBER,
last_header()->public_header.sequence_number_length);

EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillOnce(Return(
QuicBandwidth::FromKBitsPerSecond(1000ll * 256 * 256 * 256)));

SendStreamDataToPeer(1u, "bar", 9, !kFin, &last_packet);
EXPECT_EQ(4u, last_packet);
EXPECT_EQ(PACKET_4BYTE_SEQUENCE_NUMBER,
connection_.options()->send_sequence_number_length);
EXPECT_EQ(PACKET_4BYTE_SEQUENCE_NUMBER,
last_header()->public_header.sequence_number_length);

EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillOnce(Return(
QuicBandwidth::FromKBitsPerSecond(1000ll * 256 * 256 * 256 * 256)));

SendStreamDataToPeer(1u, "foo", 12, !kFin, &last_packet);
EXPECT_EQ(5u, last_packet);
EXPECT_EQ(PACKET_6BYTE_SEQUENCE_NUMBER,
connection_.options()->send_sequence_number_length);
EXPECT_EQ(PACKET_4BYTE_SEQUENCE_NUMBER,
last_header()->public_header.sequence_number_length);
}

TEST_F(QuicConnectionTest, SendingDifferentSequenceNumberLengthsUnackedDelta) {
QuicPacketSequenceNumber last_packet;
SendStreamDataToPeer(1, "foo", 0, !kFin, &last_packet);
EXPECT_EQ(1u, last_packet);
EXPECT_EQ(PACKET_1BYTE_SEQUENCE_NUMBER,
connection_.options()->send_sequence_number_length);
EXPECT_EQ(PACKET_1BYTE_SEQUENCE_NUMBER,
last_header()->public_header.sequence_number_length);

QuicConnectionPeer::GetPacketCreator(&connection_)->set_sequence_number(100);

SendStreamDataToPeer(1u, "bar", 3, !kFin, &last_packet);
EXPECT_EQ(PACKET_2BYTE_SEQUENCE_NUMBER,
connection_.options()->send_sequence_number_length);
EXPECT_EQ(PACKET_1BYTE_SEQUENCE_NUMBER,
last_header()->public_header.sequence_number_length);

QuicConnectionPeer::GetPacketCreator(&connection_)->set_sequence_number(
100 * 256);

SendStreamDataToPeer(1, "foo", 6, !kFin, &last_packet);
EXPECT_EQ(PACKET_4BYTE_SEQUENCE_NUMBER,
connection_.options()->send_sequence_number_length);
EXPECT_EQ(PACKET_2BYTE_SEQUENCE_NUMBER,
last_header()->public_header.sequence_number_length);

QuicConnectionPeer::GetPacketCreator(&connection_)->set_sequence_number(
100 * 256 * 256);

SendStreamDataToPeer(1u, "bar", 9, !kFin, &last_packet);
EXPECT_EQ(PACKET_4BYTE_SEQUENCE_NUMBER,
connection_.options()->send_sequence_number_length);
EXPECT_EQ(PACKET_4BYTE_SEQUENCE_NUMBER,
last_header()->public_header.sequence_number_length);

QuicConnectionPeer::GetPacketCreator(&connection_)->set_sequence_number(
100 * 256 * 256 * 256);

SendStreamDataToPeer(1u, "foo", 12, !kFin, &last_packet);
EXPECT_EQ(PACKET_6BYTE_SEQUENCE_NUMBER,
connection_.options()->send_sequence_number_length);
EXPECT_EQ(PACKET_4BYTE_SEQUENCE_NUMBER,
last_header()->public_header.sequence_number_length);
}

TEST_F(QuicConnectionTest, BasicSending) {
EXPECT_CALL(*send_algorithm_, OnIncomingAck(_, _, _)).Times(6);
QuicPacketSequenceNumber last_packet;
Expand Down Expand Up @@ -1021,8 +1125,9 @@ TEST_F(QuicConnectionTest, FECSending) {
// All packets carry version info till version is negotiated.
size_t payload_length;
connection_.options()->max_packet_length =
GetPacketLengthForOneStream(connection_.version(), kIncludeVersion,
IN_FEC_GROUP, &payload_length);
GetPacketLengthForOneStream(
connection_.version(), kIncludeVersion, PACKET_1BYTE_SEQUENCE_NUMBER,
IN_FEC_GROUP, &payload_length);
// And send FEC every two packets.
connection_.options()->max_packets_per_fec_group = 2;

Expand All @@ -1039,8 +1144,9 @@ TEST_F(QuicConnectionTest, FECQueueing) {
// All packets carry version info till version is negotiated.
size_t payload_length;
connection_.options()->max_packet_length =
GetPacketLengthForOneStream(connection_.version(), kIncludeVersion,
IN_FEC_GROUP, &payload_length);
GetPacketLengthForOneStream(
connection_.version(), kIncludeVersion, PACKET_1BYTE_SEQUENCE_NUMBER,
IN_FEC_GROUP, &payload_length);
// And send FEC every two packets.
connection_.options()->max_packets_per_fec_group = 2;

Expand Down Expand Up @@ -1261,12 +1367,11 @@ TEST_F(QuicConnectionTest, RetransmitNackedPacketsOnTruncatedAck) {

// Make a truncated ack frame.
QuicAckFrame frame(0, QuicTime::Zero(), 1);
frame.received_info.largest_observed = 192;
InsertMissingPacketsBetween(&frame.received_info, 1, 192);
frame.received_info.largest_observed = 193;
InsertMissingPacketsBetween(&frame.received_info, 1, 193);
frame.received_info.entropy_hash =
QuicConnectionPeer::GetSentEntropyHash(&connection_, 192) ^
QuicConnectionPeer::GetSentEntropyHash(&connection_, 191);

QuicConnectionPeer::GetSentEntropyHash(&connection_, 193) ^
QuicConnectionPeer::GetSentEntropyHash(&connection_, 192);

EXPECT_CALL(*send_algorithm_, OnIncomingAck(_, _, _)).Times(1);
EXPECT_CALL(*send_algorithm_, OnIncomingLoss(_)).Times(1);
Expand All @@ -1277,16 +1382,16 @@ TEST_F(QuicConnectionTest, RetransmitNackedPacketsOnTruncatedAck) {
QuicConnectionPeer::SetMaxPacketsPerRetransmissionAlarm(&connection_, 200);
clock_.AdvanceTime(DefaultRetransmissionTime());
// Only packets that are less than largest observed should be retransmitted.
EXPECT_CALL(*send_algorithm_, AbandoningPacket(_, _)).Times(191);
EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(191);
EXPECT_CALL(*send_algorithm_, AbandoningPacket(_, _)).Times(192);
EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(192);
connection_.OnRetransmissionTimeout();

clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(
2 * DefaultRetransmissionTime().ToMicroseconds()));
// Retransmit already retransmitted packets event though the sequence number
// greater than the largest observed.
EXPECT_CALL(*send_algorithm_, AbandoningPacket(_, _)).Times(191);
EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(191);
EXPECT_CALL(*send_algorithm_, AbandoningPacket(_, _)).Times(192);
EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(192);
connection_.OnRetransmissionTimeout();
}

Expand Down Expand Up @@ -1948,8 +2053,9 @@ TEST_F(QuicConnectionTest, TestQueueLimitsOnSendStreamData) {
// All packets carry version info till version is negotiated.
size_t payload_length;
connection_.options()->max_packet_length =
GetPacketLengthForOneStream(connection_.version(), kIncludeVersion,
NOT_IN_FEC_GROUP, &payload_length);
GetPacketLengthForOneStream(
connection_.version(), kIncludeVersion, PACKET_1BYTE_SEQUENCE_NUMBER,
NOT_IN_FEC_GROUP, &payload_length);

// Queue the first packet.
EXPECT_CALL(*send_algorithm_,
Expand All @@ -1965,8 +2071,9 @@ TEST_F(QuicConnectionTest, LoopThroughSendingPackets) {
// All packets carry version info till version is negotiated.
size_t payload_length;
connection_.options()->max_packet_length =
GetPacketLengthForOneStream(connection_.version(), kIncludeVersion,
NOT_IN_FEC_GROUP, &payload_length);
GetPacketLengthForOneStream(
connection_.version(), kIncludeVersion, PACKET_1BYTE_SEQUENCE_NUMBER,
NOT_IN_FEC_GROUP, &payload_length);

// Queue the first packet.
EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(7);
Expand Down
Loading

0 comments on commit ea825e0

Please sign in to comment.