| 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;
|
|
|