const size_t kPublicResetPacketMessageTagOffset =
kConnectionIdOffset + PACKET_8BYTE_CONNECTION_ID;
-// TODO(wtc): remove this when we drop support for QUIC_VERSION_13.
-// Index into the nonce proof of the public reset packet.
-// Public resets always have full connection_ids.
-const size_t kPublicResetPacketNonceProofOffset =
- kConnectionIdOffset + PACKET_8BYTE_CONNECTION_ID;
-
-// TODO(wtc): remove this when we drop support for QUIC_VERSION_13.
-// Index into the rejected sequence number of the public reset packet.
-const size_t kPublicResetPacketRejectedSequenceNumberOffset =
- kPublicResetPacketNonceProofOffset + kPublicResetNonceSize;
-
class TestEncrypter : public QuicEncrypter {
public:
virtual ~TestEncrypter() {}
STLDeleteElements(&ack_frames_);
STLDeleteElements(&congestion_feedback_frames_);
STLDeleteElements(&stop_waiting_frames_);
+ STLDeleteElements(&ping_frames_);
STLDeleteElements(&fec_data_);
}
return true;
}
+ virtual void OnDecryptedPacket(EncryptionLevel level) OVERRIDE {}
+
virtual bool OnPacketHeader(const QuicPacketHeader& header) OVERRIDE {
++packet_count_;
header_.reset(new QuicPacketHeader(header));
return true;
}
+ virtual bool OnPingFrame(const QuicPingFrame& frame) OVERRIDE {
+ ++frame_count_;
+ ping_frames_.push_back(new QuicPingFrame(frame));
+ return true;
+ }
+
virtual void OnFecData(const QuicFecData& fec) OVERRIDE {
++fec_count_;
fec_data_.push_back(new QuicFecData(fec));
vector<QuicAckFrame*> ack_frames_;
vector<QuicCongestionFeedbackFrame*> congestion_feedback_frames_;
vector<QuicStopWaitingFrame*> stop_waiting_frames_;
+ vector<QuicPingFrame*> ping_frames_;
vector<QuicFecData*> fec_data_;
string fec_protected_payload_;
QuicRstStreamFrame rst_stream_frame_;
framer_(QuicSupportedVersions(), start_, true) {
version_ = GetParam();
framer_.set_version(version_);
- framer_.SetDecrypter(decrypter_);
+ framer_.SetDecrypter(decrypter_, ENCRYPTION_NONE);
framer_.SetEncrypter(ENCRYPTION_NONE, encrypter_);
framer_.set_visitor(&visitor_);
framer_.set_received_entropy_calculator(&entropy_calculator_);
TEST_P(QuicFramerTest, InvalidPublicFlag) {
unsigned char packet[] = {
- // public flags, unknown flag at bit 6
- 0x40,
+ // public flags: all flags set but the public reset flag and version flag.
+ 0xFC,
// connection_id
0x10, 0x32, 0x54, 0x76,
0x98, 0xBA, 0xDC, 0xFE,
arraysize(packet),
"Illegal public flags value.",
QUIC_INVALID_PACKET_HEADER);
+
+ // Now turn off validation.
+ framer_.set_validate_flags(false);
+ QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
+ EXPECT_TRUE(framer_.ProcessPacket(encrypted));
};
TEST_P(QuicFramerTest, InvalidPublicFlagWithMatchingVersions) {
CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
}
-TEST_P(QuicFramerTest, AckFrameV13) {
- if (framer_.version() != QUIC_VERSION_13) {
- 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 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,
- // num missing packets
- 0x01,
- // missing packet delta
- 0x01,
- // 0 more missing packets in range.
- 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(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(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);
- EXPECT_EQ(GG_UINT64_C(0x0123456789AA0), frame.sent_info.least_unacked);
-
- const size_t kSentEntropyOffset = kQuicFrameTypeSize;
- const size_t kLeastUnackedOffset = kSentEntropyOffset + kQuicEntropyHashSize;
- const size_t kReceivedEntropyOffset = kLeastUnackedOffset +
- PACKET_6BYTE_SEQUENCE_NUMBER;
- 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;
- // Now test framing boundaries
- const size_t ack_frame_size = kMissingPacketsRange +
- PACKET_1BYTE_SEQUENCE_NUMBER;
- for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) {
- string expected_error;
- if (i < kLeastUnackedOffset) {
- expected_error = "Unable to read entropy hash for sent packets.";
- } else 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 {
- expected_error = "Unable to read missing sequence number range.";
- }
- 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, AckFrame15) {
if (framer_.version() != QUIC_VERSION_15) {
return;
AsChars(packet), arraysize(packet));
}
-TEST_P(QuicFramerTest, AckFrame500NacksV13) {
- if (framer_.version() != QUIC_VERSION_13) {
- 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 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,
- // 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,
- };
-
- 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(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);
- 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, CongestionFeedbackFrameTCP) {
- if (framer_.version() == QUIC_VERSION_13) {
- return;
- }
unsigned char packet[] = {
// public flags (8 byte connection_id)
0x3C,
}
}
-TEST_P(QuicFramerTest, CongestionFeedbackFrameTCPV13) {
- if (framer_.version() != QUIC_VERSION_13) {
- return;
- }
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x3C,
- // connection_id
- 0x10, 0x32, 0x54, 0x76,
- 0x98, 0xBA, 0xDC, 0xFE,
- // packet sequence number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // private flags
- 0x00,
-
- // frame type (congestion feedback frame)
- 0x20,
- // congestion feedback type (tcp)
- 0x00,
- // ack_frame.feedback.tcp.accumulated_number_of_lost_packets
- 0x01, 0x02,
- // ack_frame.feedback.tcp.receive_window
- 0x03, 0x04,
- };
-
- 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_.congestion_feedback_frames_.size());
- const QuicCongestionFeedbackFrame& frame =
- *visitor_.congestion_feedback_frames_[0];
- ASSERT_EQ(kTCP, frame.type);
- EXPECT_EQ(0x4030u, frame.tcp.receive_window);
-
- // Now test framing boundaries
- for (size_t i = kQuicFrameTypeSize; i < 6; ++i) {
- string expected_error;
- if (i < 2) {
- expected_error = "Unable to read congestion feedback type.";
- } else if (i < 4) {
- expected_error = "Unable to read accumulated number of lost packets.";
- } else if (i < 6) {
- expected_error = "Unable to read receive window.";
- }
- CheckProcessingFails(
- packet,
- i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
- expected_error, QUIC_INVALID_CONGESTION_FEEDBACK_DATA);
- }
-}
-
TEST_P(QuicFramerTest, CongestionFeedbackFrameInterArrival) {
- if (framer_.version() == QUIC_VERSION_13) {
- return;
- }
unsigned char packet[] = {
// public flags (8 byte connection_id)
0x3C,
}
}
-TEST_P(QuicFramerTest, CongestionFeedbackFrameInterArrivalV13) {
- if (framer_.version() != QUIC_VERSION_13) {
- return;
- }
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x3C,
- // connection_id
- 0x10, 0x32, 0x54, 0x76,
- 0x98, 0xBA, 0xDC, 0xFE,
- // packet sequence number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // private flags
- 0x00,
-
- // frame type (congestion feedback frame)
- 0x20,
- // congestion feedback type (inter arrival)
- 0x01,
- // accumulated_number_of_lost_packets
- 0x02, 0x03,
- // num received packets
- 0x03,
- // lowest sequence number
- 0xBA, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // receive time
- 0x87, 0x96, 0xA5, 0xB4,
- 0xC3, 0xD2, 0xE1, 0x07,
- // sequence delta
- 0x01, 0x00,
- // time delta
- 0x01, 0x00, 0x00, 0x00,
- // sequence delta (skip one packet)
- 0x03, 0x00,
- // time delta
- 0x02, 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_.congestion_feedback_frames_.size());
- const QuicCongestionFeedbackFrame& frame =
- *visitor_.congestion_feedback_frames_[0];
- ASSERT_EQ(kInterArrival, frame.type);
- ASSERT_EQ(3u, frame.inter_arrival.received_packet_times.size());
- TimeMap::const_iterator iter =
- frame.inter_arrival.received_packet_times.begin();
- EXPECT_EQ(GG_UINT64_C(0x0123456789ABA), iter->first);
- EXPECT_EQ(GG_INT64_C(0x07E1D2C3B4A59687),
- iter->second.Subtract(start_).ToMicroseconds());
- ++iter;
- EXPECT_EQ(GG_UINT64_C(0x0123456789ABB), iter->first);
- EXPECT_EQ(GG_INT64_C(0x07E1D2C3B4A59688),
- iter->second.Subtract(start_).ToMicroseconds());
- ++iter;
- EXPECT_EQ(GG_UINT64_C(0x0123456789ABD), iter->first);
- EXPECT_EQ(GG_INT64_C(0x07E1D2C3B4A59689),
- iter->second.Subtract(start_).ToMicroseconds());
-
- // Now test framing boundaries
- for (size_t i = kQuicFrameTypeSize; i < 31; ++i) {
- string expected_error;
- if (i < 2) {
- expected_error = "Unable to read congestion feedback type.";
- } else if (i < 4) {
- expected_error = "Unable to read accumulated number of lost packets.";
- } else if (i < 5) {
- expected_error = "Unable to read num received packets.";
- } else if (i < 11) {
- expected_error = "Unable to read smallest received.";
- } else if (i < 19) {
- expected_error = "Unable to read time received.";
- } else if (i < 21) {
- expected_error = "Unable to read sequence delta in received packets.";
- } else if (i < 25) {
- expected_error = "Unable to read time delta in received packets.";
- } else if (i < 27) {
- expected_error = "Unable to read sequence delta in received packets.";
- } else if (i < 31) {
- expected_error = "Unable to read time delta in received packets.";
- }
- CheckProcessingFails(
- packet,
- i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
- expected_error, QUIC_INVALID_CONGESTION_FEEDBACK_DATA);
- }
-}
-
-TEST_P(QuicFramerTest, CongestionFeedbackFrameFixRate) {
+TEST_P(QuicFramerTest, CongestionFeedbackFrameFixRate) {
unsigned char packet[] = {
// public flags (8 byte connection_id)
0x3C,
}
}
-TEST_P(QuicFramerTest, RstStreamFrameVersion13) {
- if (version_ > QUIC_VERSION_13) {
- return;
- }
-
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x3C,
- // connection_id
- 0x10, 0x32, 0x54, 0x76,
- 0x98, 0xBA, 0xDC, 0xFE,
- // packet sequence number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // private flags
- 0x00,
-
- // frame type (rst stream frame)
- 0x01,
- // stream id
- 0x04, 0x03, 0x02, 0x01,
- // error code
- 0x01, 0x00, 0x00, 0x00,
-
- // error details length
- 0x0d, 0x00,
- // error details
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n',
- };
-
- 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(GG_UINT64_C(0x01020304), visitor_.rst_stream_frame_.stream_id);
- EXPECT_EQ(0x01, visitor_.rst_stream_frame_.error_code);
- EXPECT_EQ("because I can", visitor_.rst_stream_frame_.error_details);
-
- // Now test framing boundaries
- for (size_t i = kQuicFrameTypeSize;
- i < QuicFramer::GetMinRstStreamFrameSize(version_); ++i) {
- string expected_error;
- if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize) {
- expected_error = "Unable to read stream_id.";
- } else if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize +
- kQuicErrorCodeSize) {
- expected_error = "Unable to read rst stream error code.";
- } else {
- expected_error = "Unable to read rst stream error details.";
- }
- CheckProcessingFails(
- packet,
- i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
- expected_error, QUIC_INVALID_RST_STREAM_DATA);
- }
-}
-
TEST_P(QuicFramerTest, RstStreamFrameQuic) {
- if (version_ <= QUIC_VERSION_13) {
- return;
- }
-
unsigned char packet[] = {
// public flags (8 byte connection_id)
0x3C,
QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
- // WINDOW_UPDATE frame introduced in QUIC_VERSION_14.
- if (version_ <= QUIC_VERSION_13) {
- string expected_error = "Trying to read a WindowUpdateFrame in " +
- QuicVersionToString(version_);
- EXPECT_DFATAL(framer_.ProcessPacket(encrypted), expected_error);
- return;
- }
-
EXPECT_TRUE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
- // BLOCKED frame introduced in QUIC_VERSION_14.
- if (version_ <= QUIC_VERSION_13) {
- string expected_error =
- "Trying to read a BlockedFrame in " + QuicVersionToString(version_);
- EXPECT_DFATAL(framer_.ProcessPacket(encrypted), expected_error);
- return;
- }
-
EXPECT_TRUE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
}
}
+TEST_P(QuicFramerTest, PingFrame) {
+ if (version_ <= QUIC_VERSION_17) {
+ return;
+ }
+
+ unsigned char packet[] = {
+ // public flags (8 byte connection_id)
+ 0x3C,
+ // connection_id
+ 0x10, 0x32, 0x54, 0x76,
+ 0x98, 0xBA, 0xDC, 0xFE,
+ // packet sequence number
+ 0xBC, 0x9A, 0x78, 0x56,
+ 0x34, 0x12,
+ // private flags
+ 0x00,
+
+ // frame type (ping frame)
+ 0x07,
+ };
+
+ 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(1u, visitor_.ping_frames_.size());
+
+ // No need to check the PING frame boundaries because it has no payload.
+}
+
TEST_P(QuicFramerTest, PublicResetPacket) {
unsigned char packet[] = {
// public flags (public reset, 8 byte connection_id)
}
}
-// TODO(wtc): remove this test when we drop support for QUIC_VERSION_13.
-TEST_P(QuicFramerTest, PublicResetPacketOld) {
- unsigned char packet[] = {
- // public flags (public reset, 8 byte connection_id)
- 0x3E,
- // connection_id
- 0x10, 0x32, 0x54, 0x76,
- 0x98, 0xBA, 0xDC, 0xFE,
- // nonce proof
- 0x89, 0x67, 0x45, 0x23,
- 0x01, 0xEF, 0xCD, 0xAB,
- // rejected sequence number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- };
-
- QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
- EXPECT_TRUE(framer_.ProcessPacket(encrypted));
- ASSERT_EQ(QUIC_NO_ERROR, framer_.error());
- ASSERT_TRUE(visitor_.public_reset_packet_.get());
- EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
- visitor_.public_reset_packet_->public_header.connection_id);
- EXPECT_TRUE(visitor_.public_reset_packet_->public_header.reset_flag);
- EXPECT_FALSE(visitor_.public_reset_packet_->public_header.version_flag);
- EXPECT_EQ(GG_UINT64_C(0xABCDEF0123456789),
- visitor_.public_reset_packet_->nonce_proof);
- EXPECT_EQ(GG_UINT64_C(0x123456789ABC),
- visitor_.public_reset_packet_->rejected_sequence_number);
- EXPECT_TRUE(
- visitor_.public_reset_packet_->client_address.address().empty());
-
- // Now test framing boundaries
- for (size_t i = 0; i < arraysize(packet); ++i) {
- string expected_error;
- DVLOG(1) << "iteration: " << i;
- if (i < kConnectionIdOffset) {
- expected_error = "Unable to read public flags.";
- CheckProcessingFails(packet, i, expected_error,
- QUIC_INVALID_PACKET_HEADER);
- } else if (i < kPublicResetPacketNonceProofOffset) {
- expected_error = "Unable to read ConnectionId.";
- CheckProcessingFails(packet, i, expected_error,
- QUIC_INVALID_PACKET_HEADER);
- } else if (i < kPublicResetPacketRejectedSequenceNumberOffset) {
- expected_error = "Unable to read nonce proof.";
- CheckProcessingFails(packet, i, expected_error,
- QUIC_INVALID_PUBLIC_RST_PACKET);
- } else {
- expected_error = "Unable to read rejected sequence number.";
- CheckProcessingFails(packet, i, expected_error,
- QUIC_INVALID_PUBLIC_RST_PACKET);
- }
- }
-}
-
TEST_P(QuicFramerTest, VersionNegotiationPacket) {
unsigned char packet[] = {
// public flags (version, 8 byte connection_id)
AsChars(packet), arraysize(packet));
}
-TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
+TEST_P(QuicFramerTest, BuildStreamFramePacketInFecGroup) {
QuicPacketHeader header;
header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
header.public_header.reset_flag = false;
- header.public_header.version_flag = true;
+ header.public_header.version_flag = false;
header.fec_flag = false;
header.entropy_flag = true;
header.packet_sequence_number = GG_UINT64_C(0x77123456789ABC);
- header.fec_group = 0;
+ header.is_in_fec_group = IN_FEC_GROUP;
+ header.fec_group = GG_UINT64_C(0x77123456789ABC);
QuicStreamFrame stream_frame;
stream_frame.stream_id = 0x01020304;
QuicFrames frames;
frames.push_back(QuicFrame(&stream_frame));
-
unsigned char packet[] = {
- // public flags (version, 8 byte connection_id)
- 0x3D,
+ // public flags (8 byte connection_id)
+ 0x3C,
// connection_id
0x10, 0x32, 0x54, 0x76,
0x98, 0xBA, 0xDC, 0xFE,
- // version tag
- 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
// packet sequence number
0xBC, 0x9A, 0x78, 0x56,
0x34, 0x12,
- // private flags (entropy)
- 0x01,
-
- // frame type (stream frame with fin and no length)
- 0xDF,
+ // private flags (entropy, is_in_fec_group)
+ 0x03,
+ // FEC group
+ 0x00,
+ // frame type (stream frame with fin and data length field)
+ 0xFF,
// stream id
0x04, 0x03, 0x02, 0x01,
// offset
0x54, 0x76, 0x10, 0x32,
0xDC, 0xFE, 0x98, 0xBA,
+ // data length (since packet is in an FEC group)
+ 0x0C, 0x00,
// data
'h', 'e', 'l', 'l',
'o', ' ', 'w', 'o',
'r', 'l', 'd', '!',
};
- QuicFramerPeer::SetIsServer(&framer_, false);
scoped_ptr<QuicPacket> data(
framer_.BuildUnsizedDataPacket(header, frames).packet);
ASSERT_TRUE(data != NULL);
AsChars(packet), arraysize(packet));
}
-TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) {
- QuicPacketPublicHeader header;
- header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
- header.reset_flag = false;
- header.version_flag = true;
-
- unsigned char packet[] = {
- // public flags (version, 8 byte connection_id)
- 0x0D,
- // connection_id
- 0x10, 0x32, 0x54, 0x76,
- 0x98, 0xBA, 0xDC, 0xFE,
- // version tag
- 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
- };
-
- 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, BuildAckFramePacket) {
- if (version_ <= QUIC_VERSION_15) {
- return;
- }
+TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
QuicPacketHeader header;
header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
header.public_header.reset_flag = false;
- header.public_header.version_flag = false;
+ header.public_header.version_flag = true;
header.fec_flag = false;
header.entropy_flag = true;
- header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8);
+ header.packet_sequence_number = GG_UINT64_C(0x77123456789ABC);
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));
+ QuicStreamFrame stream_frame;
+ stream_frame.stream_id = 0x01020304;
+ stream_frame.fin = true;
+ stream_frame.offset = GG_UINT64_C(0xBA98FEDC32107654);
+ stream_frame.data = MakeIOVector("hello world!");
QuicFrames frames;
- frames.push_back(QuicFrame(&ack_frame));
+ frames.push_back(QuicFrame(&stream_frame));
unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x3C,
+ // public flags (version, 8 byte connection_id)
+ 0x3D,
// connection_id
0x10, 0x32, 0x54, 0x76,
0x98, 0xBA, 0xDC, 0xFE,
+ // version tag
+ 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
// packet sequence number
- 0xA8, 0x9A, 0x78, 0x56,
+ 0xBC, 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,
+ // frame type (stream frame with fin and no length)
+ 0xDF,
+ // stream id
+ 0x04, 0x03, 0x02, 0x01,
+ // offset
+ 0x54, 0x76, 0x10, 0x32,
+ 0xDC, 0xFE, 0x98, 0xBA,
+ // data
+ 'h', 'e', 'l', 'l',
+ 'o', ' ', 'w', 'o',
+ 'r', 'l', 'd', '!',
};
+ QuicFramerPeer::SetIsServer(&framer_, false);
scoped_ptr<QuicPacket> data(
framer_.BuildUnsizedDataPacket(header, frames).packet);
ASSERT_TRUE(data != NULL);
AsChars(packet), arraysize(packet));
}
-TEST_P(QuicFramerTest, BuildAckFramePacket15) {
- if (version_ != QUIC_VERSION_15) {
+TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) {
+ QuicPacketPublicHeader header;
+ header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
+ header.reset_flag = false;
+ header.version_flag = true;
+
+ unsigned char packet[] = {
+ // public flags (version, 8 byte connection_id)
+ 0x0D,
+ // connection_id
+ 0x10, 0x32, 0x54, 0x76,
+ 0x98, 0xBA, 0xDC, 0xFE,
+ // version tag
+ 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
+ };
+
+ 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, BuildAckFramePacket) {
+ if (version_ <= QUIC_VERSION_15) {
return;
}
QuicPacketHeader header;
ack_frame.received_info.delta_time_largest_observed = QuicTime::Delta::Zero();
ack_frame.received_info.missing_packets.insert(
GG_UINT64_C(0x770123456789ABE));
- ack_frame.sent_info.entropy_hash = 0x14;
- ack_frame.sent_info.least_unacked = GG_UINT64_C(0x770123456789AA0);
QuicFrames frames;
frames.push_back(QuicFrame(&ack_frame));
// frame type (ack frame)
// (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
0x6C,
- // 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,
// entropy hash of all received packets.
0x43,
// largest observed packet sequence number
AsChars(packet), arraysize(packet));
}
-TEST_P(QuicFramerTest, BuildAckFramePacketV13) {
- if (version_ != QUIC_VERSION_13) {
+TEST_P(QuicFramerTest, BuildAckFramePacket15) {
+ if (version_ != QUIC_VERSION_15) {
return;
}
QuicPacketHeader header;
0x01,
// 0 more missing packets in range.
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, BuildCongestionFeedbackFramePacketTCP) {
- if (version_ == QUIC_VERSION_13) {
- 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;
-
- QuicCongestionFeedbackFrame congestion_feedback_frame;
- congestion_feedback_frame.type = kTCP;
- congestion_feedback_frame.tcp.receive_window = 0x4030;
-
- QuicFrames frames;
- frames.push_back(QuicFrame(&congestion_feedback_frame));
-
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x3C,
- // connection_id
- 0x10, 0x32, 0x54, 0x76,
- 0x98, 0xBA, 0xDC, 0xFE,
- // packet sequence number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // private flags
- 0x00,
-
- // frame type (congestion feedback frame)
- 0x20,
- // congestion feedback type (TCP)
+ // 0 revived packets.
0x00,
- // TCP receive window
- 0x03, 0x04,
};
scoped_ptr<QuicPacket> data(
AsChars(packet), arraysize(packet));
}
-TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketTCPV13) {
- if (version_ != QUIC_VERSION_13) {
- return;
- }
+TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketTCP) {
QuicPacketHeader header;
header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
header.public_header.reset_flag = false;
0x20,
// congestion feedback type (TCP)
0x00,
- // accumulated number of lost packets
- 0x00, 0x00,
// TCP receive window
0x03, 0x04,
};
}
TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketInterArrival) {
- if (version_ == QUIC_VERSION_13) {
- return;
- }
QuicPacketHeader header;
header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
header.public_header.reset_flag = false;
AsChars(packet), arraysize(packet));
}
-TEST_P(QuicFramerTest, BuildCongestionFeedbackFramePacketInterArrivalV13) {
- if (version_ != QUIC_VERSION_13) {
- 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;
-
- QuicCongestionFeedbackFrame frame;
- frame.type = kInterArrival;
- frame.inter_arrival.received_packet_times.insert(
- make_pair(GG_UINT64_C(0x0123456789ABA),
- start_.Add(QuicTime::Delta::FromMicroseconds(
- GG_UINT64_C(0x07E1D2C3B4A59687)))));
- frame.inter_arrival.received_packet_times.insert(
- make_pair(GG_UINT64_C(0x0123456789ABB),
- start_.Add(QuicTime::Delta::FromMicroseconds(
- GG_UINT64_C(0x07E1D2C3B4A59688)))));
- frame.inter_arrival.received_packet_times.insert(
- make_pair(GG_UINT64_C(0x0123456789ABD),
- start_.Add(QuicTime::Delta::FromMicroseconds(
- GG_UINT64_C(0x07E1D2C3B4A59689)))));
- QuicFrames frames;
- frames.push_back(QuicFrame(&frame));
-
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x3C,
- // connection_id
- 0x10, 0x32, 0x54, 0x76,
- 0x98, 0xBA, 0xDC, 0xFE,
- // packet sequence number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // private flags
- 0x00,
-
- // frame type (congestion feedback frame)
- 0x20,
- // congestion feedback type (inter arrival)
- 0x01,
- // accumulated_number_of_lost_packets
- 0x00, 0x00,
- // num received packets
- 0x03,
- // lowest sequence number
- 0xBA, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // receive time
- 0x87, 0x96, 0xA5, 0xB4,
- 0xC3, 0xD2, 0xE1, 0x07,
- // sequence delta
- 0x01, 0x00,
- // time delta
- 0x01, 0x00, 0x00, 0x00,
- // sequence delta (skip one packet)
- 0x03, 0x00,
- // time delta
- 0x02, 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, BuildStopWaitingPacket) {
if (version_ <= QUIC_VERSION_15) {
return;
ASSERT_TRUE(data == NULL);
}
-TEST_P(QuicFramerTest, BuildRstFramePacketVersion13) {
- if (version_ > QUIC_VERSION_13) {
- 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;
-
- QuicRstStreamFrame rst_frame;
- rst_frame.stream_id = 0x01020304;
- rst_frame.error_code = static_cast<QuicRstStreamErrorCode>(0x05060708);
- rst_frame.error_details = "because I can";
-
- unsigned char packet[] = {
- // public flags (8 byte connection_id)
- 0x3C,
- // connection_id
- 0x10, 0x32, 0x54, 0x76,
- 0x98, 0xBA, 0xDC, 0xFE,
- // packet sequence number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // private flags
- 0x00,
-
- // frame type (rst stream frame)
- 0x01,
- // stream id
- 0x04, 0x03, 0x02, 0x01,
- // error code
- 0x08, 0x07, 0x06, 0x05,
- // error details length
- 0x0d, 0x00,
- // error details
- 'b', 'e', 'c', 'a',
- 'u', 's', 'e', ' ',
- 'I', ' ', 'c', 'a',
- 'n',
- };
-
- QuicFrames frames;
- frames.push_back(QuicFrame(&rst_frame));
-
- 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, BuildRstFramePacketQuic) {
- if (version_ <= QUIC_VERSION_13) {
- return;
- }
-
QuicPacketHeader header;
header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
header.public_header.reset_flag = false;
0x44, 0x33, 0x22, 0x11,
};
- if (version_ > QUIC_VERSION_13) {
- scoped_ptr<QuicPacket> data(
- framer_.BuildUnsizedDataPacket(header, frames).packet);
- ASSERT_TRUE(data != NULL);
+ 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));
- } else {
- string expected_error = "Attempt to add a WindowUpdateFrame in " +
- QuicVersionToString(version_);
- EXPECT_DFATAL(framer_.BuildUnsizedDataPacket(header, frames),
- expected_error);
- return;
- }
+ test::CompareCharArraysWithHexError("constructed packet", data->data(),
+ data->length(), AsChars(packet),
+ arraysize(packet));
}
TEST_P(QuicFramerTest, BuildBlockedPacket) {
0x04, 0x03, 0x02, 0x01,
};
- if (version_ > QUIC_VERSION_13) {
+ 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, BuildPingPacket) {
+ 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(0x123456789ABC);
+ header.fec_group = 0;
+
+ QuicPingFrame ping_frame;
+
+ QuicFrames frames;
+ frames.push_back(QuicFrame(&ping_frame));
+
+ unsigned char packet[] = {
+ // public flags (8 byte connection_id)
+ 0x3C,
+ // connection_id
+ 0x10, 0x32, 0x54, 0x76,
+ 0x98, 0xBA, 0xDC, 0xFE,
+ // packet sequence number
+ 0xBC, 0x9A, 0x78, 0x56,
+ 0x34, 0x12,
+ // private flags(entropy)
+ 0x01,
+
+ // frame type (ping frame)
+ 0x07,
+ };
+
+ if (version_ > QUIC_VERSION_17) {
scoped_ptr<QuicPacket> data(
framer_.BuildUnsizedDataPacket(header, frames).packet);
ASSERT_TRUE(data != NULL);
arraysize(packet));
} else {
string expected_error =
- "Attempt to add a BlockedFrame in " + QuicVersionToString(version_);
+ "Attempt to add a PingFrame in " + QuicVersionToString(version_);
EXPECT_DFATAL(framer_.BuildUnsizedDataPacket(header, frames),
expected_error);
return;