Index: net/quic/quic_framer_test.cc |
diff --git a/net/quic/quic_framer_test.cc b/net/quic/quic_framer_test.cc |
index f9c2de78d659a092e43717d6d8de45e91921370b..870eda0e28e69cfd2273310aefa4713e51480535 100644 |
--- a/net/quic/quic_framer_test.cc |
+++ b/net/quic/quic_framer_test.cc |
@@ -211,13 +211,14 @@ class TestQuicVisitor : public ::net::QuicFramerVisitorInterface { |
STLDeleteElements(&stream_frames_); |
STLDeleteElements(&ack_frames_); |
STLDeleteElements(&congestion_feedback_frames_); |
+ STLDeleteElements(&stop_waiting_frames_); |
STLDeleteElements(&fec_data_); |
} |
virtual void OnError(QuicFramer* f) OVERRIDE { |
DVLOG(1) << "QuicFramer Error: " << QuicUtils::ErrorToString(f->error()) |
<< " (" << f->error() << ")"; |
- error_count_++; |
+ ++error_count_; |
} |
virtual void OnPacket() OVERRIDE {} |
@@ -233,12 +234,12 @@ class TestQuicVisitor : public ::net::QuicFramerVisitorInterface { |
} |
virtual void OnRevivedPacket() OVERRIDE { |
- revived_packets_++; |
+ ++revived_packets_; |
} |
virtual bool OnProtocolVersionMismatch(QuicVersion version) OVERRIDE { |
DVLOG(1) << "QuicFramer Version Mismatch, version: " << version; |
- version_mismatch_++; |
+ ++version_mismatch_; |
return true; |
} |
@@ -254,13 +255,13 @@ class TestQuicVisitor : public ::net::QuicFramerVisitorInterface { |
} |
virtual bool OnPacketHeader(const QuicPacketHeader& header) OVERRIDE { |
- packet_count_++; |
+ ++packet_count_; |
header_.reset(new QuicPacketHeader(header)); |
return accept_packet_; |
} |
virtual bool OnStreamFrame(const QuicStreamFrame& frame) OVERRIDE { |
- frame_count_++; |
+ ++frame_count_; |
stream_frames_.push_back(new QuicStreamFrame(frame)); |
return true; |
} |
@@ -270,26 +271,32 @@ class TestQuicVisitor : public ::net::QuicFramerVisitorInterface { |
} |
virtual bool OnAckFrame(const QuicAckFrame& frame) OVERRIDE { |
- frame_count_++; |
+ ++frame_count_; |
ack_frames_.push_back(new QuicAckFrame(frame)); |
return true; |
} |
virtual bool OnCongestionFeedbackFrame( |
const QuicCongestionFeedbackFrame& frame) OVERRIDE { |
- frame_count_++; |
+ ++frame_count_; |
congestion_feedback_frames_.push_back( |
new QuicCongestionFeedbackFrame(frame)); |
return true; |
} |
+ virtual bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) OVERRIDE { |
+ ++frame_count_; |
+ stop_waiting_frames_.push_back(new QuicStopWaitingFrame(frame)); |
+ return true; |
+ } |
+ |
virtual void OnFecData(const QuicFecData& fec) OVERRIDE { |
- fec_count_++; |
+ ++fec_count_; |
fec_data_.push_back(new QuicFecData(fec)); |
} |
virtual void OnPacketComplete() OVERRIDE { |
- complete_packets_++; |
+ ++complete_packets_; |
} |
virtual bool OnRstStreamFrame(const QuicRstStreamFrame& frame) OVERRIDE { |
@@ -337,6 +344,7 @@ class TestQuicVisitor : public ::net::QuicFramerVisitorInterface { |
vector<QuicStreamFrame*> stream_frames_; |
vector<QuicAckFrame*> ack_frames_; |
vector<QuicCongestionFeedbackFrame*> congestion_feedback_frames_; |
+ vector<QuicStopWaitingFrame*> stop_waiting_frames_; |
vector<QuicFecData*> fec_data_; |
string fec_protected_payload_; |
QuicRstStreamFrame rst_stream_frame_; |
@@ -1760,8 +1768,8 @@ TEST_P(QuicFramerTest, AckFrameV14) { |
} |
} |
-TEST_P(QuicFramerTest, AckFrame) { |
- if (framer_.version() <= QUIC_VERSION_14) { |
+TEST_P(QuicFramerTest, AckFrame15) { |
+ if (framer_.version() != QUIC_VERSION_15) { |
return; |
} |
@@ -1869,8 +1877,207 @@ TEST_P(QuicFramerTest, AckFrame) { |
} |
} |
+TEST_P(QuicFramerTest, AckFrame) { |
+ if (framer_.version() <= QUIC_VERSION_15) { |
+ return; |
+ } |
+ |
+ unsigned char packet[] = { |
+ // public flags (8 byte guid) |
+ 0x3C, |
+ // guid |
+ 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.received_info.entropy_hash); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.received_info.largest_observed); |
+ ASSERT_EQ(1u, frame.received_info.missing_packets.size()); |
+ SequenceNumberSet::const_iterator missing_iter = |
+ frame.received_info.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 + |
+ kNumberOfMissingPacketsSize; |
+ 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_GUID, !kIncludeVersion, |
+ PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), |
+ expected_error, QUIC_INVALID_ACK_DATA); |
+ } |
+} |
+ |
TEST_P(QuicFramerTest, AckFrameRevivedPackets) { |
- if (framer_.version() <= QUIC_VERSION_14) { |
+ if (framer_.version() <= QUIC_VERSION_15) { |
+ return; |
+ } |
+ |
+ unsigned char packet[] = { |
+ // public flags (8 byte guid) |
+ 0x3C, |
+ // guid |
+ 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. |
+ 0x01, |
+ // Revived packet sequence number. |
+ 0xBE, 0x9A, 0x78, 0x56, |
+ 0x34, 0x12, |
+ }; |
+ |
+ 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.received_info.entropy_hash); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.received_info.largest_observed); |
+ ASSERT_EQ(1u, frame.received_info.missing_packets.size()); |
+ SequenceNumberSet::const_iterator missing_iter = |
+ frame.received_info.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 + |
+ kNumberOfMissingPacketsSize; |
+ const size_t kMissingPacketsRange = kMissingPacketsOffset + |
+ PACKET_1BYTE_SEQUENCE_NUMBER; |
+ const size_t kRevivedPacketsLength = kMissingPacketsRange + |
+ PACKET_1BYTE_SEQUENCE_NUMBER; |
+ 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 < 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) { |
+ 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 if (i < kRevivedPacketSequenceNumberLength) { |
+ expected_error = "Unable to read num revived packets."; |
+ } else { |
+ expected_error = "Unable to read revived packet."; |
+ } |
+ CheckProcessingFails( |
+ packet, |
+ i + GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion, |
+ PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), |
+ expected_error, QUIC_INVALID_ACK_DATA); |
+ } |
+} |
+ |
+TEST_P(QuicFramerTest, AckFrameRevivedPackets15) { |
+ if (framer_.version() != QUIC_VERSION_15) { |
return; |
} |
@@ -1985,7 +2192,127 @@ TEST_P(QuicFramerTest, AckFrameRevivedPackets) { |
} |
} |
-TEST_P(QuicFramerTest, AckFrameNoNacks) { |
+TEST_P(QuicFramerTest, AckFrameNoNacks) { |
+ if (framer_.version() <= QUIC_VERSION_15) { |
+ return; |
+ } |
+ unsigned char packet[] = { |
+ // public flags (8 byte guid) |
+ 0x3C, |
+ // guid |
+ 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->received_info.entropy_hash); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), |
+ frame->received_info.largest_observed); |
+ ASSERT_EQ(0u, frame->received_info.missing_packets.size()); |
+ |
+ // Verify that the packet re-serializes identically. |
+ QuicFrames frames; |
+ frames.push_back(QuicFrame(frame)); |
+ scoped_ptr<QuicPacket> data( |
+ framer_.BuildUnsizedDataPacket(*visitor_.header_, frames).packet); |
+ ASSERT_TRUE(data != NULL); |
+ |
+ test::CompareCharArraysWithHexError("constructed packet", |
+ data->data(), data->length(), |
+ AsChars(packet), arraysize(packet)); |
+} |
+ |
+TEST_P(QuicFramerTest, AckFrameNoNacks15) { |
+ if (framer_.version() > QUIC_VERSION_15) { |
+ return; |
+ } |
+ unsigned char packet[] = { |
+ // public flags (8 byte guid) |
+ 0x3C, |
+ // guid |
+ 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 sent packets till least awaiting - 1. |
+ 0xAB, |
+ // least packet sequence number awaiting an ack, delta from sequence number. |
+ 0x08, 0x00, 0x00, 0x00, |
+ 0x00, 0x00, |
+ // 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(0xAB, frame->sent_info.entropy_hash); |
+ EXPECT_EQ(0xBA, frame->received_info.entropy_hash); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), |
+ frame->received_info.largest_observed); |
+ ASSERT_EQ(0u, frame->received_info.missing_packets.size()); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789AA0), frame->sent_info.least_unacked); |
+ |
+ // Verify that the packet re-serializes identically. |
+ QuicFrames frames; |
+ frames.push_back(QuicFrame(frame)); |
+ scoped_ptr<QuicPacket> data( |
+ framer_.BuildUnsizedDataPacket(*visitor_.header_, frames).packet); |
+ ASSERT_TRUE(data != NULL); |
+ |
+ test::CompareCharArraysWithHexError("constructed packet", |
+ data->data(), data->length(), |
+ AsChars(packet), arraysize(packet)); |
+} |
+ |
+TEST_P(QuicFramerTest, AckFrame500Nacks) { |
+ if (framer_.version() <= QUIC_VERSION_15) { |
+ return; |
+ } |
unsigned char packet[] = { |
// public flags (8 byte guid) |
0x3C, |
@@ -1999,13 +2326,8 @@ TEST_P(QuicFramerTest, AckFrameNoNacks) { |
0x01, |
// frame type (ack frame) |
- // (no nacks, not truncated, 6 byte largest observed, 1 byte delta) |
- 0x4C, |
- // entropy hash of sent packets till least awaiting - 1. |
- 0xAB, |
- // least packet sequence number awaiting an ack, delta from sequence number. |
- 0x08, 0x00, 0x00, 0x00, |
- 0x00, 0x00, |
+ // (has nacks, not truncated, 6 byte largest observed, 1 byte delta) |
+ 0x6C, |
// entropy hash of all received packets. |
0xBA, |
// largest observed packet sequence number |
@@ -2013,6 +2335,19 @@ TEST_P(QuicFramerTest, AckFrameNoNacks) { |
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); |
@@ -2025,12 +2360,17 @@ TEST_P(QuicFramerTest, AckFrameNoNacks) { |
EXPECT_EQ(0u, visitor_.stream_frames_.size()); |
ASSERT_EQ(1u, visitor_.ack_frames_.size()); |
QuicAckFrame* frame = visitor_.ack_frames_[0]; |
- EXPECT_EQ(0xAB, frame->sent_info.entropy_hash); |
EXPECT_EQ(0xBA, frame->received_info.entropy_hash); |
EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), |
frame->received_info.largest_observed); |
- ASSERT_EQ(0u, frame->received_info.missing_packets.size()); |
- EXPECT_EQ(GG_UINT64_C(0x0123456789AA0), frame->sent_info.least_unacked); |
+ EXPECT_EQ(0u, frame->received_info.revived_packets.size()); |
+ ASSERT_EQ(500u, frame->received_info.missing_packets.size()); |
+ SequenceNumberSet::const_iterator first_missing_iter = |
+ frame->received_info.missing_packets.begin(); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789ABE) - 499, *first_missing_iter); |
+ SequenceNumberSet::const_reverse_iterator last_missing_iter = |
+ frame->received_info.missing_packets.rbegin(); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *last_missing_iter); |
// Verify that the packet re-serializes identically. |
QuicFrames frames; |
@@ -2044,8 +2384,8 @@ TEST_P(QuicFramerTest, AckFrameNoNacks) { |
AsChars(packet), arraysize(packet)); |
} |
-TEST_P(QuicFramerTest, AckFrame500Nacks) { |
- if (framer_.version() <= QUIC_VERSION_14) { |
+TEST_P(QuicFramerTest, AckFrame500Nacks15) { |
+ if (framer_.version() != QUIC_VERSION_15) { |
return; |
} |
unsigned char packet[] = { |
@@ -2584,6 +2924,63 @@ TEST_P(QuicFramerTest, CongestionFeedbackFrameInvalidFeedback) { |
EXPECT_EQ(QUIC_INVALID_CONGESTION_FEEDBACK_DATA, framer_.error()); |
} |
+TEST_P(QuicFramerTest, StopWaitingFrame) { |
+ if (framer_.version() <= QUIC_VERSION_15) { |
+ return; |
+ } |
+ unsigned char packet[] = { |
+ // public flags (8 byte guid) |
+ 0x3C, |
+ // guid |
+ 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) |
+ 0x06, |
+ // entropy hash of sent packets till least awaiting - 1. |
+ 0xAB, |
+ // least packet sequence number awaiting an ack, delta from sequence number. |
+ 0x08, 0x00, 0x00, 0x00, |
+ 0x00, 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_.stop_waiting_frames_.size()); |
+ const QuicStopWaitingFrame& frame = *visitor_.stop_waiting_frames_[0]; |
+ EXPECT_EQ(0xAB, frame.entropy_hash); |
+ EXPECT_EQ(GG_UINT64_C(0x0123456789AA0), frame.least_unacked); |
+ |
+ const size_t kSentEntropyOffset = kQuicFrameTypeSize; |
+ const size_t kLeastUnackedOffset = kSentEntropyOffset + kQuicEntropyHashSize; |
+ const size_t frame_size = 7; |
+ for (size_t i = kQuicFrameTypeSize; i < frame_size; ++i) { |
+ string expected_error; |
+ if (i < kLeastUnackedOffset) { |
+ expected_error = "Unable to read entropy hash for sent packets."; |
+ } else { |
+ expected_error = "Unable to read least unacked delta."; |
+ } |
+ CheckProcessingFails( |
+ packet, |
+ i + GetPacketHeaderSize(PACKET_8BYTE_GUID, !kIncludeVersion, |
+ PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), |
+ expected_error, QUIC_INVALID_STOP_WAITING_DATA); |
+ } |
+} |
+ |
TEST_P(QuicFramerTest, RstStreamFrameVersion13) { |
if (version_ > QUIC_VERSION_13) { |
return; |
@@ -3571,7 +3968,71 @@ TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) { |
} |
TEST_P(QuicFramerTest, BuildAckFramePacket) { |
- if (version_ <= QUIC_VERSION_14) { |
+ if (version_ <= QUIC_VERSION_15) { |
+ return; |
+ } |
+ QuicPacketHeader header; |
+ header.public_header.guid = 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.received_info.entropy_hash = 0x43; |
+ ack_frame.received_info.largest_observed = GG_UINT64_C(0x770123456789ABF); |
+ ack_frame.received_info.delta_time_largest_observed = QuicTime::Delta::Zero(); |
+ ack_frame.received_info.missing_packets.insert( |
+ GG_UINT64_C(0x770123456789ABE)); |
+ |
+ QuicFrames frames; |
+ frames.push_back(QuicFrame(&ack_frame)); |
+ |
+ unsigned char packet[] = { |
+ // public flags (8 byte guid) |
+ 0x3C, |
+ // guid |
+ 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( |
+ framer_.BuildUnsizedDataPacket(header, frames).packet); |
+ ASSERT_TRUE(data != NULL); |
+ |
+ test::CompareCharArraysWithHexError("constructed packet", |
+ data->data(), data->length(), |
+ AsChars(packet), arraysize(packet)); |
+} |
+ |
+TEST_P(QuicFramerTest, BuildAckFramePacket15) { |
+ if (version_ != QUIC_VERSION_15) { |
return; |
} |
QuicPacketHeader header; |
@@ -3958,6 +4419,56 @@ TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketInterArrivalV14) { |
AsChars(packet), arraysize(packet)); |
} |
+TEST_P(QuicFramerTest, BuildStopWaitingPacket) { |
+ if (version_ <= QUIC_VERSION_15) { |
+ return; |
+ } |
+ QuicPacketHeader header; |
+ header.public_header.guid = 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; |
+ |
+ QuicStopWaitingFrame stop_waiting_frame; |
+ stop_waiting_frame.entropy_hash = 0x14; |
+ stop_waiting_frame.least_unacked = GG_UINT64_C(0x770123456789AA0); |
+ |
+ QuicFrames frames; |
+ frames.push_back(QuicFrame(&stop_waiting_frame)); |
+ |
+ unsigned char packet[] = { |
+ // public flags (8 byte guid) |
+ 0x3C, |
+ // guid |
+ 0x10, 0x32, 0x54, 0x76, |
+ 0x98, 0xBA, 0xDC, 0xFE, |
+ // packet sequence number |
+ 0xA8, 0x9A, 0x78, 0x56, |
+ 0x34, 0x12, |
+ // private flags (entropy) |
+ 0x01, |
+ |
+ // frame type (stop waiting frame) |
+ 0x06, |
+ // entropy hash of sent packets till least awaiting - 1. |
+ 0x14, |
+ // least packet sequence number awaiting an ack, delta from sequence number. |
+ 0x08, 0x00, 0x00, 0x00, |
+ 0x00, 0x00, |
+ }; |
+ |
+ scoped_ptr<QuicPacket> data( |
+ framer_.BuildUnsizedDataPacket(header, frames).packet); |
+ ASSERT_TRUE(data != NULL); |
+ |
+ test::CompareCharArraysWithHexError("constructed packet", |
+ data->data(), data->length(), |
+ AsChars(packet), arraysize(packet)); |
+} |
+ |
TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketFixRate) { |
QuicPacketHeader header; |
header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); |
@@ -4025,7 +4536,7 @@ TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketInvalidFeedback) { |
scoped_ptr<QuicPacket> data; |
EXPECT_DFATAL( |
data.reset(framer_.BuildUnsizedDataPacket(header, frames).packet), |
- "AppendQuicCongestionFeedbackFrame failed"); |
+ "AppendCongestionFeedbackFrame failed"); |
ASSERT_TRUE(data == NULL); |
} |
@@ -4571,6 +5082,58 @@ TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) { |
} |
TEST_P(QuicFramerTest, Truncation) { |
+ if (framer_.version() <= QUIC_VERSION_15) { |
+ return; |
+ } |
+ QuicPacketHeader header; |
+ header.public_header.guid = 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; |
+ |
+ QuicAckFrame ack_frame; |
+ ack_frame.received_info.largest_observed = 601; |
+ for (uint64 i = 1; i < ack_frame.received_info.largest_observed; i += 2) { |
+ ack_frame.received_info.missing_packets.insert(i); |
+ } |
+ |
+ // Create a packet with just the ack |
+ QuicFrame frame; |
+ frame.type = ACK_FRAME; |
+ frame.ack_frame = &ack_frame; |
+ QuicFrames frames; |
+ frames.push_back(frame); |
+ |
+ scoped_ptr<QuicPacket> raw_ack_packet( |
+ framer_.BuildUnsizedDataPacket(header, frames).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()); |
+ const QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0]; |
+ EXPECT_TRUE(processed_ack_frame.received_info.is_truncated); |
+ EXPECT_EQ(510u, processed_ack_frame.received_info.largest_observed); |
+ ASSERT_EQ(255u, processed_ack_frame.received_info.missing_packets.size()); |
+ SequenceNumberSet::const_iterator missing_iter = |
+ processed_ack_frame.received_info.missing_packets.begin(); |
+ EXPECT_EQ(1u, *missing_iter); |
+ SequenceNumberSet::const_reverse_iterator last_missing_iter = |
+ processed_ack_frame.received_info.missing_packets.rbegin(); |
+ EXPECT_EQ(509u, *last_missing_iter); |
+} |
+ |
+TEST_P(QuicFramerTest, Truncation15) { |
+ if (framer_.version() > QUIC_VERSION_15) { |
+ return; |
+ } |
QuicPacketHeader header; |
header.public_header.guid = GG_UINT64_C(0xFEDCBA9876543210); |
header.public_header.reset_flag = false; |