Index: net/quic/quic_framer_test.cc |
diff --git a/net/quic/quic_framer_test.cc b/net/quic/quic_framer_test.cc |
index d14e673f85e1fb4c93d4a7cbb33a10af82f70556..2c3d2749d3b59bacc2e2942f73fc40a86ddac639 100644 |
--- a/net/quic/quic_framer_test.cc |
+++ b/net/quic/quic_framer_test.cc |
@@ -460,7 +460,7 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> { |
void CheckStreamFrameBoundaries(unsigned char* packet, |
size_t stream_id_size, |
bool include_version) { |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
for (size_t i = kQuicFrameTypeSize; i < GetMinStreamFrameSize(); ++i) { |
string expected_error; |
if (i < kQuicFrameTypeSize + stream_id_size) { |
@@ -682,7 +682,7 @@ TEST_P(QuicFramerTest, PacketHeader) { |
EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group); |
EXPECT_EQ(0x00u, visitor_.header_->fec_group); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
for (size_t i = 0; |
i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, |
PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); |
@@ -735,7 +735,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith4ByteConnectionId) { |
EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group); |
EXPECT_EQ(0x00u, visitor_.header_->fec_group); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
for (size_t i = 0; |
i < GetPacketHeaderSize(PACKET_4BYTE_CONNECTION_ID, !kIncludeVersion, |
PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); |
@@ -791,7 +791,7 @@ TEST_P(QuicFramerTest, PacketHeader1ByteConnectionId) { |
EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group); |
EXPECT_EQ(0x00u, visitor_.header_->fec_group); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
for (size_t i = 0; |
i < GetPacketHeaderSize(PACKET_1BYTE_CONNECTION_ID, !kIncludeVersion, |
PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); |
@@ -846,7 +846,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) { |
EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group); |
EXPECT_EQ(0x00u, visitor_.header_->fec_group); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
for (size_t i = 0; |
i < GetPacketHeaderSize(PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion, |
PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); |
@@ -903,7 +903,7 @@ TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) { |
EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group); |
EXPECT_EQ(0x00u, visitor_.header_->fec_group); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
for (size_t i = 0; |
i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, kIncludeVersion, |
PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); |
@@ -958,7 +958,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith4ByteSequenceNumber) { |
EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group); |
EXPECT_EQ(0x00u, visitor_.header_->fec_group); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
for (size_t i = 0; |
i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, |
PACKET_4BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); |
@@ -1013,7 +1013,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith2ByteSequenceNumber) { |
EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group); |
EXPECT_EQ(0x00u, visitor_.header_->fec_group); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
for (size_t i = 0; |
i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, |
PACKET_2BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); |
@@ -1068,7 +1068,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith1ByteSequenceNumber) { |
EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group); |
EXPECT_EQ(0x00u, visitor_.header_->fec_group); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
for (size_t i = 0; |
i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, |
PACKET_1BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); |
@@ -1307,7 +1307,7 @@ TEST_P(QuicFramerTest, StreamFrame) { |
visitor_.stream_frames_[0]->offset); |
CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
CheckStreamFrameBoundaries(packet, kQuicMaxStreamIdSize, !kIncludeVersion); |
} |
@@ -1355,7 +1355,7 @@ TEST_P(QuicFramerTest, StreamFrame3ByteStreamId) { |
visitor_.stream_frames_[0]->offset); |
CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
const size_t stream_id_size = 3; |
CheckStreamFrameBoundaries(packet, stream_id_size, !kIncludeVersion); |
} |
@@ -1404,7 +1404,7 @@ TEST_P(QuicFramerTest, StreamFrame2ByteStreamId) { |
visitor_.stream_frames_[0]->offset); |
CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
const size_t stream_id_size = 2; |
CheckStreamFrameBoundaries(packet, stream_id_size, !kIncludeVersion); |
} |
@@ -1453,7 +1453,7 @@ TEST_P(QuicFramerTest, StreamFrame1ByteStreamId) { |
visitor_.stream_frames_[0]->offset); |
CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
const size_t stream_id_size = 1; |
CheckStreamFrameBoundaries(packet, stream_id_size, !kIncludeVersion); |
} |
@@ -1506,7 +1506,7 @@ TEST_P(QuicFramerTest, StreamFrameWithVersion) { |
visitor_.stream_frames_[0]->offset); |
CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
CheckStreamFrameBoundaries(packet, kQuicMaxStreamIdSize, kIncludeVersion); |
} |
@@ -1682,7 +1682,445 @@ TEST_P(QuicFramerTest, StreamFrameInFecGroup) { |
CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]); |
} |
+TEST_P(QuicFramerTest, AckFramev22) { |
+ if (version_ > QUIC_VERSION_22) { |
+ return; |
+ } |
+ unsigned char packet[] = { |
+ // public flags (8 byte connection_id) |
+ 0x3C, |
+ // connection_id |
+ 0x10, 0x32, 0x54, 0x76, |
+ 0x98, 0xBA, 0xDC, 0xFE, |
+ // packet sequence number |
+ 0xA8, 0x9A, 0x78, 0x56, |
+ 0x34, 0x12, |
+ // private flags (entropy) |
+ 0x01, |
+ |
+ // frame type (ack frame) |
+ // (has nacks, not truncated, 6 byte largest observed, 1 byte delta) |
+ 0x6C, |
+ // entropy hash of all received packets. |
+ 0xBA, |
+ // largest observed packet sequence number |
+ 0xBF, 0x9A, 0x78, 0x56, |
+ 0x34, 0x12, |
+ // Zero delta time. |
+ 0x0, 0x0, |
+ // num missing packets |
+ 0x01, |
+ // missing packet delta |
+ 0x01, |
+ // 0 more missing packets in range. |
+ 0x00, |
+ // Number of revived packets. |
+ 0x00, |
+ }; |
+ |
+ QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); |
+ EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
+ |
+ EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
+ ASSERT_TRUE(visitor_.header_.get()); |
+ EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); |
+ |
+ EXPECT_EQ(0u, visitor_.stream_frames_.size()); |
+ ASSERT_EQ(1u, visitor_.ack_frames_.size()); |
+ const QuicAckFrame& frame = *visitor_.ack_frames_[0]; |
+ EXPECT_EQ(0xBA, frame.entropy_hash); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed); |
+ ASSERT_EQ(1u, frame.missing_packets.size()); |
+ SequenceNumberSet::const_iterator missing_iter = |
+ frame.missing_packets.begin(); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter); |
+ |
+ const size_t kReceivedEntropyOffset = kQuicFrameTypeSize; |
+ const size_t kLargestObservedOffset = kReceivedEntropyOffset + |
+ kQuicEntropyHashSize; |
+ const size_t kMissingDeltaTimeOffset = kLargestObservedOffset + |
+ PACKET_6BYTE_SEQUENCE_NUMBER; |
+ const size_t kNumMissingPacketOffset = kMissingDeltaTimeOffset + |
+ kQuicDeltaTimeLargestObservedSize; |
+ const size_t kMissingPacketsOffset = kNumMissingPacketOffset + |
+ kNumberOfNackRangesSize; |
+ const size_t kMissingPacketsRange = kMissingPacketsOffset + |
+ PACKET_1BYTE_SEQUENCE_NUMBER; |
+ const size_t kRevivedPacketsLength = kMissingPacketsRange + |
+ PACKET_1BYTE_SEQUENCE_NUMBER; |
+ // Now test framing boundaries. |
+ const size_t ack_frame_size = kRevivedPacketsLength + |
+ PACKET_1BYTE_SEQUENCE_NUMBER; |
+ for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) { |
+ string expected_error; |
+ if (i < kLargestObservedOffset) { |
+ expected_error = "Unable to read entropy hash for received packets."; |
+ } else if (i < kMissingDeltaTimeOffset) { |
+ expected_error = "Unable to read largest observed."; |
+ } else if (i < kNumMissingPacketOffset) { |
+ expected_error = "Unable to read delta time largest observed."; |
+ } else if (i < kMissingPacketsOffset) { |
+ expected_error = "Unable to read num missing packet ranges."; |
+ } else if (i < kMissingPacketsRange) { |
+ expected_error = "Unable to read missing sequence number delta."; |
+ } else if (i < kRevivedPacketsLength) { |
+ expected_error = "Unable to read missing sequence number range."; |
+ } else { |
+ expected_error = "Unable to read num revived packets."; |
+ } |
+ CheckProcessingFails( |
+ packet, |
+ i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, |
+ PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), |
+ expected_error, QUIC_INVALID_ACK_DATA); |
+ } |
+} |
+ |
+ |
+TEST_P(QuicFramerTest, AckFrameTwoTimestamp) { |
+ if (version_ <= QUIC_VERSION_22) { |
+ return; |
+ } |
+ unsigned char packet[] = { |
+ // public flags (8 byte connection_id) |
+ 0x3C, |
+ // connection_id |
+ 0x10, 0x32, 0x54, 0x76, |
+ 0x98, 0xBA, 0xDC, 0xFE, |
+ // packet sequence number |
+ 0xA8, 0x9A, 0x78, 0x56, |
+ 0x34, 0x12, |
+ // private flags (entropy) |
+ 0x01, |
+ |
+ // frame type (ack frame) |
+ // (has nacks, not truncated, 6 byte largest observed, 1 byte delta) |
+ 0x6C, |
+ // entropy hash of all received packets. |
+ 0xBA, |
+ // largest observed packet sequence number |
+ 0xBF, 0x9A, 0x78, 0x56, |
+ 0x34, 0x12, |
+ // Zero delta time. |
+ 0x0, 0x0, |
+ // Number of timestamps. |
+ 0x02, |
+ // Delta from largest observed. |
+ 0x01, |
+ // Delta time. |
+ 0x10, 0x32, 0x54, 0x76, |
+ // Delta from largest observed. |
+ 0x02, |
+ // Delta time. |
+ 0x10, 0x32, |
+ // num missing packets |
+ 0x01, |
+ // missing packet delta |
+ 0x01, |
+ // 0 more missing packets in range. |
+ 0x00, |
+ // Number of revived packets. |
+ 0x00, |
+ }; |
+ |
+ QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); |
+ EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
+ |
+ EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
+ ASSERT_TRUE(visitor_.header_.get()); |
+ EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); |
+ |
+ EXPECT_EQ(0u, visitor_.stream_frames_.size()); |
+ ASSERT_EQ(1u, visitor_.ack_frames_.size()); |
+ const QuicAckFrame& frame = *visitor_.ack_frames_[0]; |
+ EXPECT_EQ(0xBA, frame.entropy_hash); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed); |
+ ASSERT_EQ(1u, frame.missing_packets.size()); |
+ ASSERT_EQ(2u, frame.received_packet_times.size()); |
+ SequenceNumberSet::const_iterator missing_iter = |
+ frame.missing_packets.begin(); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter); |
+ |
+ const size_t kReceivedEntropyOffset = kQuicFrameTypeSize; |
+ const size_t kLargestObservedOffset = kReceivedEntropyOffset + |
+ kQuicEntropyHashSize; |
+ const size_t kMissingDeltaTimeOffset = kLargestObservedOffset + |
+ PACKET_6BYTE_SEQUENCE_NUMBER; |
+ const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset + |
+ kQuicDeltaTimeLargestObservedSize; |
+ const size_t kTimestampDeltaLargestObserved1 = kNumTimestampsOffset + |
+ kQuicNumTimestampsSize; |
+ const size_t kTimestampTimeDeltaLargestObserved1 = |
+ kTimestampDeltaLargestObserved1 + 1; |
+ const size_t kTimestampDeltaLargestObserved2 = |
+ kTimestampTimeDeltaLargestObserved1 + 4; |
+ const size_t kTimestampTimeDeltaLargestObserved2 = |
+ kTimestampDeltaLargestObserved2 + 1; |
+ const size_t kNumMissingPacketOffset = |
+ kTimestampTimeDeltaLargestObserved2 + 2; |
+ const size_t kMissingPacketsOffset = kNumMissingPacketOffset + |
+ kNumberOfNackRangesSize; |
+ const size_t kMissingPacketsRange = kMissingPacketsOffset + |
+ PACKET_1BYTE_SEQUENCE_NUMBER; |
+ const size_t kRevivedPacketsLength = kMissingPacketsRange + |
+ PACKET_1BYTE_SEQUENCE_NUMBER; |
+ // Now test framing boundaries. |
+ const size_t ack_frame_size = kRevivedPacketsLength + |
+ PACKET_1BYTE_SEQUENCE_NUMBER; |
+ for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) { |
+ string expected_error; |
+ if (i < kLargestObservedOffset) { |
+ expected_error = "Unable to read entropy hash for received packets."; |
+ } else if (i < kMissingDeltaTimeOffset) { |
+ expected_error = "Unable to read largest observed."; |
+ } else if (i < kNumTimestampsOffset) { |
+ expected_error = "Unable to read delta time largest observed."; |
+ } else if (i < kTimestampDeltaLargestObserved1) { |
+ expected_error = "Unable to read num received packets."; |
+ } else if (i < kTimestampTimeDeltaLargestObserved1) { |
+ expected_error = "Unable to read sequence delta in received packets."; |
+ } else if (i < kTimestampDeltaLargestObserved2) { |
+ expected_error = "Unable to read time delta in received packets."; |
+ } else if (i < kTimestampTimeDeltaLargestObserved2) { |
+ expected_error = "Unable to read sequence delta in received packets."; |
+ } else if (i < kNumMissingPacketOffset) { |
+ expected_error = |
+ "Unable to read incremental time delta in received packets."; |
+ } else if (i < kMissingPacketsOffset) { |
+ expected_error = "Unable to read num missing packet ranges."; |
+ } else if (i < kMissingPacketsRange) { |
+ expected_error = "Unable to read missing sequence number delta."; |
+ } else if (i < kRevivedPacketsLength) { |
+ expected_error = "Unable to read missing sequence number range."; |
+ } else { |
+ expected_error = "Unable to read num revived packets."; |
+ } |
+ CheckProcessingFails( |
+ packet, |
+ i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, |
+ PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), |
+ expected_error, QUIC_INVALID_ACK_DATA); |
+ } |
+} |
+ |
+ |
+TEST_P(QuicFramerTest, AckFrameOneTimestamp) { |
+ if (version_ <= QUIC_VERSION_22) { |
+ return; |
+ } |
+ unsigned char packet[] = { |
+ // public flags (8 byte connection_id) |
+ 0x3C, |
+ // connection_id |
+ 0x10, 0x32, 0x54, 0x76, |
+ 0x98, 0xBA, 0xDC, 0xFE, |
+ // packet sequence number |
+ 0xA8, 0x9A, 0x78, 0x56, |
+ 0x34, 0x12, |
+ // private flags (entropy) |
+ 0x01, |
+ |
+ // frame type (ack frame) |
+ // (has nacks, not truncated, 6 byte largest observed, 1 byte delta) |
+ 0x6C, |
+ // entropy hash of all received packets. |
+ 0xBA, |
+ // largest observed packet sequence number |
+ 0xBF, 0x9A, 0x78, 0x56, |
+ 0x34, 0x12, |
+ // Zero delta time. |
+ 0x0, 0x0, |
+ // Number of timestamps. |
+ 0x01, |
+ // Delta from largest observed. |
+ 0x01, |
+ // Delta time. |
+ 0x10, 0x32, 0x54, 0x76, |
+ // num missing packets |
+ 0x01, |
+ // missing packet delta |
+ 0x01, |
+ // 0 more missing packets in range. |
+ 0x00, |
+ // Number of revived packets. |
+ 0x00, |
+ }; |
+ |
+ QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); |
+ EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
+ |
+ EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
+ ASSERT_TRUE(visitor_.header_.get()); |
+ EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); |
+ |
+ EXPECT_EQ(0u, visitor_.stream_frames_.size()); |
+ ASSERT_EQ(1u, visitor_.ack_frames_.size()); |
+ const QuicAckFrame& frame = *visitor_.ack_frames_[0]; |
+ EXPECT_EQ(0xBA, frame.entropy_hash); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed); |
+ ASSERT_EQ(1u, frame.missing_packets.size()); |
+ ASSERT_EQ(1u, frame.received_packet_times.size()); |
+ SequenceNumberSet::const_iterator missing_iter = |
+ frame.missing_packets.begin(); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter); |
+ |
+ const size_t kReceivedEntropyOffset = kQuicFrameTypeSize; |
+ const size_t kLargestObservedOffset = kReceivedEntropyOffset + |
+ kQuicEntropyHashSize; |
+ const size_t kMissingDeltaTimeOffset = kLargestObservedOffset + |
+ PACKET_6BYTE_SEQUENCE_NUMBER; |
+ const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset + |
+ kQuicDeltaTimeLargestObservedSize; |
+ const size_t kTimestampDeltaLargestObserved = kNumTimestampsOffset + |
+ kQuicNumTimestampsSize; |
+ const size_t kTimestampTimeDeltaLargestObserved = |
+ kTimestampDeltaLargestObserved + 1; |
+ const size_t kNumMissingPacketOffset = kTimestampTimeDeltaLargestObserved + 4; |
+ const size_t kMissingPacketsOffset = kNumMissingPacketOffset + |
+ kNumberOfNackRangesSize; |
+ const size_t kMissingPacketsRange = kMissingPacketsOffset + |
+ PACKET_1BYTE_SEQUENCE_NUMBER; |
+ const size_t kRevivedPacketsLength = kMissingPacketsRange + |
+ PACKET_1BYTE_SEQUENCE_NUMBER; |
+ // Now test framing boundaries. |
+ const size_t ack_frame_size = kRevivedPacketsLength + |
+ PACKET_1BYTE_SEQUENCE_NUMBER; |
+ for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) { |
+ string expected_error; |
+ if (i < kLargestObservedOffset) { |
+ expected_error = "Unable to read entropy hash for received packets."; |
+ } else if (i < kMissingDeltaTimeOffset) { |
+ expected_error = "Unable to read largest observed."; |
+ } else if (i < kNumTimestampsOffset) { |
+ expected_error = "Unable to read delta time largest observed."; |
+ } else if (i < kTimestampDeltaLargestObserved) { |
+ expected_error = "Unable to read num received packets."; |
+ } else if (i < kTimestampTimeDeltaLargestObserved) { |
+ expected_error = "Unable to read sequence delta in received packets."; |
+ } else if (i < kNumMissingPacketOffset) { |
+ expected_error = "Unable to read time delta in received packets."; |
+ } else if (i < kMissingPacketsOffset) { |
+ expected_error = "Unable to read num missing packet ranges."; |
+ } else if (i < kMissingPacketsRange) { |
+ expected_error = "Unable to read missing sequence number delta."; |
+ } else if (i < kRevivedPacketsLength) { |
+ expected_error = "Unable to read missing sequence number range."; |
+ } else { |
+ expected_error = "Unable to read num revived packets."; |
+ } |
+ CheckProcessingFails( |
+ packet, |
+ i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, |
+ PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), |
+ expected_error, QUIC_INVALID_ACK_DATA); |
+ } |
+} |
+ |
+ |
TEST_P(QuicFramerTest, AckFrame) { |
+ if (version_ <= QUIC_VERSION_22) { |
+ return; |
+ } |
+ unsigned char packet[] = { |
+ // public flags (8 byte connection_id) |
+ 0x3C, |
+ // connection_id |
+ 0x10, 0x32, 0x54, 0x76, |
+ 0x98, 0xBA, 0xDC, 0xFE, |
+ // packet sequence number |
+ 0xA8, 0x9A, 0x78, 0x56, |
+ 0x34, 0x12, |
+ // private flags (entropy) |
+ 0x01, |
+ |
+ // frame type (ack frame) |
+ // (has nacks, not truncated, 6 byte largest observed, 1 byte delta) |
+ 0x6C, |
+ // entropy hash of all received packets. |
+ 0xBA, |
+ // largest observed packet sequence number |
+ 0xBF, 0x9A, 0x78, 0x56, |
+ 0x34, 0x12, |
+ // Zero delta time. |
+ 0x0, 0x0, |
+ // Number of timestamps. |
+ 0x00, |
+ // num missing packets |
+ 0x01, |
+ // missing packet delta |
+ 0x01, |
+ // 0 more missing packets in range. |
+ 0x00, |
+ // Number of revived packets. |
+ 0x00, |
+ }; |
+ |
+ QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); |
+ EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
+ |
+ EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
+ ASSERT_TRUE(visitor_.header_.get()); |
+ EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); |
+ |
+ EXPECT_EQ(0u, visitor_.stream_frames_.size()); |
+ ASSERT_EQ(1u, visitor_.ack_frames_.size()); |
+ const QuicAckFrame& frame = *visitor_.ack_frames_[0]; |
+ EXPECT_EQ(0xBA, frame.entropy_hash); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed); |
+ ASSERT_EQ(1u, frame.missing_packets.size()); |
+ SequenceNumberSet::const_iterator missing_iter = |
+ frame.missing_packets.begin(); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter); |
+ |
+ const size_t kReceivedEntropyOffset = kQuicFrameTypeSize; |
+ const size_t kLargestObservedOffset = kReceivedEntropyOffset + |
+ kQuicEntropyHashSize; |
+ const size_t kMissingDeltaTimeOffset = kLargestObservedOffset + |
+ PACKET_6BYTE_SEQUENCE_NUMBER; |
+ const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset + |
+ kQuicDeltaTimeLargestObservedSize; |
+ const size_t kNumMissingPacketOffset = kNumTimestampsOffset + |
+ kQuicNumTimestampsSize; |
+ const size_t kMissingPacketsOffset = kNumMissingPacketOffset + |
+ kNumberOfNackRangesSize; |
+ const size_t kMissingPacketsRange = kMissingPacketsOffset + |
+ PACKET_1BYTE_SEQUENCE_NUMBER; |
+ const size_t kRevivedPacketsLength = kMissingPacketsRange + |
+ PACKET_1BYTE_SEQUENCE_NUMBER; |
+ // Now test framing boundaries. |
+ const size_t ack_frame_size = kRevivedPacketsLength + |
+ PACKET_1BYTE_SEQUENCE_NUMBER; |
+ for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) { |
+ string expected_error; |
+ if (i < kLargestObservedOffset) { |
+ expected_error = "Unable to read entropy hash for received packets."; |
+ } else if (i < kMissingDeltaTimeOffset) { |
+ expected_error = "Unable to read largest observed."; |
+ } else if (i < kNumTimestampsOffset) { |
+ expected_error = "Unable to read delta time largest observed."; |
+ } else if (i < kNumMissingPacketOffset) { |
+ expected_error = "Unable to read num received packets."; |
+ } else if (i < kMissingPacketsOffset) { |
+ expected_error = "Unable to read num missing packet ranges."; |
+ } else if (i < kMissingPacketsRange) { |
+ expected_error = "Unable to read missing sequence number delta."; |
+ } else if (i < kRevivedPacketsLength) { |
+ expected_error = "Unable to read missing sequence number range."; |
+ } else { |
+ expected_error = "Unable to read num revived packets."; |
+ } |
+ CheckProcessingFails( |
+ packet, |
+ i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, |
+ PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), |
+ expected_error, QUIC_INVALID_ACK_DATA); |
+ } |
+} |
+ |
+TEST_P(QuicFramerTest, AckFrameRevivedPackets) { |
+ if (version_ <= QUIC_VERSION_22) { |
+ return; |
+ } |
unsigned char packet[] = { |
// public flags (8 byte connection_id) |
0x3C, |
@@ -1705,6 +2143,8 @@ TEST_P(QuicFramerTest, AckFrame) { |
0x34, 0x12, |
// Zero delta time. |
0x0, 0x0, |
+ // num received packets. |
+ 0x00, |
// num missing packets |
0x01, |
// missing packet delta |
@@ -1712,6 +2152,11 @@ TEST_P(QuicFramerTest, AckFrame) { |
// 0 more missing packets in range. |
0x00, |
// Number of revived packets. |
+ 0x01, |
+ // Revived packet sequence number. |
+ 0xBE, 0x9A, 0x78, 0x56, |
+ 0x34, 0x12, |
+ // Number of revived packets. |
0x00, |
}; |
@@ -1737,33 +2182,43 @@ TEST_P(QuicFramerTest, AckFrame) { |
kQuicEntropyHashSize; |
const size_t kMissingDeltaTimeOffset = kLargestObservedOffset + |
PACKET_6BYTE_SEQUENCE_NUMBER; |
- const size_t kNumMissingPacketOffset = kMissingDeltaTimeOffset + |
+ const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset + |
kQuicDeltaTimeLargestObservedSize; |
+ const size_t kNumMissingPacketOffset = kNumTimestampsOffset + |
+ kQuicNumTimestampsSize; |
const size_t kMissingPacketsOffset = kNumMissingPacketOffset + |
kNumberOfNackRangesSize; |
const size_t kMissingPacketsRange = kMissingPacketsOffset + |
PACKET_1BYTE_SEQUENCE_NUMBER; |
const size_t kRevivedPacketsLength = kMissingPacketsRange + |
PACKET_1BYTE_SEQUENCE_NUMBER; |
- // Now test framing boundaries |
- const size_t ack_frame_size = kRevivedPacketsLength + |
+ const size_t kRevivedPacketSequenceNumberLength = kRevivedPacketsLength + |
PACKET_1BYTE_SEQUENCE_NUMBER; |
+ // Now test framing boundaries. |
+ const size_t ack_frame_size = kRevivedPacketSequenceNumberLength + |
+ PACKET_6BYTE_SEQUENCE_NUMBER; |
for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) { |
string expected_error; |
- if (i < kLargestObservedOffset) { |
+ if (i < kReceivedEntropyOffset) { |
+ expected_error = "Unable to read least unacked delta."; |
+ } else if (i < kLargestObservedOffset) { |
expected_error = "Unable to read entropy hash for received packets."; |
} else if (i < kMissingDeltaTimeOffset) { |
expected_error = "Unable to read largest observed."; |
- } else if (i < kNumMissingPacketOffset) { |
+ } else if (i < kNumTimestampsOffset) { |
expected_error = "Unable to read delta time largest observed."; |
+ } else if (i < kNumMissingPacketOffset) { |
+ expected_error = "Unable to read num received packets."; |
} else if (i < kMissingPacketsOffset) { |
expected_error = "Unable to read num missing packet ranges."; |
} else if (i < kMissingPacketsRange) { |
expected_error = "Unable to read missing sequence number delta."; |
} else if (i < kRevivedPacketsLength) { |
expected_error = "Unable to read missing sequence number range."; |
- } else { |
+ } else if (i < kRevivedPacketSequenceNumberLength) { |
expected_error = "Unable to read num revived packets."; |
+ } else { |
+ expected_error = "Unable to read revived packet."; |
} |
CheckProcessingFails( |
packet, |
@@ -1773,7 +2228,10 @@ TEST_P(QuicFramerTest, AckFrame) { |
} |
} |
-TEST_P(QuicFramerTest, AckFrameRevivedPackets) { |
+TEST_P(QuicFramerTest, AckFrameRevivedPacketsv22) { |
+ if (version_ > QUIC_VERSION_22) { |
+ return; |
+ } |
unsigned char packet[] = { |
// public flags (8 byte connection_id) |
0x3C, |
@@ -1807,6 +2265,8 @@ TEST_P(QuicFramerTest, AckFrameRevivedPackets) { |
// Revived packet sequence number. |
0xBE, 0x9A, 0x78, 0x56, |
0x34, 0x12, |
+ // Number of revived packets. |
+ 0x00, |
}; |
QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); |
@@ -1841,7 +2301,7 @@ TEST_P(QuicFramerTest, AckFrameRevivedPackets) { |
PACKET_1BYTE_SEQUENCE_NUMBER; |
const size_t kRevivedPacketSequenceNumberLength = kRevivedPacketsLength + |
PACKET_1BYTE_SEQUENCE_NUMBER; |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
const size_t ack_frame_size = kRevivedPacketSequenceNumberLength + |
PACKET_6BYTE_SEQUENCE_NUMBER; |
for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) { |
@@ -1873,7 +2333,63 @@ TEST_P(QuicFramerTest, AckFrameRevivedPackets) { |
} |
} |
+TEST_P(QuicFramerTest, AckFrameNoNacksv22) { |
+ if (version_ > QUIC_VERSION_22) { |
+ return; |
+ } |
+ unsigned char packet[] = { |
+ // public flags (8 byte connection_id) |
+ 0x3C, |
+ // connection_id |
+ 0x10, 0x32, 0x54, 0x76, |
+ 0x98, 0xBA, 0xDC, 0xFE, |
+ // packet sequence number |
+ 0xA8, 0x9A, 0x78, 0x56, |
+ 0x34, 0x12, |
+ // private flags (entropy) |
+ 0x01, |
+ |
+ // frame type (ack frame) |
+ // (no nacks, not truncated, 6 byte largest observed, 1 byte delta) |
+ 0x4C, |
+ // entropy hash of all received packets. |
+ 0xBA, |
+ // largest observed packet sequence number |
+ 0xBF, 0x9A, 0x78, 0x56, |
+ 0x34, 0x12, |
+ // Zero delta time. |
+ 0x0, 0x0, |
+ }; |
+ |
+ QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); |
+ EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
+ |
+ EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
+ ASSERT_TRUE(visitor_.header_.get()); |
+ EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); |
+ |
+ EXPECT_EQ(0u, visitor_.stream_frames_.size()); |
+ ASSERT_EQ(1u, visitor_.ack_frames_.size()); |
+ QuicAckFrame* frame = visitor_.ack_frames_[0]; |
+ EXPECT_EQ(0xBA, frame->entropy_hash); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame->largest_observed); |
+ ASSERT_EQ(0u, frame->missing_packets.size()); |
+ |
+ // Verify that the packet re-serializes identically. |
+ QuicFrames frames; |
+ frames.push_back(QuicFrame(frame)); |
+ scoped_ptr<QuicPacket> data(BuildDataPacket(*visitor_.header_, frames)); |
+ ASSERT_TRUE(data != NULL); |
+ |
+ test::CompareCharArraysWithHexError("constructed packet", |
+ data->data(), data->length(), |
+ AsChars(packet), arraysize(packet)); |
+} |
+ |
TEST_P(QuicFramerTest, AckFrameNoNacks) { |
+ if (version_ <= QUIC_VERSION_22) { |
+ return; |
+ } |
unsigned char packet[] = { |
// public flags (8 byte connection_id) |
0x3C, |
@@ -1896,6 +2412,8 @@ TEST_P(QuicFramerTest, AckFrameNoNacks) { |
0x34, 0x12, |
// Zero delta time. |
0x0, 0x0, |
+ // Number of received packets. |
+ 0x00, |
}; |
QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); |
@@ -1923,7 +2441,83 @@ TEST_P(QuicFramerTest, AckFrameNoNacks) { |
AsChars(packet), arraysize(packet)); |
} |
+TEST_P(QuicFramerTest, AckFrame500Nacksv22) { |
+ if (version_ > QUIC_VERSION_22) { |
+ return; |
+ } |
+ unsigned char packet[] = { |
+ // public flags (8 byte connection_id) |
+ 0x3C, |
+ // connection_id |
+ 0x10, 0x32, 0x54, 0x76, |
+ 0x98, 0xBA, 0xDC, 0xFE, |
+ // packet sequence number |
+ 0xA8, 0x9A, 0x78, 0x56, |
+ 0x34, 0x12, |
+ // private flags (entropy) |
+ 0x01, |
+ |
+ // frame type (ack frame) |
+ // (has nacks, not truncated, 6 byte largest observed, 1 byte delta) |
+ 0x6C, |
+ // entropy hash of all received packets. |
+ 0xBA, |
+ // largest observed packet sequence number |
+ 0xBF, 0x9A, 0x78, 0x56, |
+ 0x34, 0x12, |
+ // Zero delta time. |
+ 0x0, 0x0, |
+ // num missing packet ranges |
+ 0x02, |
+ // missing packet delta |
+ 0x01, |
+ // 243 more missing packets in range. |
+ // The ranges are listed in this order so the re-constructed packet matches. |
+ 0xF3, |
+ // No gap between ranges |
+ 0x00, |
+ // 255 more missing packets in range. |
+ 0xFF, |
+ // No revived packets. |
+ 0x00, |
+ }; |
+ |
+ QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); |
+ EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
+ |
+ EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
+ ASSERT_TRUE(visitor_.header_.get()); |
+ EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion)); |
+ |
+ EXPECT_EQ(0u, visitor_.stream_frames_.size()); |
+ ASSERT_EQ(1u, visitor_.ack_frames_.size()); |
+ QuicAckFrame* frame = visitor_.ack_frames_[0]; |
+ EXPECT_EQ(0xBA, frame->entropy_hash); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame->largest_observed); |
+ EXPECT_EQ(0u, frame->revived_packets.size()); |
+ ASSERT_EQ(500u, frame->missing_packets.size()); |
+ SequenceNumberSet::const_iterator first_missing_iter = |
+ frame->missing_packets.begin(); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789ABE) - 499, *first_missing_iter); |
+ SequenceNumberSet::const_reverse_iterator last_missing_iter = |
+ frame->missing_packets.rbegin(); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *last_missing_iter); |
+ |
+ // Verify that the packet re-serializes identically. |
+ QuicFrames frames; |
+ frames.push_back(QuicFrame(frame)); |
+ scoped_ptr<QuicPacket> data(BuildDataPacket(*visitor_.header_, frames)); |
+ ASSERT_TRUE(data != NULL); |
+ |
+ test::CompareCharArraysWithHexError("constructed packet", |
+ data->data(), data->length(), |
+ AsChars(packet), arraysize(packet)); |
+} |
+ |
TEST_P(QuicFramerTest, AckFrame500Nacks) { |
+ if (version_ <= QUIC_VERSION_22) { |
+ return; |
+ } |
unsigned char packet[] = { |
// public flags (8 byte connection_id) |
0x3C, |
@@ -1946,6 +2540,8 @@ TEST_P(QuicFramerTest, AckFrame500Nacks) { |
0x34, 0x12, |
// Zero delta time. |
0x0, 0x0, |
+ // No received packets. |
+ 0x00, |
// num missing packet ranges |
0x02, |
// missing packet delta |
@@ -2028,7 +2624,7 @@ TEST_P(QuicFramerTest, CongestionFeedbackFrameTCP) { |
ASSERT_EQ(kTCP, frame.type); |
EXPECT_EQ(0x4030u, frame.tcp.receive_window); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
for (size_t i = kQuicFrameTypeSize; i < 4; ++i) { |
string expected_error; |
if (i < 2) { |
@@ -2170,7 +2766,7 @@ TEST_P(QuicFramerTest, RstStreamFrameQuic) { |
EXPECT_EQ(GG_UINT64_C(0x0807060504030201), |
visitor_.rst_stream_frame_.byte_offset); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
for (size_t i = kQuicFrameTypeSize; |
i < QuicFramer::GetMinRstStreamFrameSize(); ++i) { |
string expected_error; |
@@ -2234,7 +2830,7 @@ TEST_P(QuicFramerTest, ConnectionCloseFrame) { |
ASSERT_EQ(0u, visitor_.ack_frames_.size()); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
for (size_t i = kQuicFrameTypeSize; |
i < QuicFramer::GetMinConnectionCloseFrameSize(); ++i) { |
string expected_error; |
@@ -2292,7 +2888,7 @@ TEST_P(QuicFramerTest, GoAwayFrame) { |
EXPECT_EQ("because I can", visitor_.goaway_frame_.reason_phrase); |
const size_t reason_size = arraysize("because I can") - 1; |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
for (size_t i = kQuicFrameTypeSize; |
i < QuicFramer::GetMinGoAwayFrameSize() + reason_size; ++i) { |
string expected_error; |
@@ -2347,7 +2943,7 @@ TEST_P(QuicFramerTest, WindowUpdateFrame) { |
EXPECT_EQ(GG_UINT64_C(0x0c0b0a0908070605), |
visitor_.window_update_frame_.byte_offset); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
for (size_t i = kQuicFrameTypeSize; |
i < QuicFramer::GetWindowUpdateFrameSize(); ++i) { |
string expected_error; |
@@ -2394,7 +2990,7 @@ TEST_P(QuicFramerTest, BlockedFrame) { |
EXPECT_EQ(GG_UINT64_C(0x01020304), |
visitor_.blocked_frame_.stream_id); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
for (size_t i = kQuicFrameTypeSize; i < QuicFramer::GetBlockedFrameSize(); |
++i) { |
string expected_error = "Unable to read stream_id."; |
@@ -2481,7 +3077,7 @@ TEST_P(QuicFramerTest, PublicResetPacket) { |
EXPECT_TRUE( |
visitor_.public_reset_packet_->client_address.address().empty()); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
for (size_t i = 0; i < arraysize(packet); ++i) { |
string expected_error; |
DVLOG(1) << "iteration: " << i; |
@@ -2587,7 +3183,7 @@ TEST_P(QuicFramerTest, PublicResetPacketWithClientAddress) { |
client_address.address())); |
EXPECT_EQ(443, visitor_.public_reset_packet_->client_address.port()); |
- // Now test framing boundaries |
+ // Now test framing boundaries. |
for (size_t i = 0; i < arraysize(packet); ++i) { |
string expected_error; |
DVLOG(1) << "iteration: " << i; |
@@ -3042,10 +3638,73 @@ TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) { |
'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(), |
}; |
- QuicVersionVector versions; |
- versions.push_back(GetParam()); |
- scoped_ptr<QuicEncryptedPacket> data( |
- framer_.BuildVersionNegotiationPacket(header, versions)); |
+ QuicVersionVector versions; |
+ versions.push_back(GetParam()); |
+ scoped_ptr<QuicEncryptedPacket> data( |
+ framer_.BuildVersionNegotiationPacket(header, versions)); |
+ |
+ test::CompareCharArraysWithHexError("constructed packet", |
+ data->data(), data->length(), |
+ AsChars(packet), arraysize(packet)); |
+} |
+ |
+TEST_P(QuicFramerTest, BuildAckFramePacketv22) { |
+ if (version_ > QUIC_VERSION_22) { |
+ return; |
+ } |
+ QuicPacketHeader header; |
+ header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); |
+ header.public_header.reset_flag = false; |
+ header.public_header.version_flag = false; |
+ header.fec_flag = false; |
+ header.entropy_flag = true; |
+ header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8); |
+ header.fec_group = 0; |
+ |
+ QuicAckFrame ack_frame; |
+ ack_frame.entropy_hash = 0x43; |
+ ack_frame.largest_observed = GG_UINT64_C(0x770123456789ABF); |
+ ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero(); |
+ ack_frame.missing_packets.insert( |
+ GG_UINT64_C(0x770123456789ABE)); |
+ |
+ QuicFrames frames; |
+ frames.push_back(QuicFrame(&ack_frame)); |
+ |
+ unsigned char packet[] = { |
+ // public flags (8 byte connection_id) |
+ 0x3C, |
+ // connection_id |
+ 0x10, 0x32, 0x54, 0x76, |
+ 0x98, 0xBA, 0xDC, 0xFE, |
+ // packet sequence number |
+ 0xA8, 0x9A, 0x78, 0x56, |
+ 0x34, 0x12, |
+ // private flags (entropy) |
+ 0x01, |
+ |
+ // frame type (ack frame) |
+ // (has nacks, not truncated, 6 byte largest observed, 1 byte delta) |
+ 0x6C, |
+ // entropy hash of all received packets. |
+ 0x43, |
+ // largest observed packet sequence number |
+ 0xBF, 0x9A, 0x78, 0x56, |
+ 0x34, 0x12, |
+ // Zero delta time. |
+ 0x0, 0x0, |
+ // num missing packet ranges |
+ 0x01, |
+ // missing packet delta |
+ 0x01, |
+ // 0 more missing packets in range. |
+ 0x00, |
+ // 0 revived packets. |
+ 0x00, |
+ }; |
+ |
+ scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
+ ASSERT_TRUE(data != NULL); |
test::CompareCharArraysWithHexError("constructed packet", |
data->data(), data->length(), |
@@ -3053,6 +3712,9 @@ TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) { |
} |
TEST_P(QuicFramerTest, BuildAckFramePacket) { |
+ if (version_ <= QUIC_VERSION_22) { |
+ return; |
+ } |
QuicPacketHeader header; |
header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); |
header.public_header.reset_flag = false; |
@@ -3094,6 +3756,8 @@ TEST_P(QuicFramerTest, BuildAckFramePacket) { |
0x34, 0x12, |
// Zero delta time. |
0x0, 0x0, |
+ // num received packets. |
+ 0x00, |
// num missing packet ranges |
0x01, |
// missing packet delta |
@@ -3114,7 +3778,126 @@ TEST_P(QuicFramerTest, BuildAckFramePacket) { |
// TODO(jri): Add test for tuncated packets in which the original ack frame had |
// revived packets. (In both the large and small packet cases below). |
+ |
+TEST_P(QuicFramerTest, BuildTruncatedAckFrameLargePacketv22) { |
+ if (version_ > QUIC_VERSION_22) { |
+ return; |
+ } |
+ QuicPacketHeader header; |
+ header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); |
+ header.public_header.reset_flag = false; |
+ header.public_header.version_flag = false; |
+ header.fec_flag = false; |
+ header.entropy_flag = true; |
+ header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8); |
+ header.fec_group = 0; |
+ |
+ QuicAckFrame ack_frame; |
+ // This entropy hash is different from what shows up in the packet below, |
+ // since entropy is recomputed by the framer on ack truncation (by |
+ // TestEntropyCalculator for this test.) |
+ ack_frame.entropy_hash = 0x43; |
+ ack_frame.largest_observed = 2 * 300; |
+ ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero(); |
+ for (size_t i = 1; i < 2 * 300; i += 2) { |
+ ack_frame.missing_packets.insert(i); |
+ } |
+ |
+ QuicFrames frames; |
+ frames.push_back(QuicFrame(&ack_frame)); |
+ |
+ unsigned char packet[] = { |
+ // public flags (8 byte connection_id) |
+ 0x3C, |
+ // connection_id |
+ 0x10, 0x32, 0x54, 0x76, |
+ 0x98, 0xBA, 0xDC, 0xFE, |
+ // packet sequence number |
+ 0xA8, 0x9A, 0x78, 0x56, |
+ 0x34, 0x12, |
+ // private flags (entropy) |
+ 0x01, |
+ |
+ // frame type (ack frame) |
+ // (has nacks, is truncated, 2 byte largest observed, 1 byte delta) |
+ 0x74, |
+ // entropy hash of all received packets, set to 1 by TestEntropyCalculator |
+ // since ack is truncated. |
+ 0x01, |
+ // 2-byte largest observed packet sequence number. |
+ // Expected to be 510 (0x1FE), since only 255 nack ranges can fit. |
+ 0xFE, 0x01, |
+ // Zero delta time. |
+ 0x0, 0x0, |
+ // num missing packet ranges (limited to 255 by size of this field). |
+ 0xFF, |
+ // {missing packet delta, further missing packets in range} |
+ // 6 nack ranges x 42 + 3 nack ranges |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ |
+ // 0 revived packets. |
+ 0x00, |
+ }; |
+ |
+ scoped_ptr<QuicPacket> data( |
+ framer_.BuildDataPacket(header, frames, kMaxPacketSize).packet); |
+ ASSERT_TRUE(data != NULL); |
+ |
+ test::CompareCharArraysWithHexError("constructed packet", |
+ data->data(), data->length(), |
+ AsChars(packet), arraysize(packet)); |
+} |
+ |
TEST_P(QuicFramerTest, BuildTruncatedAckFrameLargePacket) { |
+ if (version_ <= QUIC_VERSION_22) { |
+ return; |
+ } |
QuicPacketHeader header; |
header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); |
header.public_header.reset_flag = false; |
@@ -3227,7 +4010,79 @@ TEST_P(QuicFramerTest, BuildTruncatedAckFrameLargePacket) { |
} |
+TEST_P(QuicFramerTest, BuildTruncatedAckFrameSmallPacketv22) { |
+ if (version_ > QUIC_VERSION_22) { |
+ return; |
+ } |
+ QuicPacketHeader header; |
+ header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); |
+ header.public_header.reset_flag = false; |
+ header.public_header.version_flag = false; |
+ header.fec_flag = false; |
+ header.entropy_flag = true; |
+ header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8); |
+ header.fec_group = 0; |
+ |
+ QuicAckFrame ack_frame; |
+ // This entropy hash is different from what shows up in the packet below, |
+ // since entropy is recomputed by the framer on ack truncation (by |
+ // TestEntropyCalculator for this test.) |
+ ack_frame.entropy_hash = 0x43; |
+ ack_frame.largest_observed = 2 * 300; |
+ ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero(); |
+ for (size_t i = 1; i < 2 * 300; i += 2) { |
+ ack_frame.missing_packets.insert(i); |
+ } |
+ |
+ QuicFrames frames; |
+ frames.push_back(QuicFrame(&ack_frame)); |
+ |
+ unsigned char packet[] = { |
+ // public flags (8 byte connection_id) |
+ 0x3C, |
+ // connection_id |
+ 0x10, 0x32, 0x54, 0x76, |
+ 0x98, 0xBA, 0xDC, 0xFE, |
+ // packet sequence number |
+ 0xA8, 0x9A, 0x78, 0x56, |
+ 0x34, 0x12, |
+ // private flags (entropy) |
+ 0x01, |
+ |
+ // frame type (ack frame) |
+ // (has nacks, is truncated, 2 byte largest observed, 1 byte delta) |
+ 0x74, |
+ // entropy hash of all received packets, set to 1 by TestEntropyCalculator |
+ // since ack is truncated. |
+ 0x01, |
+ // 2-byte largest observed packet sequence number. |
+ // Expected to be 12 (0x0C), since only 6 nack ranges can fit. |
+ 0x0C, 0x00, |
+ // Zero delta time. |
+ 0x0, 0x0, |
+ // num missing packet ranges (limited to 6 by packet size of 37). |
+ 0x06, |
+ // {missing packet delta, further missing packets in range} |
+ // 6 nack ranges |
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, |
+ // 0 revived packets. |
+ 0x00, |
+ }; |
+ |
+ scoped_ptr<QuicPacket> data( |
+ framer_.BuildDataPacket(header, frames, 37u).packet); |
+ ASSERT_TRUE(data != NULL); |
+ // Expect 1 byte unused since at least 2 bytes are needed to fit more nacks. |
+ EXPECT_EQ(36u, data->length()); |
+ test::CompareCharArraysWithHexError("constructed packet", |
+ data->data(), data->length(), |
+ AsChars(packet), arraysize(packet)); |
+} |
+ |
TEST_P(QuicFramerTest, BuildTruncatedAckFrameSmallPacket) { |
+ if (version_ <= QUIC_VERSION_22) { |
+ return; |
+ } |
QuicPacketHeader header; |
header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); |
header.public_header.reset_flag = false; |
@@ -3396,7 +4251,7 @@ TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketInvalidFeedback) { |
QuicCongestionFeedbackFrame congestion_feedback_frame; |
congestion_feedback_frame.type = |
- static_cast<CongestionFeedbackType>(kTimestamp + 1); |
+ static_cast<CongestionFeedbackType>(kTCP + 1); |
QuicFrames frames; |
frames.push_back(QuicFrame(&congestion_feedback_frame)); |
@@ -3953,7 +4808,54 @@ TEST_P(QuicFramerTest, AckTruncationLargePacket) { |
EXPECT_EQ(509u, *last_missing_iter); |
} |
+TEST_P(QuicFramerTest, AckTruncationSmallPacketv22) { |
+ if (version_ > QUIC_VERSION_22) { |
+ return; |
+ } |
+ QuicPacketHeader header; |
+ header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); |
+ header.public_header.reset_flag = false; |
+ header.public_header.version_flag = false; |
+ header.fec_flag = false; |
+ header.entropy_flag = false; |
+ header.packet_sequence_number = GG_UINT64_C(0x123456789ABC); |
+ header.fec_group = 0; |
+ |
+ // Create a packet with just the ack. |
+ QuicAckFrame ack_frame = MakeAckFrameWithNackRanges(300, 0u); |
+ QuicFrame frame; |
+ frame.type = ACK_FRAME; |
+ frame.ack_frame = &ack_frame; |
+ QuicFrames frames; |
+ frames.push_back(frame); |
+ |
+ // Build an ack packet with truncation due to limit in number of nack ranges. |
+ scoped_ptr<QuicPacket> raw_ack_packet( |
+ framer_.BuildDataPacket(header, frames, 500).packet); |
+ ASSERT_TRUE(raw_ack_packet != NULL); |
+ scoped_ptr<QuicEncryptedPacket> ack_packet( |
+ framer_.EncryptPacket(ENCRYPTION_NONE, header.packet_sequence_number, |
+ *raw_ack_packet)); |
+ // Now make sure we can turn our ack packet back into an ack frame. |
+ ASSERT_TRUE(framer_.ProcessPacket(*ack_packet)); |
+ ASSERT_EQ(1u, visitor_.ack_frames_.size()); |
+ QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0]; |
+ EXPECT_TRUE(processed_ack_frame.is_truncated); |
+ EXPECT_EQ(476u, processed_ack_frame.largest_observed); |
+ ASSERT_EQ(238u, processed_ack_frame.missing_packets.size()); |
+ SequenceNumberSet::const_iterator missing_iter = |
+ processed_ack_frame.missing_packets.begin(); |
+ EXPECT_EQ(1u, *missing_iter); |
+ SequenceNumberSet::const_reverse_iterator last_missing_iter = |
+ processed_ack_frame.missing_packets.rbegin(); |
+ EXPECT_EQ(475u, *last_missing_iter); |
+} |
+ |
+ |
TEST_P(QuicFramerTest, AckTruncationSmallPacket) { |
+ if (version_ <= QUIC_VERSION_22) { |
+ return; |
+ } |
QuicPacketHeader header; |
header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210); |
header.public_header.reset_flag = false; |