Index: net/quic/quic_framer_test.cc |
diff --git a/net/quic/quic_framer_test.cc b/net/quic/quic_framer_test.cc |
deleted file mode 100644 |
index 88a0b8e9492100752d33b65272d537f7bf551a16..0000000000000000000000000000000000000000 |
--- a/net/quic/quic_framer_test.cc |
+++ /dev/null |
@@ -1,7192 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "net/quic/quic_framer.h" |
- |
-#include <stdint.h> |
- |
-#include <algorithm> |
-#include <map> |
-#include <memory> |
-#include <string> |
-#include <vector> |
- |
-#include "base/logging.h" |
-#include "base/stl_util.h" |
-#include "net/quic/crypto/null_decrypter.h" |
-#include "net/quic/crypto/quic_decrypter.h" |
-#include "net/quic/crypto/quic_encrypter.h" |
-#include "net/quic/quic_protocol.h" |
-#include "net/quic/quic_utils.h" |
-#include "net/quic/test_tools/quic_framer_peer.h" |
-#include "net/quic/test_tools/quic_test_utils.h" |
-#include "net/test/gtest_util.h" |
- |
-using base::StringPiece; |
-using std::make_pair; |
-using std::map; |
-using std::numeric_limits; |
-using std::pair; |
-using std::string; |
-using std::vector; |
-using testing::Return; |
-using testing::Truly; |
-using testing::_; |
- |
-namespace net { |
-namespace test { |
- |
-const QuicPacketNumber kEpoch = UINT64_C(1) << 48; |
-const QuicPacketNumber kMask = kEpoch - 1; |
- |
-// Use fields in which each byte is distinct to ensure that every byte is |
-// framed correctly. The values are otherwise arbitrary. |
-const QuicConnectionId kConnectionId = UINT64_C(0xFEDCBA9876543210); |
-const QuicPathId kPathId = 0x42; |
-const QuicPacketNumber kPacketNumber = UINT64_C(0x123456789ABC); |
-const QuicPacketNumber kLargestObserved = UINT64_C(0x0123456789ABF); |
-const QuicPacketNumber kSmallLargestObserved = UINT16_C(0x1234); |
-const QuicPacketNumber kMissingPacket = UINT64_C(0x0123456789ABE); |
-const QuicPacketNumber kSmallMissingPacket = UINT16_C(0x1233); |
-const QuicPacketNumber kLeastUnacked = UINT64_C(0x0123456789AA0); |
-const QuicStreamId kStreamId = UINT64_C(0x01020304); |
-const QuicStreamOffset kStreamOffset = UINT64_C(0xBA98FEDC32107654); |
-const QuicPublicResetNonceProof kNonceProof = UINT64_C(0xABCDEF0123456789); |
- |
-// Index into the connection_id offset in the header. |
-const size_t kConnectionIdOffset = kPublicFlagsSize; |
-// Index into the version string in the header. (if present). |
-const size_t kVersionOffset = kConnectionIdOffset + PACKET_8BYTE_CONNECTION_ID; |
- |
-// Size in bytes of the stream frame fields for an arbitrary StreamID and |
-// offset and the last frame in a packet. |
-size_t GetMinStreamFrameSize() { |
- return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize; |
-} |
- |
-// Index into the path id offset in the header (if present). |
-size_t GetPathIdOffset(QuicConnectionIdLength connection_id_length, |
- bool include_version) { |
- return kConnectionIdOffset + connection_id_length + |
- (include_version ? kQuicVersionSize : 0); |
-} |
- |
-// Index into the packet number offset in the header. |
-size_t GetPacketNumberOffset(QuicConnectionIdLength connection_id_length, |
- bool include_version, |
- bool include_path_id) { |
- return kConnectionIdOffset + connection_id_length + |
- (include_version ? kQuicVersionSize : 0) + |
- (include_path_id ? kQuicPathIdSize : 0); |
-} |
- |
-size_t GetPacketNumberOffset(bool include_version, bool include_path_id) { |
- return GetPacketNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version, |
- include_path_id); |
-} |
- |
-// Index into the private flags offset in the data packet header. |
-size_t GetPrivateFlagsOffset(QuicConnectionIdLength connection_id_length, |
- bool include_version, |
- bool include_path_id) { |
- return GetPacketNumberOffset(connection_id_length, include_version, |
- include_path_id) + |
- PACKET_6BYTE_PACKET_NUMBER; |
-} |
- |
-size_t GetPrivateFlagsOffset(bool include_version, bool include_path_id) { |
- return GetPrivateFlagsOffset(PACKET_8BYTE_CONNECTION_ID, include_version, |
- include_path_id); |
-} |
- |
-size_t GetPrivateFlagsOffset(bool include_version, |
- bool include_path_id, |
- QuicPacketNumberLength packet_number_length) { |
- return GetPacketNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version, |
- include_path_id) + |
- packet_number_length; |
-} |
- |
-// Index into the message tag of the public reset packet. |
-// Public resets always have full connection_ids. |
-const size_t kPublicResetPacketMessageTagOffset = |
- kConnectionIdOffset + PACKET_8BYTE_CONNECTION_ID; |
- |
-class TestEncrypter : public QuicEncrypter { |
- public: |
- ~TestEncrypter() override {} |
- bool SetKey(StringPiece key) override { return true; } |
- bool SetNoncePrefix(StringPiece nonce_prefix) override { return true; } |
- bool EncryptPacket(QuicPathId path_id, |
- QuicPacketNumber packet_number, |
- StringPiece associated_data, |
- StringPiece plaintext, |
- char* output, |
- size_t* output_length, |
- size_t max_output_length) override { |
- path_id_ = path_id; |
- packet_number_ = packet_number; |
- associated_data_ = associated_data.as_string(); |
- plaintext_ = plaintext.as_string(); |
- memcpy(output, plaintext.data(), plaintext.length()); |
- *output_length = plaintext.length(); |
- return true; |
- } |
- size_t GetKeySize() const override { return 0; } |
- size_t GetNoncePrefixSize() const override { return 0; } |
- size_t GetMaxPlaintextSize(size_t ciphertext_size) const override { |
- return ciphertext_size; |
- } |
- size_t GetCiphertextSize(size_t plaintext_size) const override { |
- return plaintext_size; |
- } |
- StringPiece GetKey() const override { return StringPiece(); } |
- StringPiece GetNoncePrefix() const override { return StringPiece(); } |
- QuicPathId path_id_; |
- QuicPacketNumber packet_number_; |
- string associated_data_; |
- string plaintext_; |
-}; |
- |
-class TestDecrypter : public QuicDecrypter { |
- public: |
- ~TestDecrypter() override {} |
- bool SetKey(StringPiece key) override { return true; } |
- bool SetNoncePrefix(StringPiece nonce_prefix) override { return true; } |
- bool SetPreliminaryKey(StringPiece key) override { |
- QUIC_BUG << "should not be called"; |
- return false; |
- } |
- bool SetDiversificationNonce(DiversificationNonce key) override { |
- return true; |
- } |
- bool DecryptPacket(QuicPathId path_id, |
- QuicPacketNumber packet_number, |
- StringPiece associated_data, |
- StringPiece ciphertext, |
- char* output, |
- size_t* output_length, |
- size_t max_output_length) override { |
- path_id_ = path_id; |
- packet_number_ = packet_number; |
- associated_data_ = associated_data.as_string(); |
- ciphertext_ = ciphertext.as_string(); |
- memcpy(output, ciphertext.data(), ciphertext.length()); |
- *output_length = ciphertext.length(); |
- return true; |
- } |
- StringPiece GetKey() const override { return StringPiece(); } |
- StringPiece GetNoncePrefix() const override { return StringPiece(); } |
- const char* cipher_name() const override { return "Test"; } |
- // Use a distinct value starting with 0xFFFFFF, which is never used by TLS. |
- uint32_t cipher_id() const override { return 0xFFFFFFF2; } |
- QuicPathId path_id_; |
- QuicPacketNumber packet_number_; |
- string associated_data_; |
- string ciphertext_; |
-}; |
- |
-class TestQuicVisitor : public QuicFramerVisitorInterface { |
- public: |
- TestQuicVisitor() |
- : error_count_(0), |
- version_mismatch_(0), |
- packet_count_(0), |
- frame_count_(0), |
- complete_packets_(0), |
- accept_packet_(true), |
- accept_public_header_(true) {} |
- |
- ~TestQuicVisitor() override { |
- STLDeleteElements(&stream_frames_); |
- STLDeleteElements(&ack_frames_); |
- STLDeleteElements(&stop_waiting_frames_); |
- STLDeleteElements(&padding_frames_); |
- STLDeleteElements(&ping_frames_); |
- STLDeleteElements(&stream_data_); |
- } |
- |
- void OnError(QuicFramer* f) override { |
- DVLOG(1) << "QuicFramer Error: " << QuicUtils::ErrorToString(f->error()) |
- << " (" << f->error() << ")"; |
- ++error_count_; |
- } |
- |
- void OnPacket() override {} |
- |
- void OnPublicResetPacket(const QuicPublicResetPacket& packet) override { |
- public_reset_packet_.reset(new QuicPublicResetPacket(packet)); |
- } |
- |
- void OnVersionNegotiationPacket( |
- const QuicVersionNegotiationPacket& packet) override { |
- version_negotiation_packet_.reset(new QuicVersionNegotiationPacket(packet)); |
- } |
- |
- bool OnProtocolVersionMismatch(QuicVersion version) override { |
- DVLOG(1) << "QuicFramer Version Mismatch, version: " << version; |
- ++version_mismatch_; |
- return true; |
- } |
- |
- bool OnUnauthenticatedPublicHeader( |
- const QuicPacketPublicHeader& header) override { |
- public_header_.reset(new QuicPacketPublicHeader(header)); |
- return accept_public_header_; |
- } |
- |
- bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override { |
- return true; |
- } |
- |
- void OnDecryptedPacket(EncryptionLevel level) override {} |
- |
- bool OnPacketHeader(const QuicPacketHeader& header) override { |
- if (header.fec_flag) { |
- // Drop any FEC packet. |
- return false; |
- } |
- ++packet_count_; |
- header_.reset(new QuicPacketHeader(header)); |
- return accept_packet_; |
- } |
- |
- bool OnStreamFrame(const QuicStreamFrame& frame) override { |
- ++frame_count_; |
- // Save a copy of the data so it is valid after the packet is processed. |
- string* string_data = new string(); |
- StringPiece(frame.data_buffer, frame.data_length) |
- .AppendToString(string_data); |
- stream_data_.push_back(string_data); |
- stream_frames_.push_back(new QuicStreamFrame(frame.stream_id, frame.fin, |
- frame.offset, *string_data)); |
- return true; |
- } |
- |
- bool OnAckFrame(const QuicAckFrame& frame) override { |
- ++frame_count_; |
- ack_frames_.push_back(new QuicAckFrame(frame)); |
- return true; |
- } |
- |
- bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override { |
- ++frame_count_; |
- stop_waiting_frames_.push_back(new QuicStopWaitingFrame(frame)); |
- return true; |
- } |
- |
- bool OnPaddingFrame(const QuicPaddingFrame& frame) override { |
- padding_frames_.push_back(new QuicPaddingFrame(frame)); |
- return true; |
- } |
- |
- bool OnPingFrame(const QuicPingFrame& frame) override { |
- ++frame_count_; |
- ping_frames_.push_back(new QuicPingFrame(frame)); |
- return true; |
- } |
- |
- void OnPacketComplete() override { ++complete_packets_; } |
- |
- bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override { |
- rst_stream_frame_ = frame; |
- return true; |
- } |
- |
- bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override { |
- connection_close_frame_ = frame; |
- return true; |
- } |
- |
- bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override { |
- goaway_frame_ = frame; |
- return true; |
- } |
- |
- bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override { |
- window_update_frame_ = frame; |
- return true; |
- } |
- |
- bool OnBlockedFrame(const QuicBlockedFrame& frame) override { |
- blocked_frame_ = frame; |
- return true; |
- } |
- |
- bool OnPathCloseFrame(const QuicPathCloseFrame& frame) override { |
- path_close_frame_ = frame; |
- return true; |
- } |
- |
- // Counters from the visitor_ callbacks. |
- int error_count_; |
- int version_mismatch_; |
- int packet_count_; |
- int frame_count_; |
- int complete_packets_; |
- bool accept_packet_; |
- bool accept_public_header_; |
- |
- std::unique_ptr<QuicPacketHeader> header_; |
- std::unique_ptr<QuicPacketPublicHeader> public_header_; |
- std::unique_ptr<QuicPublicResetPacket> public_reset_packet_; |
- std::unique_ptr<QuicVersionNegotiationPacket> version_negotiation_packet_; |
- vector<QuicStreamFrame*> stream_frames_; |
- vector<QuicAckFrame*> ack_frames_; |
- vector<QuicStopWaitingFrame*> stop_waiting_frames_; |
- vector<QuicPaddingFrame*> padding_frames_; |
- vector<QuicPingFrame*> ping_frames_; |
- QuicRstStreamFrame rst_stream_frame_; |
- QuicConnectionCloseFrame connection_close_frame_; |
- QuicGoAwayFrame goaway_frame_; |
- QuicWindowUpdateFrame window_update_frame_; |
- QuicBlockedFrame blocked_frame_; |
- QuicPathCloseFrame path_close_frame_; |
- vector<string*> stream_data_; |
-}; |
- |
-class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> { |
- public: |
- QuicFramerTest() |
- : encrypter_(new test::TestEncrypter()), |
- decrypter_(new test::TestDecrypter()), |
- start_(QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(0x10)), |
- framer_(QuicSupportedVersions(), start_, Perspective::IS_SERVER) { |
- version_ = GetParam(); |
- framer_.set_version(version_); |
- framer_.SetDecrypter(ENCRYPTION_NONE, decrypter_); |
- framer_.SetEncrypter(ENCRYPTION_NONE, encrypter_); |
- framer_.set_visitor(&visitor_); |
- framer_.set_received_entropy_calculator(&entropy_calculator_); |
- } |
- |
- // Helper function to get unsigned char representation of digit in the |
- // units place of the current QUIC version number. |
- unsigned char GetQuicVersionDigitOnes() { |
- return static_cast<unsigned char>('0' + version_ % 10); |
- } |
- |
- // Helper function to get unsigned char representation of digit in the |
- // tens place of the current QUIC version number. |
- unsigned char GetQuicVersionDigitTens() { |
- return static_cast<unsigned char>('0' + (version_ / 10) % 10); |
- } |
- |
- bool CheckEncryption(QuicPathId path_id, |
- QuicPacketNumber packet_number, |
- QuicPacket* packet) { |
- if (packet_number != encrypter_->packet_number_) { |
- LOG(ERROR) << "Encrypted incorrect packet number. expected " |
- << packet_number << " actual: " << encrypter_->packet_number_; |
- return false; |
- } |
- if (packet->AssociatedData(framer_.version()) != |
- encrypter_->associated_data_) { |
- LOG(ERROR) << "Encrypted incorrect associated data. expected " |
- << packet->AssociatedData(framer_.version()) |
- << " actual: " << encrypter_->associated_data_; |
- return false; |
- } |
- if (packet->Plaintext(framer_.version()) != encrypter_->plaintext_) { |
- LOG(ERROR) << "Encrypted incorrect plaintext data. expected " |
- << packet->Plaintext(framer_.version()) |
- << " actual: " << encrypter_->plaintext_; |
- return false; |
- } |
- return true; |
- } |
- |
- bool CheckDecryption(const QuicEncryptedPacket& encrypted, |
- bool includes_version, |
- bool includes_path_id, |
- bool includes_diversification_nonce) { |
- if (visitor_.header_->packet_number != decrypter_->packet_number_) { |
- LOG(ERROR) << "Decrypted incorrect packet number. expected " |
- << visitor_.header_->packet_number |
- << " actual: " << decrypter_->packet_number_; |
- return false; |
- } |
- if (QuicFramer::GetAssociatedDataFromEncryptedPacket( |
- framer_.version(), encrypted, PACKET_8BYTE_CONNECTION_ID, |
- includes_version, includes_path_id, includes_diversification_nonce, |
- PACKET_6BYTE_PACKET_NUMBER) != decrypter_->associated_data_) { |
- LOG(ERROR) << "Decrypted incorrect associated data. expected " |
- << QuicFramer::GetAssociatedDataFromEncryptedPacket( |
- framer_.version(), encrypted, |
- PACKET_8BYTE_CONNECTION_ID, includes_version, |
- includes_path_id, includes_diversification_nonce, |
- PACKET_6BYTE_PACKET_NUMBER) |
- << " actual: " << decrypter_->associated_data_; |
- return false; |
- } |
- StringPiece ciphertext( |
- encrypted.AsStringPiece().substr(GetStartOfEncryptedData( |
- framer_.version(), PACKET_8BYTE_CONNECTION_ID, includes_version, |
- includes_path_id, includes_diversification_nonce, |
- PACKET_6BYTE_PACKET_NUMBER))); |
- if (ciphertext != decrypter_->ciphertext_) { |
- LOG(ERROR) << "Decrypted incorrect ciphertext data. expected " |
- << ciphertext << " actual: " << decrypter_->ciphertext_; |
- return false; |
- } |
- return true; |
- } |
- |
- char* AsChars(unsigned char* data) { return reinterpret_cast<char*>(data); } |
- |
- void CheckProcessingFails(unsigned char* packet, |
- size_t len, |
- string expected_error, |
- QuicErrorCode error_code) { |
- QuicEncryptedPacket encrypted(AsChars(packet), len, false); |
- EXPECT_FALSE(framer_.ProcessPacket(encrypted)) << "len: " << len; |
- EXPECT_EQ(expected_error, framer_.detailed_error()) << "len: " << len; |
- EXPECT_EQ(error_code, framer_.error()) << "len: " << len; |
- } |
- |
- // Checks if the supplied string matches data in the supplied StreamFrame. |
- void CheckStreamFrameData(string str, QuicStreamFrame* frame) { |
- EXPECT_EQ(str, string(frame->data_buffer, frame->data_length)); |
- } |
- |
- void CheckStreamFrameBoundaries(unsigned char* packet, |
- size_t stream_id_size, |
- bool include_version) { |
- // Now test framing boundaries. |
- for (size_t i = kQuicFrameTypeSize; i < GetMinStreamFrameSize(); ++i) { |
- string expected_error; |
- if (i < kQuicFrameTypeSize + stream_id_size) { |
- expected_error = "Unable to read stream_id."; |
- } else if (i < kQuicFrameTypeSize + stream_id_size + |
- kQuicMaxStreamOffsetSize) { |
- expected_error = "Unable to read offset."; |
- } else { |
- expected_error = "Unable to read frame data."; |
- } |
- CheckProcessingFails( |
- packet, |
- i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- include_version, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER), |
- expected_error, QUIC_INVALID_STREAM_DATA); |
- } |
- } |
- |
- void CheckCalculatePacketNumber(QuicPacketNumber expected_packet_number, |
- QuicPacketNumber last_packet_number) { |
- QuicPacketNumber wire_packet_number = expected_packet_number & kMask; |
- QuicFramerPeer::SetLastPacketNumber(&framer_, last_packet_number); |
- EXPECT_EQ( |
- expected_packet_number, |
- QuicFramerPeer::CalculatePacketNumberFromWire( |
- &framer_, PACKET_6BYTE_PACKET_NUMBER, |
- QuicFramerPeer::GetLastPacketNumber(&framer_), wire_packet_number)) |
- << "last_packet_number: " << last_packet_number |
- << " wire_packet_number: " << wire_packet_number; |
- } |
- |
- QuicPacket* BuildDataPacket(const QuicPacketHeader& header, |
- const QuicFrames& frames) { |
- return BuildUnsizedDataPacket(&framer_, header, frames); |
- } |
- |
- QuicPacket* BuildDataPacket(const QuicPacketHeader& header, |
- const QuicFrames& frames, |
- size_t packet_size) { |
- return BuildUnsizedDataPacket(&framer_, header, frames, packet_size); |
- } |
- |
- test::TestEncrypter* encrypter_; |
- test::TestDecrypter* decrypter_; |
- QuicVersion version_; |
- QuicTime start_; |
- QuicFramer framer_; |
- test::TestQuicVisitor visitor_; |
- test::TestEntropyCalculator entropy_calculator_; |
-}; |
- |
-// Run all framer tests with all supported versions of QUIC. |
-INSTANTIATE_TEST_CASE_P(QuicFramerTests, |
- QuicFramerTest, |
- ::testing::ValuesIn(kSupportedQuicVersions)); |
- |
-TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearEpochStart) { |
- // A few quick manual sanity checks. |
- CheckCalculatePacketNumber(UINT64_C(1), UINT64_C(0)); |
- CheckCalculatePacketNumber(kEpoch + 1, kMask); |
- CheckCalculatePacketNumber(kEpoch, kMask); |
- |
- // Cases where the last number was close to the start of the range. |
- for (uint64_t last = 0; last < 10; last++) { |
- // Small numbers should not wrap (even if they're out of order). |
- for (uint64_t j = 0; j < 10; j++) { |
- CheckCalculatePacketNumber(j, last); |
- } |
- |
- // Large numbers should not wrap either (because we're near 0 already). |
- for (uint64_t j = 0; j < 10; j++) { |
- CheckCalculatePacketNumber(kEpoch - 1 - j, last); |
- } |
- } |
-} |
- |
-TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearEpochEnd) { |
- // Cases where the last number was close to the end of the range |
- for (uint64_t i = 0; i < 10; i++) { |
- QuicPacketNumber last = kEpoch - i; |
- |
- // Small numbers should wrap. |
- for (uint64_t j = 0; j < 10; j++) { |
- CheckCalculatePacketNumber(kEpoch + j, last); |
- } |
- |
- // Large numbers should not (even if they're out of order). |
- for (uint64_t j = 0; j < 10; j++) { |
- CheckCalculatePacketNumber(kEpoch - 1 - j, last); |
- } |
- } |
-} |
- |
-// Next check where we're in a non-zero epoch to verify we handle |
-// reverse wrapping, too. |
-TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearPrevEpoch) { |
- const uint64_t prev_epoch = 1 * kEpoch; |
- const uint64_t cur_epoch = 2 * kEpoch; |
- // Cases where the last number was close to the start of the range |
- for (uint64_t i = 0; i < 10; i++) { |
- uint64_t last = cur_epoch + i; |
- // Small number should not wrap (even if they're out of order). |
- for (uint64_t j = 0; j < 10; j++) { |
- CheckCalculatePacketNumber(cur_epoch + j, last); |
- } |
- |
- // But large numbers should reverse wrap. |
- for (uint64_t j = 0; j < 10; j++) { |
- uint64_t num = kEpoch - 1 - j; |
- CheckCalculatePacketNumber(prev_epoch + num, last); |
- } |
- } |
-} |
- |
-TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearNextEpoch) { |
- const uint64_t cur_epoch = 2 * kEpoch; |
- const uint64_t next_epoch = 3 * kEpoch; |
- // Cases where the last number was close to the end of the range |
- for (uint64_t i = 0; i < 10; i++) { |
- QuicPacketNumber last = next_epoch - 1 - i; |
- |
- // Small numbers should wrap. |
- for (uint64_t j = 0; j < 10; j++) { |
- CheckCalculatePacketNumber(next_epoch + j, last); |
- } |
- |
- // but large numbers should not (even if they're out of order). |
- for (uint64_t j = 0; j < 10; j++) { |
- uint64_t num = kEpoch - 1 - j; |
- CheckCalculatePacketNumber(cur_epoch + num, last); |
- } |
- } |
-} |
- |
-TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearNextMax) { |
- const uint64_t max_number = numeric_limits<uint64_t>::max(); |
- const uint64_t max_epoch = max_number & ~kMask; |
- |
- // Cases where the last number was close to the end of the range |
- for (uint64_t i = 0; i < 10; i++) { |
- // Subtract 1, because the expected next packet number is 1 more than the |
- // last packet number. |
- QuicPacketNumber last = max_number - i - 1; |
- |
- // Small numbers should not wrap, because they have nowhere to go. |
- for (uint64_t j = 0; j < 10; j++) { |
- CheckCalculatePacketNumber(max_epoch + j, last); |
- } |
- |
- // Large numbers should not wrap either. |
- for (uint64_t j = 0; j < 10; j++) { |
- uint64_t num = kEpoch - 1 - j; |
- CheckCalculatePacketNumber(max_epoch + num, last); |
- } |
- } |
-} |
- |
-TEST_P(QuicFramerTest, EmptyPacket) { |
- char packet[] = {0x00}; |
- QuicEncryptedPacket encrypted(packet, 0, false); |
- EXPECT_FALSE(framer_.ProcessPacket(encrypted)); |
- EXPECT_EQ(QUIC_INVALID_PACKET_HEADER, framer_.error()); |
-} |
- |
-TEST_P(QuicFramerTest, LargePacket) { |
- // clang-format off |
- unsigned char packet[kMaxPacketSize + 1] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // private flags |
- 0x00, |
- }; |
- // clang-format on |
- |
- const size_t header_size = GetPacketHeaderSize( |
- framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, |
- !kIncludePathId, !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER); |
- |
- memset(packet + header_size, 0, kMaxPacketSize - header_size); |
- |
- QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); |
- EXPECT_DFATAL(framer_.ProcessPacket(encrypted), "Packet too large:1"); |
- |
- ASSERT_TRUE(visitor_.header_.get()); |
- // Make sure we've parsed the packet header, so we can send an error. |
- EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id); |
- // Make sure the correct error is propagated. |
- EXPECT_EQ(QUIC_PACKET_TOO_LARGE, framer_.error()); |
-} |
- |
-TEST_P(QuicFramerTest, PacketHeader) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // private flags |
- 0x00, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_FALSE(framer_.ProcessPacket(encrypted)); |
- EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id); |
- EXPECT_FALSE(visitor_.header_->public_header.multipath_flag); |
- EXPECT_FALSE(visitor_.header_->public_header.reset_flag); |
- EXPECT_FALSE(visitor_.header_->public_header.version_flag); |
- EXPECT_FALSE(visitor_.header_->fec_flag); |
- EXPECT_FALSE(visitor_.header_->entropy_flag); |
- EXPECT_EQ(0, visitor_.header_->entropy_hash); |
- EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number); |
- |
- // Now test framing boundaries. |
- for (size_t i = 0; |
- i < GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER); |
- ++i) { |
- string expected_error; |
- if (i < kConnectionIdOffset) { |
- expected_error = "Unable to read public flags."; |
- } else if (i < GetPacketNumberOffset(!kIncludeVersion, !kIncludePathId)) { |
- expected_error = "Unable to read ConnectionId."; |
- } else { |
- if (framer_.version() <= QUIC_VERSION_33) { |
- if (i < GetPrivateFlagsOffset(!kIncludeVersion, !kIncludePathId)) { |
- expected_error = "Unable to read packet number."; |
- } else { |
- expected_error = "Unable to read private flags."; |
- } |
- } else { |
- expected_error = "Unable to read packet number."; |
- } |
- } |
- CheckProcessingFails( |
- framer_.version() <= QUIC_VERSION_33 ? packet : packet_34, i, |
- expected_error, QUIC_INVALID_PACKET_HEADER); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) { |
- QuicFramerPeer::SetLastSerializedConnectionId(&framer_, kConnectionId); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (0 byte connection_id) |
- 0x30, |
- // connection_id |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (0 byte connection_id) |
- 0x30, |
- // connection_id |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_FALSE(framer_.ProcessPacket(encrypted)); |
- EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id); |
- EXPECT_FALSE(visitor_.header_->public_header.multipath_flag); |
- EXPECT_FALSE(visitor_.header_->public_header.reset_flag); |
- EXPECT_FALSE(visitor_.header_->public_header.version_flag); |
- EXPECT_FALSE(visitor_.header_->fec_flag); |
- EXPECT_FALSE(visitor_.header_->entropy_flag); |
- EXPECT_EQ(0, visitor_.header_->entropy_hash); |
- EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number); |
- |
- // Now test framing boundaries. |
- for (size_t i = 0; |
- i < GetPacketHeaderSize(framer_.version(), PACKET_0BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER); |
- ++i) { |
- string expected_error; |
- if (i < kConnectionIdOffset) { |
- expected_error = "Unable to read public flags."; |
- } else if (i < GetPacketNumberOffset(PACKET_0BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId)) { |
- expected_error = "Unable to read ConnectionId."; |
- } else { |
- if (framer_.version() <= QUIC_VERSION_33) { |
- if (i < GetPrivateFlagsOffset(PACKET_0BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId)) { |
- expected_error = "Unable to read packet number."; |
- } else { |
- expected_error = "Unable to read private flags."; |
- } |
- } else { |
- expected_error = "Unable to read packet number."; |
- } |
- } |
- CheckProcessingFails( |
- framer_.version() <= QUIC_VERSION_33 ? packet : packet_34, i, |
- expected_error, QUIC_INVALID_PACKET_HEADER); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (version) |
- 0x39, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // version tag |
- 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(), |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // private flags |
- 0x00, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (version) |
- 0x39, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // version tag |
- 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(), |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_FALSE(framer_.ProcessPacket(encrypted)); |
- EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id); |
- EXPECT_FALSE(visitor_.header_->public_header.multipath_flag); |
- EXPECT_FALSE(visitor_.header_->public_header.reset_flag); |
- EXPECT_TRUE(visitor_.header_->public_header.version_flag); |
- EXPECT_EQ(GetParam(), visitor_.header_->public_header.versions[0]); |
- EXPECT_FALSE(visitor_.header_->fec_flag); |
- EXPECT_FALSE(visitor_.header_->entropy_flag); |
- EXPECT_EQ(0, visitor_.header_->entropy_hash); |
- EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number); |
- |
- // Now test framing boundaries. |
- for (size_t i = 0; |
- i < GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER); |
- ++i) { |
- string expected_error; |
- if (i < kConnectionIdOffset) { |
- expected_error = "Unable to read public flags."; |
- } else if (i < kVersionOffset) { |
- expected_error = "Unable to read ConnectionId."; |
- } else if (i < GetPacketNumberOffset(kIncludeVersion, !kIncludePathId)) { |
- expected_error = "Unable to read protocol version."; |
- } else { |
- if (framer_.version() <= QUIC_VERSION_33) { |
- if (i < GetPrivateFlagsOffset(kIncludeVersion, !kIncludePathId)) { |
- expected_error = "Unable to read packet number."; |
- } else { |
- expected_error = "Unable to read private flags."; |
- } |
- } else { |
- expected_error = "Unable to read packet number."; |
- } |
- } |
- CheckProcessingFails( |
- framer_.version() <= QUIC_VERSION_33 ? packet : packet_34, i, |
- expected_error, QUIC_INVALID_PACKET_HEADER); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, PacketHeaderWithMultipathFlag) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (version) |
- 0x78, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // path_id |
- 0x42, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // private flags |
- 0x00, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (version) |
- 0x78, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // path_id |
- 0x42, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_FALSE(framer_.ProcessPacket(encrypted)); |
- EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id); |
- EXPECT_TRUE(visitor_.header_->public_header.multipath_flag); |
- EXPECT_FALSE(visitor_.header_->public_header.reset_flag); |
- EXPECT_FALSE(visitor_.header_->public_header.version_flag); |
- EXPECT_FALSE(visitor_.header_->fec_flag); |
- EXPECT_FALSE(visitor_.header_->entropy_flag); |
- EXPECT_EQ(0, visitor_.header_->entropy_hash); |
- EXPECT_EQ(kPathId, visitor_.header_->path_id); |
- EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number); |
- |
- // Now test framing boundaries. |
- for (size_t i = 0; |
- i < GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER); |
- ++i) { |
- string expected_error; |
- if (i < kConnectionIdOffset) { |
- expected_error = "Unable to read public flags."; |
- } else if (i < |
- GetPathIdOffset(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion)) { |
- expected_error = "Unable to read ConnectionId."; |
- } else if (i < GetPacketNumberOffset(!kIncludeVersion, kIncludePathId)) { |
- expected_error = "Unable to read path id."; |
- } else { |
- if (framer_.version() <= QUIC_VERSION_33) { |
- if (i < GetPrivateFlagsOffset(!kIncludeVersion, kIncludePathId)) { |
- expected_error = "Unable to read packet number."; |
- } else { |
- expected_error = "Unable to read private flags."; |
- } |
- } else { |
- expected_error = "Unable to read packet number."; |
- } |
- } |
- CheckProcessingFails( |
- framer_.version() <= QUIC_VERSION_33 ? packet : packet_34, i, |
- expected_error, QUIC_INVALID_PACKET_HEADER); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, PacketHeaderWithBothVersionFlagAndMultipathFlag) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (version) |
- 0x79, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // version tag |
- 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(), |
- // path_id |
- 0x42, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // private flags |
- 0x00, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (version) |
- 0x79, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // version tag |
- 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(), |
- // path_id |
- 0x42, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_FALSE(framer_.ProcessPacket(encrypted)); |
- EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_TRUE(CheckDecryption(encrypted, kIncludeVersion, kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id); |
- EXPECT_TRUE(visitor_.header_->public_header.multipath_flag); |
- EXPECT_FALSE(visitor_.header_->public_header.reset_flag); |
- EXPECT_TRUE(visitor_.header_->public_header.version_flag); |
- EXPECT_EQ(GetParam(), visitor_.header_->public_header.versions[0]); |
- EXPECT_FALSE(visitor_.header_->fec_flag); |
- EXPECT_FALSE(visitor_.header_->entropy_flag); |
- EXPECT_EQ(0, visitor_.header_->entropy_hash); |
- EXPECT_EQ(kPathId, visitor_.header_->path_id); |
- EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number); |
- |
- // Now test framing boundaries. |
- for (size_t i = 0; |
- i < GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER); |
- ++i) { |
- string expected_error; |
- if (i < kConnectionIdOffset) { |
- expected_error = "Unable to read public flags."; |
- } else if (i < kVersionOffset) { |
- expected_error = "Unable to read ConnectionId."; |
- } else if (i < |
- GetPathIdOffset(PACKET_8BYTE_CONNECTION_ID, kIncludeVersion)) { |
- expected_error = "Unable to read protocol version."; |
- } else if (i < GetPacketNumberOffset(kIncludeVersion, kIncludePathId)) { |
- expected_error = "Unable to read path id."; |
- } else { |
- if (framer_.version() <= QUIC_VERSION_33) { |
- if (i < GetPrivateFlagsOffset(kIncludeVersion, kIncludePathId)) { |
- expected_error = "Unable to read packet number."; |
- } else { |
- expected_error = "Unable to read private flags."; |
- } |
- } else { |
- expected_error = "Unable to read packet number."; |
- } |
- } |
- CheckProcessingFails( |
- framer_.version() <= QUIC_VERSION_33 ? packet : packet_34, i, |
- expected_error, QUIC_INVALID_PACKET_HEADER); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, PacketHeaderWithPathChange) { |
- // Packet 1 from path 0x42. |
- // clang-format off |
- unsigned char packet1[] = { |
- // public flags (version) |
- 0x78, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // path_id |
- 0x42, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // private flags |
- 0x00, |
- }; |
- unsigned char packet1_34[] = { |
- // public flags (version) |
- 0x78, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // path_id |
- 0x42, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- }; |
- // clang-format on |
- |
- EXPECT_EQ(0u, QuicFramerPeer::GetLastPacketNumber(&framer_)); |
- EXPECT_EQ(kInvalidPathId, QuicFramerPeer::GetLastPathId(&framer_)); |
- QuicEncryptedPacket encrypted1( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet1 : packet1_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet1) |
- : arraysize(packet1_34), |
- false); |
- EXPECT_FALSE(framer_.ProcessPacket(encrypted1)); |
- EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id); |
- EXPECT_EQ(kPathId, visitor_.header_->path_id); |
- EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number); |
- EXPECT_EQ(kPacketNumber, QuicFramerPeer::GetLastPacketNumber(&framer_)); |
- EXPECT_EQ(kPathId, QuicFramerPeer::GetLastPathId(&framer_)); |
- |
- // Packet 2 from default path. |
- // clang-format off |
- unsigned char packet2[] = { |
- // public flags (version) |
- 0x78, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // path_id |
- 0x00, |
- // packet number |
- 0xCC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // private flags |
- 0x00, |
- }; |
- unsigned char packet2_34[] = { |
- // public flags (version) |
- 0x78, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // path_id |
- 0x00, |
- // packet number |
- 0xCC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted2( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet2 : packet2_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet2) |
- : arraysize(packet2_34), |
- false); |
- EXPECT_FALSE(framer_.ProcessPacket(encrypted2)); |
- EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id); |
- EXPECT_EQ(kDefaultPathId, visitor_.header_->path_id); |
- EXPECT_EQ(kPacketNumber + 16, visitor_.header_->packet_number); |
- EXPECT_EQ(kPacketNumber + 16, QuicFramerPeer::GetLastPacketNumber(&framer_)); |
- EXPECT_EQ(kDefaultPathId, QuicFramerPeer::GetLastPathId(&framer_)); |
- |
- // Packet 3 from path 0x42. |
- // clang-format off |
- unsigned char packet3[] = { |
- // public flags (version) |
- 0x78, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // path_id |
- 0x42, |
- // packet number |
- 0xBD, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // private flags |
- 0x00, |
- }; |
- unsigned char packet3_34[] = { |
- // public flags (version) |
- 0x78, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // path_id |
- 0x42, |
- // packet number |
- 0xBD, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted3( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet3 : packet3_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet3) |
- : arraysize(packet3_34), |
- false); |
- EXPECT_FALSE(framer_.ProcessPacket(encrypted3)); |
- EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id); |
- EXPECT_EQ(kPathId, visitor_.header_->path_id); |
- EXPECT_EQ(kPacketNumber + 1, visitor_.header_->packet_number); |
- EXPECT_EQ(kPacketNumber + 1, QuicFramerPeer::GetLastPacketNumber(&framer_)); |
- EXPECT_EQ(kPathId, QuicFramerPeer::GetLastPathId(&framer_)); |
-} |
- |
-TEST_P(QuicFramerTest, ReceivedPacketOnClosedPath) { |
- // Packet 1 from path 0x42. |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (version) |
- 0x78, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // path_id |
- 0x42, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // private flags |
- 0x00, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (version) |
- 0x78, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // path_id |
- 0x42, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // private flags |
- 0x00, |
- }; |
- // clang-format on |
- |
- framer_.OnPathClosed(kPathId); |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_FALSE(framer_.ProcessPacket(encrypted)); |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
- EXPECT_EQ(0u, QuicFramerPeer::GetLastPacketNumber(&framer_)); |
- EXPECT_EQ(kInvalidPathId, QuicFramerPeer::GetLastPathId(&framer_)); |
-} |
- |
-TEST_P(QuicFramerTest, PacketHeaderWith4BytePacketNumber) { |
- QuicFramerPeer::SetLastPacketNumber(&framer_, kPacketNumber - 2); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id and 4 byte packet number) |
- 0x28, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- // private flags |
- 0x00, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id and 4 byte packet number) |
- 0x28, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_FALSE(framer_.ProcessPacket(encrypted)); |
- EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id); |
- EXPECT_FALSE(visitor_.header_->public_header.multipath_flag); |
- EXPECT_FALSE(visitor_.header_->public_header.reset_flag); |
- EXPECT_FALSE(visitor_.header_->public_header.version_flag); |
- EXPECT_FALSE(visitor_.header_->fec_flag); |
- EXPECT_FALSE(visitor_.header_->entropy_flag); |
- EXPECT_EQ(0, visitor_.header_->entropy_hash); |
- EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number); |
- |
- // Now test framing boundaries. |
- for (size_t i = 0; |
- i < GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_4BYTE_PACKET_NUMBER); |
- ++i) { |
- string expected_error; |
- if (i < kConnectionIdOffset) { |
- expected_error = "Unable to read public flags."; |
- } else if (i < GetPacketNumberOffset(!kIncludeVersion, !kIncludePathId)) { |
- expected_error = "Unable to read ConnectionId."; |
- } else { |
- if (framer_.version() <= QUIC_VERSION_33) { |
- if (i < GetPrivateFlagsOffset(!kIncludeVersion, !kIncludePathId, |
- PACKET_4BYTE_PACKET_NUMBER)) { |
- expected_error = "Unable to read packet number."; |
- } else { |
- expected_error = "Unable to read private flags."; |
- } |
- } else { |
- expected_error = "Unable to read packet number."; |
- } |
- } |
- CheckProcessingFails( |
- framer_.version() <= QUIC_VERSION_33 ? packet : packet_34, i, |
- expected_error, QUIC_INVALID_PACKET_HEADER); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, PacketHeaderWith2BytePacketNumber) { |
- QuicFramerPeer::SetLastPacketNumber(&framer_, kPacketNumber - 2); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id and 2 byte packet number) |
- 0x18, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, |
- // private flags |
- 0x00, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id and 2 byte packet number) |
- 0x18, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_FALSE(framer_.ProcessPacket(encrypted)); |
- EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id); |
- EXPECT_FALSE(visitor_.header_->public_header.multipath_flag); |
- EXPECT_FALSE(visitor_.header_->public_header.reset_flag); |
- EXPECT_FALSE(visitor_.header_->public_header.version_flag); |
- EXPECT_FALSE(visitor_.header_->fec_flag); |
- EXPECT_FALSE(visitor_.header_->entropy_flag); |
- EXPECT_EQ(0, visitor_.header_->entropy_hash); |
- EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number); |
- |
- // Now test framing boundaries. |
- for (size_t i = 0; |
- i < GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_2BYTE_PACKET_NUMBER); |
- ++i) { |
- string expected_error; |
- if (i < kConnectionIdOffset) { |
- expected_error = "Unable to read public flags."; |
- } else if (i < GetPacketNumberOffset(!kIncludeVersion, !kIncludePathId)) { |
- expected_error = "Unable to read ConnectionId."; |
- } else { |
- if (framer_.version() <= QUIC_VERSION_33) { |
- if (i < GetPrivateFlagsOffset(!kIncludeVersion, !kIncludePathId, |
- PACKET_2BYTE_PACKET_NUMBER)) { |
- expected_error = "Unable to read packet number."; |
- } else { |
- expected_error = "Unable to read private flags."; |
- } |
- } else { |
- expected_error = "Unable to read packet number."; |
- } |
- } |
- CheckProcessingFails( |
- framer_.version() <= QUIC_VERSION_33 ? packet : packet_34, i, |
- expected_error, QUIC_INVALID_PACKET_HEADER); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, PacketHeaderWith1BytePacketNumber) { |
- QuicFramerPeer::SetLastPacketNumber(&framer_, kPacketNumber - 2); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id and 1 byte packet number) |
- 0x08, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, |
- // private flags |
- 0x00, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id and 1 byte packet number) |
- 0x08, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_FALSE(framer_.ProcessPacket(encrypted)); |
- EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id); |
- EXPECT_FALSE(visitor_.header_->public_header.multipath_flag); |
- EXPECT_FALSE(visitor_.header_->public_header.reset_flag); |
- EXPECT_FALSE(visitor_.header_->public_header.version_flag); |
- EXPECT_FALSE(visitor_.header_->fec_flag); |
- EXPECT_FALSE(visitor_.header_->entropy_flag); |
- EXPECT_EQ(0, visitor_.header_->entropy_hash); |
- EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number); |
- |
- // Now test framing boundaries. |
- for (size_t i = 0; |
- i < GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_1BYTE_PACKET_NUMBER); |
- ++i) { |
- string expected_error; |
- if (i < kConnectionIdOffset) { |
- expected_error = "Unable to read public flags."; |
- } else if (i < GetPacketNumberOffset(!kIncludeVersion, !kIncludePathId)) { |
- expected_error = "Unable to read ConnectionId."; |
- } else { |
- if (framer_.version() <= QUIC_VERSION_33) { |
- if (i < GetPrivateFlagsOffset(!kIncludeVersion, !kIncludePathId, |
- PACKET_1BYTE_PACKET_NUMBER)) { |
- expected_error = "Unable to read packet number."; |
- } else { |
- expected_error = "Unable to read private flags."; |
- } |
- } else { |
- expected_error = "Unable to read packet number."; |
- } |
- } |
- CheckProcessingFails( |
- framer_.version() <= QUIC_VERSION_33 ? packet : packet_34, i, |
- expected_error, QUIC_INVALID_PACKET_HEADER); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, InvalidPublicFlag) { |
- if (framer_.version() > QUIC_VERSION_33) { |
- return; |
- } |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags: all flags set but the public reset flag and version flag. |
- 0xF8, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (padding) |
- 0x00, |
- 0x00, 0x00, 0x00, 0x00 |
- }; |
- // clang-format on |
- |
- CheckProcessingFails(packet, 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, PacketWithDiversificationNonce) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags: includes nonce flag |
- 0x7C, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // nonce |
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, |
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (padding) |
- 0x00, |
- 0x00, 0x00, 0x00, 0x00 |
- }; |
- unsigned char packet_34[] = { |
- // public flags: includes nonce flag |
- 0x7C, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // nonce |
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, |
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- |
- // frame type (padding) |
- 0x00, |
- 0x00, 0x00, 0x00, 0x00 |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); |
- if (framer_.version() > QUIC_VERSION_32) { |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- ASSERT_TRUE(visitor_.public_header_->nonce != nullptr); |
- for (char i = 0; i < 32; ++i) { |
- EXPECT_EQ(i, (*visitor_.public_header_->nonce)[static_cast<int>(i)]); |
- } |
- } else if (framer_.version() < QUIC_VERSION_32) { |
- // Packet is successfully parsed by accident. |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- ASSERT_TRUE(visitor_.public_header_ != nullptr); |
- } else { |
- EXPECT_FALSE(framer_.ProcessPacket(encrypted)); |
- EXPECT_EQ(QUIC_INVALID_PACKET_HEADER, framer_.error()); |
- EXPECT_EQ("Illegal private flags value.", framer_.detailed_error()); |
- } |
-}; |
- |
-TEST_P(QuicFramerTest, InvalidPublicFlagWithMatchingVersions) { |
- if (framer_.version() > QUIC_VERSION_33) { |
- return; |
- } |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id and version flag and an unknown flag) |
- 0x8D, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // version tag |
- 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(), |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (padding) |
- 0x00, |
- 0x00, 0x00, 0x00, 0x00 |
- }; |
- // clang-format on |
- CheckProcessingFails(packet, arraysize(packet), "Illegal public flags value.", |
- QUIC_INVALID_PACKET_HEADER); |
-}; |
- |
-TEST_P(QuicFramerTest, LargePublicFlagWithMismatchedVersions) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id, version flag and an unknown flag) |
- 0x79, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // version tag |
- 'Q', '0', '0', '0', |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (padding frame) |
- 0x00, |
- 0x00, 0x00, 0x00, 0x00 |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id, version flag and an unknown flag) |
- 0x79, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // version tag |
- 'Q', '0', '0', '0', |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (padding frame) |
- 0x00, |
- 0x00, 0x00, 0x00, 0x00 |
- }; |
- // clang-format on |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_EQ(0, visitor_.frame_count_); |
- EXPECT_EQ(1, visitor_.version_mismatch_); |
-}; |
- |
-TEST_P(QuicFramerTest, InvalidPrivateFlag) { |
- if (framer_.version() > QUIC_VERSION_33) { |
- return; |
- } |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x10, |
- |
- // frame type (padding) |
- 0x00, |
- 0x00, 0x00, 0x00, 0x00 |
- }; |
- // clang-format on |
- CheckProcessingFails(packet, arraysize(packet), |
- "Illegal private flags value.", |
- QUIC_INVALID_PACKET_HEADER); |
-}; |
- |
-TEST_P(QuicFramerTest, InvalidFECGroupOffset) { |
- if (framer_.version() > QUIC_VERSION_33) { |
- return; |
- } |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0x01, 0x00, 0x00, 0x00, |
- 0x00, 0x00, |
- // private flags (fec group) |
- 0x02, |
- // first fec protected packet offset |
- 0x10 |
- }; |
- // clang-format on |
- if (framer_.version() > QUIC_VERSION_31) { |
- CheckProcessingFails(packet, arraysize(packet), |
- "Illegal private flags value.", |
- QUIC_INVALID_PACKET_HEADER); |
- } else { |
- CheckProcessingFails(packet, arraysize(packet), |
- "First fec protected packet offset must be less " |
- "than the packet number.", |
- QUIC_INVALID_PACKET_HEADER); |
- } |
-}; |
- |
-TEST_P(QuicFramerTest, PaddingFrame) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (padding frame) |
- 0x00, |
- // Ignored data (which in this case is a stream frame) |
- // frame type (stream frame with fin) |
- 0xFF, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- // data length |
- 0x0c, 0x00, |
- // data |
- 'h', 'e', 'l', 'l', |
- 'o', ' ', 'w', 'o', |
- 'r', 'l', 'd', '!', |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (padding frame) |
- 0x00, |
- // Ignored data (which in this case is a stream frame) |
- // frame type (stream frame with fin) |
- 0xFF, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- // data length |
- 0x0c, 0x00, |
- // data |
- 'h', 'e', 'l', 'l', |
- 'o', ' ', 'w', 'o', |
- 'r', 'l', 'd', '!', |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- ASSERT_EQ(0u, visitor_.stream_frames_.size()); |
- EXPECT_EQ(0u, visitor_.ack_frames_.size()); |
- // A packet with no frames is not acceptable. |
- CheckProcessingFails( |
- packet, GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER), |
- "Packet has no frames.", QUIC_MISSING_PAYLOAD); |
-} |
- |
-TEST_P(QuicFramerTest, StreamFrame) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (stream frame with fin) |
- 0xFF, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- // data length |
- 0x0c, 0x00, |
- // data |
- 'h', 'e', 'l', 'l', |
- 'o', ' ', 'w', 'o', |
- 'r', 'l', 'd', '!', |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (stream frame with fin) |
- 0xFF, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- // data length |
- 0x0c, 0x00, |
- // data |
- 'h', 'e', 'l', 'l', |
- 'o', ' ', 'w', 'o', |
- 'r', 'l', 'd', '!', |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- ASSERT_EQ(1u, visitor_.stream_frames_.size()); |
- EXPECT_EQ(0u, visitor_.ack_frames_.size()); |
- EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id); |
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin); |
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset); |
- CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]); |
- |
- // Now test framing boundaries. |
- CheckStreamFrameBoundaries( |
- framer_.version() <= QUIC_VERSION_33 ? packet : packet_34, |
- kQuicMaxStreamIdSize, !kIncludeVersion); |
-} |
- |
-TEST_P(QuicFramerTest, MissingDiversificationNonce) { |
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); |
- framer_.SetDecrypter(ENCRYPTION_NONE, new NullDecrypter()); |
- decrypter_ = new test::TestDecrypter(); |
- framer_.SetAlternativeDecrypter(ENCRYPTION_INITIAL, decrypter_, false); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (stream frame with fin) |
- 0xFF, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- // data length |
- 0x0c, 0x00, |
- // data |
- 'h', 'e', 'l', 'l', |
- 'o', ' ', 'w', 'o', |
- 'r', 'l', 'd', '!', |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (stream frame with fin) |
- 0xFF, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- // data length |
- 0x0c, 0x00, |
- // data |
- 'h', 'e', 'l', 'l', |
- 'o', ' ', 'w', 'o', |
- 'r', 'l', 'd', '!', |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- if (framer_.version() > QUIC_VERSION_32) { |
- EXPECT_FALSE(framer_.ProcessPacket(encrypted)); |
- EXPECT_EQ(QUIC_DECRYPTION_FAILURE, framer_.error()); |
- |
- } else { |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, StreamFrame3ByteStreamId) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (stream frame with fin) |
- 0xFE, |
- // stream id |
- 0x04, 0x03, 0x02, |
- // offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- // data length |
- 0x0c, 0x00, |
- // data |
- 'h', 'e', 'l', 'l', |
- 'o', ' ', 'w', 'o', |
- 'r', 'l', 'd', '!', |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (stream frame with fin) |
- 0xFE, |
- // stream id |
- 0x04, 0x03, 0x02, |
- // offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- // data length |
- 0x0c, 0x00, |
- // data |
- 'h', 'e', 'l', 'l', |
- 'o', ' ', 'w', 'o', |
- 'r', 'l', 'd', '!', |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- ASSERT_EQ(1u, visitor_.stream_frames_.size()); |
- EXPECT_EQ(0u, visitor_.ack_frames_.size()); |
- // Stream ID should be the last 3 bytes of kStreamId. |
- EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id); |
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin); |
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset); |
- CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]); |
- |
- // Now test framing boundaries. |
- const size_t stream_id_size = 3; |
- CheckStreamFrameBoundaries( |
- framer_.version() <= QUIC_VERSION_33 ? packet : packet_34, stream_id_size, |
- !kIncludeVersion); |
-} |
- |
-TEST_P(QuicFramerTest, StreamFrame2ByteStreamId) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (stream frame with fin) |
- 0xFD, |
- // stream id |
- 0x04, 0x03, |
- // offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- // data length |
- 0x0c, 0x00, |
- // data |
- 'h', 'e', 'l', 'l', |
- 'o', ' ', 'w', 'o', |
- 'r', 'l', 'd', '!', |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (stream frame with fin) |
- 0xFD, |
- // stream id |
- 0x04, 0x03, |
- // offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- // data length |
- 0x0c, 0x00, |
- // data |
- 'h', 'e', 'l', 'l', |
- 'o', ' ', 'w', 'o', |
- 'r', 'l', 'd', '!', |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- ASSERT_EQ(1u, visitor_.stream_frames_.size()); |
- EXPECT_EQ(0u, visitor_.ack_frames_.size()); |
- // Stream ID should be the last 2 bytes of kStreamId. |
- EXPECT_EQ(0x0000FFFF & kStreamId, visitor_.stream_frames_[0]->stream_id); |
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin); |
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset); |
- CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]); |
- |
- // Now test framing boundaries. |
- const size_t stream_id_size = 2; |
- CheckStreamFrameBoundaries( |
- framer_.version() <= QUIC_VERSION_33 ? packet : packet_34, stream_id_size, |
- !kIncludeVersion); |
-} |
- |
-TEST_P(QuicFramerTest, StreamFrame1ByteStreamId) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (stream frame with fin) |
- 0xFC, |
- // stream id |
- 0x04, |
- // offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- // data length |
- 0x0c, 0x00, |
- // data |
- 'h', 'e', 'l', 'l', |
- 'o', ' ', 'w', 'o', |
- 'r', 'l', 'd', '!', |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (stream frame with fin) |
- 0xFC, |
- // stream id |
- 0x04, |
- // offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- // data length |
- 0x0c, 0x00, |
- // data |
- 'h', 'e', 'l', 'l', |
- 'o', ' ', 'w', 'o', |
- 'r', 'l', 'd', '!', |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- ASSERT_EQ(1u, visitor_.stream_frames_.size()); |
- EXPECT_EQ(0u, visitor_.ack_frames_.size()); |
- // Stream ID should be the last byte of kStreamId. |
- EXPECT_EQ(0x000000FF & kStreamId, visitor_.stream_frames_[0]->stream_id); |
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin); |
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset); |
- CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]); |
- |
- // Now test framing boundaries. |
- const size_t stream_id_size = 1; |
- CheckStreamFrameBoundaries( |
- framer_.version() <= QUIC_VERSION_33 ? packet : packet_34, stream_id_size, |
- !kIncludeVersion); |
-} |
- |
-TEST_P(QuicFramerTest, StreamFrameWithVersion) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (version, 8 byte connection_id) |
- 0x39, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // version tag |
- 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(), |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (stream frame with fin) |
- 0xFF, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- // data length |
- 0x0c, 0x00, |
- // data |
- 'h', 'e', 'l', 'l', |
- 'o', ' ', 'w', 'o', |
- 'r', 'l', 'd', '!', |
- }; |
- unsigned char packet_34[] = { |
- // public flags (version, 8 byte connection_id) |
- 0x39, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // version tag |
- 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(), |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (stream frame with fin) |
- 0xFF, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- // data length |
- 0x0c, 0x00, |
- // data |
- 'h', 'e', 'l', 'l', |
- 'o', ' ', 'w', 'o', |
- 'r', 'l', 'd', '!', |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_TRUE(visitor_.header_->public_header.version_flag); |
- EXPECT_EQ(GetParam(), visitor_.header_->public_header.versions[0]); |
- EXPECT_TRUE(CheckDecryption(encrypted, kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- ASSERT_EQ(1u, visitor_.stream_frames_.size()); |
- EXPECT_EQ(0u, visitor_.ack_frames_.size()); |
- EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id); |
- EXPECT_TRUE(visitor_.stream_frames_[0]->fin); |
- EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset); |
- CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]); |
- |
- // Now test framing boundaries. |
- CheckStreamFrameBoundaries( |
- framer_.version() <= QUIC_VERSION_33 ? packet : packet_34, |
- kQuicMaxStreamIdSize, kIncludeVersion); |
-} |
- |
-TEST_P(QuicFramerTest, RejectPacket) { |
- visitor_.accept_packet_ = false; |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (stream frame with fin) |
- 0xFF, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- // data length |
- 0x0c, 0x00, |
- // data |
- 'h', 'e', 'l', 'l', |
- 'o', ' ', 'w', 'o', |
- 'r', 'l', 'd', '!', |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (stream frame with fin) |
- 0xFF, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- // data length |
- 0x0c, 0x00, |
- // data |
- 'h', 'e', 'l', 'l', |
- 'o', ' ', 'w', 'o', |
- 'r', 'l', 'd', '!', |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- ASSERT_EQ(0u, visitor_.stream_frames_.size()); |
- EXPECT_EQ(0u, visitor_.ack_frames_.size()); |
-} |
- |
-TEST_P(QuicFramerTest, RejectPublicHeader) { |
- visitor_.accept_public_header_ = false; |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
- ASSERT_TRUE(visitor_.public_header_.get()); |
- ASSERT_FALSE(visitor_.header_.get()); |
-} |
- |
-TEST_P(QuicFramerTest, AckFrameTwoTimestamp) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet 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 number |
- 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // Zero delta time. |
- 0x00, 0x00, |
- // 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, |
- }; |
- // clang-format on |
- |
- if (framer_.version() > QUIC_VERSION_31) { |
- return; |
- } |
- |
- 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, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- 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(kLargestObserved, frame.largest_observed); |
- ASSERT_EQ(1u, frame.packets.NumPacketsSlow()); |
- ASSERT_EQ(2u, frame.received_packet_times.size()); |
- EXPECT_EQ(kMissingPacket, frame.packets.Min()); |
- |
- const size_t kReceivedEntropyOffset = kQuicFrameTypeSize; |
- const size_t kLargestObservedOffset = |
- kReceivedEntropyOffset + kQuicEntropyHashSize; |
- const size_t kMissingDeltaTimeOffset = |
- kLargestObservedOffset + PACKET_6BYTE_PACKET_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_PACKET_NUMBER; |
- const size_t kRevivedPacketsLength = |
- kMissingPacketsRange + PACKET_1BYTE_PACKET_NUMBER; |
- // Now test framing boundaries. |
- const size_t ack_frame_size = |
- kRevivedPacketsLength + PACKET_1BYTE_PACKET_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 ack delay time."; |
- } 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 packet number delta."; |
- } else if (i < kRevivedPacketsLength) { |
- expected_error = "Unable to read missing packet number range."; |
- } else { |
- expected_error = "Unable to read num revived packets."; |
- } |
- CheckProcessingFails( |
- packet, |
- i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER), |
- expected_error, QUIC_INVALID_ACK_DATA); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, AckFrameTwoTimestampVersion32) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x3C, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet 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 number |
- 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // Zero delta time. |
- 0x00, 0x00, |
- // 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, |
- }; |
- // clang-format on |
- |
- if (framer_.version() <= QUIC_VERSION_31 || |
- framer_.version() > QUIC_VERSION_33) { |
- return; |
- } |
- |
- 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, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- 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(kLargestObserved, frame.largest_observed); |
- ASSERT_EQ(1u, frame.packets.NumPacketsSlow()); |
- ASSERT_EQ(2u, frame.received_packet_times.size()); |
- EXPECT_EQ(kMissingPacket, frame.packets.Min()); |
- |
- const size_t kReceivedEntropyOffset = kQuicFrameTypeSize; |
- const size_t kLargestObservedOffset = |
- kReceivedEntropyOffset + kQuicEntropyHashSize; |
- const size_t kMissingDeltaTimeOffset = |
- kLargestObservedOffset + PACKET_6BYTE_PACKET_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; |
- // Now test framing boundaries. |
- const size_t ack_frame_size = PACKET_1BYTE_PACKET_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 ack delay time."; |
- } 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 { |
- expected_error = "Unable to read missing packet number delta."; |
- } |
- CheckProcessingFails( |
- packet, |
- i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER), |
- expected_error, QUIC_INVALID_ACK_DATA); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, AckFrameOneTimestamp) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet 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 number |
- 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // Zero delta time. |
- 0x00, 0x00, |
- // 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, |
- }; |
- // clang-format on |
- |
- if (framer_.version() > QUIC_VERSION_31) { |
- return; |
- } |
- |
- 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, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- 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(kLargestObserved, frame.largest_observed); |
- ASSERT_EQ(1u, frame.packets.NumPacketsSlow()); |
- ASSERT_EQ(1u, frame.received_packet_times.size()); |
- EXPECT_EQ(kMissingPacket, frame.packets.Min()); |
- |
- const size_t kReceivedEntropyOffset = kQuicFrameTypeSize; |
- const size_t kLargestObservedOffset = |
- kReceivedEntropyOffset + kQuicEntropyHashSize; |
- const size_t kMissingDeltaTimeOffset = |
- kLargestObservedOffset + PACKET_6BYTE_PACKET_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_PACKET_NUMBER; |
- const size_t kRevivedPacketsLength = |
- kMissingPacketsRange + PACKET_1BYTE_PACKET_NUMBER; |
- // Now test framing boundaries. |
- const size_t ack_frame_size = |
- kRevivedPacketsLength + PACKET_1BYTE_PACKET_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 ack delay time."; |
- } 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 packet number delta."; |
- } else if (i < kRevivedPacketsLength) { |
- expected_error = "Unable to read missing packet number range."; |
- } else { |
- expected_error = "Unable to read num revived packets."; |
- } |
- CheckProcessingFails( |
- packet, |
- i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER), |
- expected_error, QUIC_INVALID_ACK_DATA); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, AckFrameOneTimestampVersion32) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x3C, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet 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 number |
- 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // Zero delta time. |
- 0x00, 0x00, |
- // 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, |
- }; |
- // clang-format on |
- |
- if (framer_.version() <= QUIC_VERSION_31 || |
- framer_.version() > QUIC_VERSION_33) { |
- return; |
- } |
- |
- 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, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- 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(kLargestObserved, frame.largest_observed); |
- ASSERT_EQ(1u, frame.packets.NumPacketsSlow()); |
- ASSERT_EQ(1u, frame.received_packet_times.size()); |
- EXPECT_EQ(kMissingPacket, frame.packets.Min()); |
- |
- const size_t kReceivedEntropyOffset = kQuicFrameTypeSize; |
- const size_t kLargestObservedOffset = |
- kReceivedEntropyOffset + kQuicEntropyHashSize; |
- const size_t kMissingDeltaTimeOffset = |
- kLargestObservedOffset + PACKET_6BYTE_PACKET_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; |
- // Now test framing boundaries. |
- const size_t ack_frame_size = PACKET_1BYTE_PACKET_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 ack delay time."; |
- } 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 { |
- expected_error = "Unable to read missing packet number delta."; |
- } |
- CheckProcessingFails( |
- packet, |
- i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER), |
- expected_error, QUIC_INVALID_ACK_DATA); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, AckFrame) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x3C, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet 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 number |
- 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // Zero delta time. |
- 0x00, 0x00, |
- // Number of timestamps. |
- 0x00, |
- // num missing packets |
- 0x01, |
- // missing packet delta |
- 0x01, |
- // 0 more missing packets in range. |
- 0x00, |
- // Number of revived packets. |
- 0x00, |
- }; |
- // clang-format on |
- |
- if (framer_.version() > QUIC_VERSION_31) { |
- return; |
- } |
- |
- 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, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- 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(kLargestObserved, frame.largest_observed); |
- ASSERT_EQ(1u, frame.packets.NumPacketsSlow()); |
- EXPECT_EQ(kMissingPacket, frame.packets.Min()); |
- |
- const size_t kReceivedEntropyOffset = kQuicFrameTypeSize; |
- const size_t kLargestObservedOffset = |
- kReceivedEntropyOffset + kQuicEntropyHashSize; |
- const size_t kMissingDeltaTimeOffset = |
- kLargestObservedOffset + PACKET_6BYTE_PACKET_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_PACKET_NUMBER; |
- const size_t kRevivedPacketsLength = |
- kMissingPacketsRange + PACKET_1BYTE_PACKET_NUMBER; |
- // Now test framing boundaries. |
- const size_t ack_frame_size = |
- kRevivedPacketsLength + PACKET_1BYTE_PACKET_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 ack delay time."; |
- } 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 packet number delta."; |
- } else if (i < kRevivedPacketsLength) { |
- expected_error = "Unable to read missing packet number range."; |
- } else { |
- expected_error = "Unable to read num revived packets."; |
- } |
- CheckProcessingFails( |
- packet, |
- i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER), |
- expected_error, QUIC_INVALID_ACK_DATA); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, NewAckFrameOneAckBlock) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x3C, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- |
- // frame type (ack frame) |
- // (one ack block, 2 byte largest observed, 2 byte block length) |
- 0x45, |
- // largest acked |
- 0x34, 0x12, |
- // Zero delta time. |
- 0x00, 0x00, |
- // first ack block length. |
- 0x34, 0x12, |
- // num timestamps. |
- 0x00, |
- }; |
- // clang-format on |
- |
- if (framer_.version() <= QUIC_VERSION_33) { |
- return; |
- } |
- |
- 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, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- EXPECT_EQ(0u, visitor_.stream_frames_.size()); |
- ASSERT_EQ(1u, visitor_.ack_frames_.size()); |
- const QuicAckFrame& frame = *visitor_.ack_frames_[0]; |
- EXPECT_EQ(kSmallLargestObserved, frame.largest_observed); |
- EXPECT_FALSE(frame.missing); |
- ASSERT_EQ(4660u, frame.packets.NumPacketsSlow()); |
- |
- const size_t kLargestAckedOffset = kQuicFrameTypeSize; |
- const size_t kLargestAckedDeltaTimeOffset = |
- kLargestAckedOffset + PACKET_2BYTE_PACKET_NUMBER; |
- const size_t kFirstAckBlockLengthOffset = |
- kLargestAckedDeltaTimeOffset + kQuicDeltaTimeLargestObservedSize; |
- const size_t kNumTimestampsOffset = |
- kFirstAckBlockLengthOffset + PACKET_2BYTE_PACKET_NUMBER; |
- // Now test framing boundaries. |
- const size_t ack_frame_size = |
- kFirstAckBlockLengthOffset + PACKET_2BYTE_PACKET_NUMBER; |
- for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) { |
- string expected_error; |
- if (i < kLargestAckedDeltaTimeOffset) { |
- expected_error = "Unable to read largest acked."; |
- } else if (i < kFirstAckBlockLengthOffset) { |
- expected_error = "Unable to read ack delay time."; |
- } else if (i < kNumTimestampsOffset) { |
- expected_error = "Unable to read first ack block length."; |
- } else { |
- expected_error = "Unable to read num received packets."; |
- } |
- CheckProcessingFails( |
- packet, |
- i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER), |
- expected_error, QUIC_INVALID_ACK_DATA); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, NewAckFrameTwoTimeStampsMultipleAckBlocks) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x3C, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- |
- // frame type (ack frame) |
- // (more than one ack block, 2 byte largest observed, 2 byte block length) |
- 0x65, |
- // largest acked |
- 0x34, 0x12, |
- // Zero delta time. |
- 0x00, 0x00, |
- // num ack blocks ranges. |
- 0x04, |
- // first ack block length. |
- 0x01, 0x00, |
- // gap to next block. |
- 0x01, |
- // ack block length. |
- 0xaf, 0x0e, |
- // gap to next block. |
- 0xff, |
- // ack block length. |
- 0x00, 0x00, |
- // gap to next block. |
- 0x91, |
- // ack block length. |
- 0xea, 0x01, |
- // gap to next block. |
- 0x05, |
- // ack block length. |
- 0x04, 0x00, |
- // Number of timestamps. |
- 0x02, |
- // Delta from largest observed. |
- 0x01, |
- // Delta time. |
- 0x10, 0x32, 0x54, 0x76, |
- // Delta from largest observed. |
- 0x02, |
- // Delta time. |
- 0x10, 0x32, |
- }; |
- // clang-format on |
- |
- if (framer_.version() <= QUIC_VERSION_33) { |
- return; |
- } |
- |
- 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, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- EXPECT_EQ(0u, visitor_.stream_frames_.size()); |
- ASSERT_EQ(1u, visitor_.ack_frames_.size()); |
- const QuicAckFrame& frame = *visitor_.ack_frames_[0]; |
- EXPECT_EQ(kSmallLargestObserved, frame.largest_observed); |
- EXPECT_FALSE(frame.missing); |
- ASSERT_EQ(4254u, frame.packets.NumPacketsSlow()); |
- |
- const size_t kLargestAckedOffset = kQuicFrameTypeSize; |
- const size_t kLargestAckedDeltaTimeOffset = |
- kLargestAckedOffset + PACKET_2BYTE_PACKET_NUMBER; |
- const size_t kNumberOfAckBlocksOffset = |
- kLargestAckedDeltaTimeOffset + kQuicDeltaTimeLargestObservedSize; |
- const size_t kFirstAckBlockLengthOffset = |
- kNumberOfAckBlocksOffset + kNumberOfAckBlocksSize; |
- const size_t kGapToNextBlockOffset1 = |
- kFirstAckBlockLengthOffset + PACKET_2BYTE_PACKET_NUMBER; |
- const size_t kAckBlockLengthOffset1 = kGapToNextBlockOffset1 + 1; |
- const size_t kGapToNextBlockOffset2 = |
- kAckBlockLengthOffset1 + PACKET_2BYTE_PACKET_NUMBER; |
- const size_t kAckBlockLengthOffset2 = kGapToNextBlockOffset2 + 1; |
- const size_t kGapToNextBlockOffset3 = |
- kAckBlockLengthOffset2 + PACKET_2BYTE_PACKET_NUMBER; |
- const size_t kAckBlockLengthOffset3 = kGapToNextBlockOffset3 + 1; |
- const size_t kGapToNextBlockOffset4 = |
- kAckBlockLengthOffset3 + PACKET_2BYTE_PACKET_NUMBER; |
- const size_t kAckBlockLengthOffset4 = kGapToNextBlockOffset3 + 1; |
- const size_t kNumTimestampsOffset = |
- kAckBlockLengthOffset4 + PACKET_2BYTE_PACKET_NUMBER; |
- const size_t kTimestampDeltaLargestObserved1 = |
- kNumTimestampsOffset + kQuicNumTimestampsSize; |
- const size_t kTimestampTimeDeltaLargestObserved1 = |
- kTimestampDeltaLargestObserved1 + 1; |
- const size_t kTimestampDeltaLargestObserved2 = |
- kTimestampTimeDeltaLargestObserved1 + 4; |
- const size_t kTimestampTimeDeltaLargestObserved2 = |
- kTimestampDeltaLargestObserved2 + 1; |
- |
- // Now test framing boundaries. |
- const size_t ack_frame_size = |
- kAckBlockLengthOffset4 + PACKET_2BYTE_PACKET_NUMBER; |
- for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) { |
- string expected_error; |
- if (i < kLargestAckedDeltaTimeOffset) { |
- expected_error = "Unable to read largest acked."; |
- } else if (i < kNumberOfAckBlocksOffset) { |
- expected_error = "Unable to read ack delay time."; |
- } else if (i < kFirstAckBlockLengthOffset) { |
- expected_error = "Unable to read num of ack blocks."; |
- } else if (i < kGapToNextBlockOffset1) { |
- expected_error = "Unable to read first ack block length."; |
- } else if (i < kAckBlockLengthOffset1) { |
- expected_error = "Unable to read gap to next ack block."; |
- } else if (i < kGapToNextBlockOffset2) { |
- expected_error = "Unable to ack block length."; |
- } else if (i < kAckBlockLengthOffset2) { |
- expected_error = "Unable to read gap to next ack block."; |
- } else if (i < kGapToNextBlockOffset3) { |
- expected_error = "Unable to ack block length."; |
- } else if (i < kAckBlockLengthOffset3) { |
- expected_error = "Unable to read gap to next ack block."; |
- } else if (i < kGapToNextBlockOffset4) { |
- expected_error = "Unable to ack block length."; |
- } else if (i < kAckBlockLengthOffset4) { |
- expected_error = "Unable to read gap to next ack block."; |
- } else if (i < kNumTimestampsOffset) { |
- expected_error = "Unable to ack block length."; |
- } 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 { |
- expected_error = |
- "Unable to read incremental time delta in received packets."; |
- } |
- |
- CheckProcessingFails( |
- packet, |
- i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER), |
- expected_error, QUIC_INVALID_ACK_DATA); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, AckFrameVersion32) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet 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 number |
- 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // Zero delta time. |
- 0x00, 0x00, |
- // Number of timestamps. |
- 0x00, |
- // num missing packets |
- 0x01, |
- // missing packet delta |
- 0x01, |
- // 0 more missing packets in range. |
- 0x00, |
- }; |
- // clang-format on |
- |
- if (framer_.version() <= QUIC_VERSION_31 || |
- framer_.version() > QUIC_VERSION_33) { |
- return; |
- } |
- |
- 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, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- 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(kLargestObserved, frame.largest_observed); |
- ASSERT_EQ(1u, frame.packets.NumPacketsSlow()); |
- EXPECT_EQ(kMissingPacket, frame.packets.Min()); |
- |
- const size_t kReceivedEntropyOffset = kQuicFrameTypeSize; |
- const size_t kLargestObservedOffset = |
- kReceivedEntropyOffset + kQuicEntropyHashSize; |
- const size_t kMissingDeltaTimeOffset = |
- kLargestObservedOffset + PACKET_6BYTE_PACKET_NUMBER; |
- const size_t kNumTimestampsOffset = |
- kMissingDeltaTimeOffset + kQuicDeltaTimeLargestObservedSize; |
- const size_t kNumMissingPacketOffset = |
- kNumTimestampsOffset + kQuicNumTimestampsSize; |
- const size_t kMissingPacketsOffset = |
- kNumMissingPacketOffset + kNumberOfNackRangesSize; |
- // Now test framing boundaries. |
- const size_t ack_frame_size = PACKET_1BYTE_PACKET_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 ack delay time."; |
- } 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 { |
- expected_error = "Unable to read missing packet number delta."; |
- } |
- CheckProcessingFails( |
- packet, |
- i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER), |
- expected_error, QUIC_INVALID_ACK_DATA); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, AckFrameRevivedPackets) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet 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 number |
- 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // Zero delta time. |
- 0x00, 0x00, |
- // num received packets. |
- 0x00, |
- // num missing packets |
- 0x01, |
- // missing packet delta |
- 0x01, |
- // 0 more missing packets in range. |
- 0x00, |
- // Number of revived packets. |
- 0x01, |
- // Revived packet number. |
- 0xBE, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // Number of revived packets. |
- 0x00, |
- }; |
- // clang-format on |
- |
- if (framer_.version() > QUIC_VERSION_31) { |
- return; |
- } |
- |
- 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, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- 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(kLargestObserved, frame.largest_observed); |
- ASSERT_EQ(1u, frame.packets.NumPacketsSlow()); |
- EXPECT_EQ(kMissingPacket, frame.packets.Min()); |
- |
- const size_t kReceivedEntropyOffset = kQuicFrameTypeSize; |
- const size_t kLargestObservedOffset = |
- kReceivedEntropyOffset + kQuicEntropyHashSize; |
- const size_t kMissingDeltaTimeOffset = |
- kLargestObservedOffset + PACKET_6BYTE_PACKET_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_PACKET_NUMBER; |
- const size_t kRevivedPacketsLength = |
- kMissingPacketsRange + PACKET_1BYTE_PACKET_NUMBER; |
- const size_t kRevivedPacketSequenceNumberLength = |
- kRevivedPacketsLength + PACKET_1BYTE_PACKET_NUMBER; |
- // Now test framing boundaries. |
- const size_t ack_frame_size = |
- kRevivedPacketSequenceNumberLength + PACKET_6BYTE_PACKET_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 < kNumTimestampsOffset) { |
- expected_error = "Unable to read ack delay time."; |
- } 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 packet number delta."; |
- } else if (i < kRevivedPacketsLength) { |
- expected_error = "Unable to read missing packet 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(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER), |
- expected_error, QUIC_INVALID_ACK_DATA); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, AckFrameNoNacks) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet 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 number |
- 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // Zero delta time. |
- 0x00, 0x00, |
- // Number of received packets. |
- 0x00, |
- }; |
- // clang-format on |
- if (framer_.version() >= QUIC_VERSION_31) { |
- return; |
- } |
- |
- 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, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- 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(kLargestObserved, frame->largest_observed); |
- ASSERT_TRUE(frame->packets.Empty()); |
- |
- // Verify that the packet re-serializes identically. |
- QuicFrames frames; |
- frames.push_back(QuicFrame(frame)); |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(*visitor_.header_, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError("constructed packet", data->data(), |
- data->length(), AsChars(packet), |
- arraysize(packet)); |
-} |
- |
-TEST_P(QuicFramerTest, AckFrame500Nacks) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet 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 number |
- 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // Zero delta time. |
- 0x00, 0x00, |
- // No received packets. |
- 0x00, |
- // 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, |
- }; |
- // clang-format on |
- |
- if (framer_.version() > QUIC_VERSION_31) { |
- return; |
- } |
- |
- 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, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- 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(kLargestObserved, frame->largest_observed); |
- ASSERT_EQ(500u, frame->packets.NumPacketsSlow()); |
- EXPECT_EQ(kMissingPacket - 499, frame->packets.Min()); |
- EXPECT_EQ(kMissingPacket, frame->packets.Max()); |
- |
- // Verify that the packet re-serializes identically. |
- QuicFrames frames; |
- frames.push_back(QuicFrame(frame)); |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(*visitor_.header_, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError("constructed packet", data->data(), |
- data->length(), AsChars(packet), |
- arraysize(packet)); |
-} |
- |
-TEST_P(QuicFramerTest, AckFrame500NacksVersion32) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet 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 number |
- 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // Zero delta time. |
- 0x00, 0x00, |
- // No received packets. |
- 0x00, |
- // 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, |
- }; |
- // clang-format on |
- |
- if (framer_.version() <= QUIC_VERSION_31 || |
- framer_.version() > QUIC_VERSION_33) { |
- return; |
- } |
- |
- 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, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- 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(kLargestObserved, frame->largest_observed); |
- ASSERT_EQ(500u, frame->packets.NumPacketsSlow()); |
- EXPECT_EQ(kMissingPacket - 499, frame->packets.Min()); |
- EXPECT_EQ(kMissingPacket, frame->packets.Max()); |
- |
- // Verify that the packet re-serializes identically. |
- QuicFrames frames; |
- frames.push_back(QuicFrame(frame)); |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(*visitor_.header_, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError("constructed packet", data->data(), |
- data->length(), AsChars(packet), |
- arraysize(packet)); |
-} |
- |
-TEST_P(QuicFramerTest, StopWaitingFrame) { |
- if (framer_.version() > QUIC_VERSION_33) { |
- return; |
- } |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet 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 number awaiting an ack, delta from packet number. |
- 0x08, 0x00, 0x00, 0x00, |
- 0x00, 0x00, |
- }; |
- // clang-format on |
- |
- 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, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- 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(kLeastUnacked, 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(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER), |
- expected_error, QUIC_INVALID_STOP_WAITING_DATA); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, NewStopWaitingFrame) { |
- if (framer_.version() <= QUIC_VERSION_33) { |
- return; |
- } |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x3C, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xA8, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // frame type (stop waiting frame) |
- 0x06, |
- // least packet number awaiting an ack, delta from packet number. |
- 0x08, 0x00, 0x00, 0x00, |
- 0x00, 0x00, |
- }; |
- // clang-format on |
- |
- 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, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- 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(kLeastUnacked, frame.least_unacked); |
- |
- const size_t frame_size = 7; |
- for (size_t i = kQuicFrameTypeSize; i < frame_size; ++i) { |
- string expected_error; |
- expected_error = "Unable to read least unacked delta."; |
- CheckProcessingFails( |
- packet, |
- i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER), |
- expected_error, QUIC_INVALID_STOP_WAITING_DATA); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, RstStreamFrameQuic) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (rst stream frame) |
- 0x01, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- |
- // sent byte offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- |
- // error code |
- 0x01, 0x00, 0x00, 0x00, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (rst stream frame) |
- 0x01, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- |
- // sent byte offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- |
- // error code |
- 0x01, 0x00, 0x00, 0x00, |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- EXPECT_EQ(kStreamId, visitor_.rst_stream_frame_.stream_id); |
- EXPECT_EQ(0x01, visitor_.rst_stream_frame_.error_code); |
- EXPECT_EQ(kStreamOffset, visitor_.rst_stream_frame_.byte_offset); |
- |
- // Now test framing boundaries. |
- for (size_t i = kQuicFrameTypeSize; i < QuicFramer::GetRstStreamFrameSize(); |
- ++i) { |
- string expected_error; |
- if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize) { |
- expected_error = "Unable to read stream_id."; |
- } else if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize + |
- kQuicMaxStreamOffsetSize) { |
- expected_error = "Unable to read rst stream sent byte offset."; |
- } else if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize + |
- kQuicMaxStreamOffsetSize + kQuicErrorCodeSize) { |
- expected_error = "Unable to read rst stream error code."; |
- } |
- CheckProcessingFails( |
- framer_.version() <= QUIC_VERSION_33 ? packet : packet_34, |
- i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER), |
- expected_error, QUIC_INVALID_RST_STREAM_DATA); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, ConnectionCloseFrame) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (connection close frame) |
- 0x02, |
- // error code |
- 0x11, 0x00, 0x00, 0x00, |
- |
- // error details length |
- 0x0d, 0x00, |
- // error details |
- 'b', 'e', 'c', 'a', |
- 'u', 's', 'e', ' ', |
- 'I', ' ', 'c', 'a', |
- 'n', |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (connection close frame) |
- 0x02, |
- // error code |
- 0x11, 0x00, 0x00, 0x00, |
- |
- // error details length |
- 0x0d, 0x00, |
- // error details |
- 'b', 'e', 'c', 'a', |
- 'u', 's', 'e', ' ', |
- 'I', ' ', 'c', 'a', |
- 'n', |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- EXPECT_EQ(0u, visitor_.stream_frames_.size()); |
- |
- EXPECT_EQ(0x11, visitor_.connection_close_frame_.error_code); |
- EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details); |
- |
- ASSERT_EQ(0u, visitor_.ack_frames_.size()); |
- |
- // Now test framing boundaries. |
- for (size_t i = kQuicFrameTypeSize; |
- i < QuicFramer::GetMinConnectionCloseFrameSize(); ++i) { |
- string expected_error; |
- if (i < kQuicFrameTypeSize + kQuicErrorCodeSize) { |
- expected_error = "Unable to read connection close error code."; |
- } else { |
- expected_error = "Unable to read connection close error details."; |
- } |
- CheckProcessingFails( |
- framer_.version() <= QUIC_VERSION_33 ? packet : packet_34, |
- i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER), |
- expected_error, QUIC_INVALID_CONNECTION_CLOSE_DATA); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, GoAwayFrame) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (go away frame) |
- 0x03, |
- // error code |
- 0x09, 0x00, 0x00, 0x00, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // error details length |
- 0x0d, 0x00, |
- // error details |
- 'b', 'e', 'c', 'a', |
- 'u', 's', 'e', ' ', |
- 'I', ' ', 'c', 'a', |
- 'n', |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (go away frame) |
- 0x03, |
- // error code |
- 0x09, 0x00, 0x00, 0x00, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // error details length |
- 0x0d, 0x00, |
- // error details |
- 'b', 'e', 'c', 'a', |
- 'u', 's', 'e', ' ', |
- 'I', ' ', 'c', 'a', |
- 'n', |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- EXPECT_EQ(kStreamId, visitor_.goaway_frame_.last_good_stream_id); |
- EXPECT_EQ(0x9, visitor_.goaway_frame_.error_code); |
- EXPECT_EQ("because I can", visitor_.goaway_frame_.reason_phrase); |
- |
- const size_t reason_size = arraysize("because I can") - 1; |
- // Now test framing boundaries. |
- for (size_t i = kQuicFrameTypeSize; |
- i < QuicFramer::GetMinGoAwayFrameSize() + reason_size; ++i) { |
- string expected_error; |
- if (i < kQuicFrameTypeSize + kQuicErrorCodeSize) { |
- expected_error = "Unable to read go away error code."; |
- } else if (i < |
- kQuicFrameTypeSize + kQuicErrorCodeSize + kQuicMaxStreamIdSize) { |
- expected_error = "Unable to read last good stream id."; |
- } else { |
- expected_error = "Unable to read goaway reason."; |
- } |
- CheckProcessingFails( |
- framer_.version() <= QUIC_VERSION_33 ? packet : packet_34, |
- i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER), |
- expected_error, QUIC_INVALID_GOAWAY_DATA); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, WindowUpdateFrame) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (window update frame) |
- 0x04, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // byte offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (window update frame) |
- 0x04, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // byte offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- EXPECT_EQ(kStreamId, visitor_.window_update_frame_.stream_id); |
- EXPECT_EQ(kStreamOffset, visitor_.window_update_frame_.byte_offset); |
- |
- // Now test framing boundaries. |
- for (size_t i = kQuicFrameTypeSize; |
- i < QuicFramer::GetWindowUpdateFrameSize(); ++i) { |
- string expected_error; |
- if (i < kQuicFrameTypeSize + kQuicMaxStreamIdSize) { |
- expected_error = "Unable to read stream_id."; |
- } else { |
- expected_error = "Unable to read window byte_offset."; |
- } |
- CheckProcessingFails( |
- framer_.version() <= QUIC_VERSION_33 ? packet : packet_34, |
- i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER), |
- expected_error, QUIC_INVALID_WINDOW_UPDATE_DATA); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, BlockedFrame) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (blocked frame) |
- 0x05, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (blocked frame) |
- 0x05, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- EXPECT_EQ(kStreamId, visitor_.blocked_frame_.stream_id); |
- |
- // Now test framing boundaries. |
- for (size_t i = kQuicFrameTypeSize; i < QuicFramer::GetBlockedFrameSize(); |
- ++i) { |
- string expected_error = "Unable to read stream_id."; |
- CheckProcessingFails( |
- framer_.version() <= QUIC_VERSION_33 ? packet : packet_34, |
- i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER), |
- expected_error, QUIC_INVALID_BLOCKED_DATA); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, PingFrame) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (ping frame) |
- 0x07, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (ping frame) |
- 0x07, |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce)); |
- |
- EXPECT_EQ(1u, visitor_.ping_frames_.size()); |
- |
- // No need to check the PING frame boundaries because it has no payload. |
-} |
- |
-TEST_P(QuicFramerTest, PathCloseFrame) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (version) |
- 0x78, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // path_id |
- 0x00, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (path_close_frame) |
- 0x08, |
- // path id |
- 0x42, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (version) |
- 0x78, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // path_id |
- 0x00, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- |
- // frame type (path_close_frame) |
- 0x08, |
- // path id |
- 0x42, |
- }; |
- // clang-format on |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
- ASSERT_TRUE(visitor_.header_.get()); |
- // TODO(fayang): CheckDecryption after cl/110553865 is landed. |
- EXPECT_EQ(kPathId, visitor_.path_close_frame_.path_id); |
- |
- // Now test framing boundaries. |
- for (size_t i = kQuicFrameTypeSize; i < QuicFramer::GetPathCloseFrameSize(); |
- ++i) { |
- string expected_error; |
- if (i < kQuicFrameTypeSize + kQuicPathIdSize) { |
- expected_error = "Unable to read path_id."; |
- } |
- CheckProcessingFails( |
- framer_.version() <= QUIC_VERSION_33 ? packet : packet_34, |
- i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, |
- !kIncludeVersion, kIncludePathId, |
- !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER), |
- expected_error, QUIC_INVALID_PATH_CLOSE_DATA); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, PublicResetPacketV33) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (public reset, 8 byte connection_id) |
- 0x0A, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // message tag (kPRST) |
- 'P', 'R', 'S', 'T', |
- // num_entries (2) + padding |
- 0x02, 0x00, 0x00, 0x00, |
- // tag kRNON |
- 'R', 'N', 'O', 'N', |
- // end offset 8 |
- 0x08, 0x00, 0x00, 0x00, |
- // tag kRSEQ |
- 'R', 'S', 'E', 'Q', |
- // end offset 16 |
- 0x10, 0x00, 0x00, 0x00, |
- // nonce proof |
- 0x89, 0x67, 0x45, 0x23, |
- 0x01, 0xEF, 0xCD, 0xAB, |
- // rejected packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, 0x00, 0x00, |
- }; |
- // clang-format on |
- |
- 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(kConnectionId, |
- 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(kNonceProof, visitor_.public_reset_packet_->nonce_proof); |
- EXPECT_EQ(0u, visitor_.public_reset_packet_->rejected_packet_number); |
- EXPECT_EQ(ADDRESS_FAMILY_UNSPECIFIED, |
- visitor_.public_reset_packet_->client_address.GetFamily()); |
- |
- // 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 < kPublicResetPacketMessageTagOffset) { |
- expected_error = "Unable to read ConnectionId."; |
- CheckProcessingFails(packet, i, expected_error, |
- QUIC_INVALID_PACKET_HEADER); |
- } else { |
- expected_error = "Unable to read reset message."; |
- CheckProcessingFails(packet, i, expected_error, |
- QUIC_INVALID_PUBLIC_RST_PACKET); |
- } |
- } |
-} |
- |
-TEST_P(QuicFramerTest, PublicResetPacket) { |
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (public reset, 8 byte connection_id) |
- 0x0E, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // message tag (kPRST) |
- 'P', 'R', 'S', 'T', |
- // num_entries (2) + padding |
- 0x02, 0x00, 0x00, 0x00, |
- // tag kRNON |
- 'R', 'N', 'O', 'N', |
- // end offset 8 |
- 0x08, 0x00, 0x00, 0x00, |
- // tag kRSEQ |
- 'R', 'S', 'E', 'Q', |
- // end offset 16 |
- 0x10, 0x00, 0x00, 0x00, |
- // nonce proof |
- 0x89, 0x67, 0x45, 0x23, |
- 0x01, 0xEF, 0xCD, 0xAB, |
- // rejected packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, 0x00, 0x00, |
- }; |
- // clang-format on |
- |
- 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(kConnectionId, |
- 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(kNonceProof, visitor_.public_reset_packet_->nonce_proof); |
- EXPECT_EQ(0u, visitor_.public_reset_packet_->rejected_packet_number); |
- EXPECT_EQ(ADDRESS_FAMILY_UNSPECIFIED, |
- visitor_.public_reset_packet_->client_address.GetFamily()); |
- |
- // 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 < kPublicResetPacketMessageTagOffset) { |
- expected_error = "Unable to read ConnectionId."; |
- CheckProcessingFails(packet, i, expected_error, |
- QUIC_INVALID_PACKET_HEADER); |
- } else { |
- expected_error = "Unable to read reset message."; |
- CheckProcessingFails(packet, i, expected_error, |
- QUIC_INVALID_PUBLIC_RST_PACKET); |
- } |
- } |
-} |
- |
-TEST_P(QuicFramerTest, PublicResetPacketWithTrailingJunk) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (public reset, 8 byte connection_id) |
- 0x0A, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // message tag (kPRST) |
- 'P', 'R', 'S', 'T', |
- // num_entries (2) + padding |
- 0x02, 0x00, 0x00, 0x00, |
- // tag kRNON |
- 'R', 'N', 'O', 'N', |
- // end offset 8 |
- 0x08, 0x00, 0x00, 0x00, |
- // tag kRSEQ |
- 'R', 'S', 'E', 'Q', |
- // end offset 16 |
- 0x10, 0x00, 0x00, 0x00, |
- // nonce proof |
- 0x89, 0x67, 0x45, 0x23, |
- 0x01, 0xEF, 0xCD, 0xAB, |
- // rejected packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, 0x00, 0x00, |
- // trailing junk |
- 'j', 'u', 'n', 'k', |
- }; |
- // clang-format on |
- |
- string expected_error = "Unable to read reset message."; |
- CheckProcessingFails(packet, arraysize(packet), expected_error, |
- QUIC_INVALID_PUBLIC_RST_PACKET); |
-} |
- |
-TEST_P(QuicFramerTest, PublicResetPacketWithClientAddress) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (public reset, 8 byte connection_id) |
- 0x0A, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // message tag (kPRST) |
- 'P', 'R', 'S', 'T', |
- // num_entries (3) + padding |
- 0x03, 0x00, 0x00, 0x00, |
- // tag kRNON |
- 'R', 'N', 'O', 'N', |
- // end offset 8 |
- 0x08, 0x00, 0x00, 0x00, |
- // tag kRSEQ |
- 'R', 'S', 'E', 'Q', |
- // end offset 16 |
- 0x10, 0x00, 0x00, 0x00, |
- // tag kCADR |
- 'C', 'A', 'D', 'R', |
- // end offset 24 |
- 0x18, 0x00, 0x00, 0x00, |
- // nonce proof |
- 0x89, 0x67, 0x45, 0x23, |
- 0x01, 0xEF, 0xCD, 0xAB, |
- // rejected packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, 0x00, 0x00, |
- // client address: 4.31.198.44:443 |
- 0x02, 0x00, |
- 0x04, 0x1F, 0xC6, 0x2C, |
- 0xBB, 0x01, |
- }; |
- // clang-format on |
- |
- 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(kConnectionId, |
- 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(kNonceProof, visitor_.public_reset_packet_->nonce_proof); |
- EXPECT_EQ(0u, visitor_.public_reset_packet_->rejected_packet_number); |
- EXPECT_EQ("4.31.198.44", |
- visitor_.public_reset_packet_->client_address.address().ToString()); |
- EXPECT_EQ(443, visitor_.public_reset_packet_->client_address.port()); |
- |
- // 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 < kPublicResetPacketMessageTagOffset) { |
- expected_error = "Unable to read ConnectionId."; |
- CheckProcessingFails(packet, i, expected_error, |
- QUIC_INVALID_PACKET_HEADER); |
- } else { |
- expected_error = "Unable to read reset message."; |
- CheckProcessingFails(packet, i, expected_error, |
- QUIC_INVALID_PUBLIC_RST_PACKET); |
- } |
- } |
-} |
- |
-TEST_P(QuicFramerTest, VersionNegotiationPacket) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (version, 8 byte connection_id) |
- 0x39, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // version tag |
- 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(), |
- 'Q', '2', '.', '0', |
- }; |
- // clang-format on |
- |
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); |
- |
- QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- ASSERT_EQ(QUIC_NO_ERROR, framer_.error()); |
- ASSERT_TRUE(visitor_.version_negotiation_packet_.get()); |
- EXPECT_EQ(2u, visitor_.version_negotiation_packet_->versions.size()); |
- EXPECT_EQ(GetParam(), visitor_.version_negotiation_packet_->versions[0]); |
- |
- for (size_t i = 0; i <= kPublicFlagsSize + PACKET_8BYTE_CONNECTION_ID; ++i) { |
- string expected_error; |
- QuicErrorCode error_code = QUIC_INVALID_PACKET_HEADER; |
- if (i < kConnectionIdOffset) { |
- expected_error = "Unable to read public flags."; |
- } else if (i < kVersionOffset) { |
- expected_error = "Unable to read ConnectionId."; |
- } else { |
- expected_error = "Unable to read supported version in negotiation."; |
- error_code = QUIC_INVALID_VERSION_NEGOTIATION_PACKET; |
- } |
- CheckProcessingFails(packet, i, expected_error, error_code); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, OldVersionNegotiationPacket) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (version, 8 byte connection_id) |
- 0x3D, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // version tag |
- 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(), |
- 'Q', '2', '.', '0', |
- }; |
- // clang-format on |
- |
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); |
- |
- QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- ASSERT_EQ(QUIC_NO_ERROR, framer_.error()); |
- ASSERT_TRUE(visitor_.version_negotiation_packet_.get()); |
- EXPECT_EQ(2u, visitor_.version_negotiation_packet_->versions.size()); |
- EXPECT_EQ(GetParam(), visitor_.version_negotiation_packet_->versions[0]); |
- |
- for (size_t i = 0; i <= kPublicFlagsSize + PACKET_8BYTE_CONNECTION_ID; ++i) { |
- string expected_error; |
- QuicErrorCode error_code = QUIC_INVALID_PACKET_HEADER; |
- if (i < kConnectionIdOffset) { |
- expected_error = "Unable to read public flags."; |
- } else if (i < kVersionOffset) { |
- expected_error = "Unable to read ConnectionId."; |
- } else { |
- expected_error = "Unable to read supported version in negotiation."; |
- error_code = QUIC_INVALID_VERSION_NEGOTIATION_PACKET; |
- } |
- CheckProcessingFails(packet, i, expected_error, error_code); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, DropFecPacket) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags (fec group & FEC) |
- 0x06, |
- // first fec protected packet offset |
- 0x01, |
- |
- // redundancy |
- 'a', 'b', 'c', 'd', |
- 'e', 'f', 'g', 'h', |
- 'i', 'j', 'k', 'l', |
- 'm', 'n', 'o', 'p', |
- }; |
- if (framer_.version() > QUIC_VERSION_33) { |
- return; |
- } |
- QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); |
- if (framer_.version() <= QUIC_VERSION_31) { |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
- } else { |
- EXPECT_FALSE(framer_.ProcessPacket(encrypted)); |
- EXPECT_EQ(QUIC_INVALID_PACKET_HEADER, framer_.error()); |
- } |
- EXPECT_FALSE(visitor_.header_.get()); |
-} |
- |
-TEST_P(QuicFramerTest, BuildPaddingFramePacket) { |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = false; |
- header.packet_number = kPacketNumber; |
- |
- QuicPaddingFrame padding_frame; |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(padding_frame)); |
- |
- // clang-format off |
- unsigned char packet[kMaxPacketSize] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (padding frame) |
- 0x00, |
- 0x00, 0x00, 0x00, 0x00 |
- }; |
- unsigned char packet_34[kMaxPacketSize] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (padding frame) |
- 0x00, |
- 0x00, 0x00, 0x00, 0x00 |
- }; |
- // clang-format on |
- |
- uint64_t header_size = GetPacketHeaderSize( |
- framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, |
- !kIncludePathId, !kIncludeDiversificationNonce, |
- PACKET_6BYTE_PACKET_NUMBER); |
- memset((framer_.version() <= QUIC_VERSION_33 ? packet : packet_34) + |
- header_size + 1, |
- 0x00, kMaxPacketSize - header_size - 1); |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError( |
- "constructed packet", data->data(), data->length(), |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34)); |
-} |
- |
-TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) { |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = false; |
- header.public_header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER; |
- header.packet_number = kPacketNumber; |
- |
- QuicPaddingFrame padding_frame; |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(padding_frame)); |
- |
- // clang-format off |
- unsigned char packet[kMaxPacketSize] = { |
- // public flags (8 byte connection_id and 4 byte packet number) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x28 : 0x2C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- // private flags |
- 0x00, |
- |
- // frame type (padding frame) |
- 0x00, |
- 0x00, 0x00, 0x00, 0x00 |
- }; |
- unsigned char packet_34[kMaxPacketSize] = { |
- // public flags (8 byte connection_id and 4 byte packet number) |
- 0x28, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- |
- // frame type (padding frame) |
- 0x00, |
- 0x00, 0x00, 0x00, 0x00 |
- }; |
- // clang-format on |
- |
- uint64_t header_size = GetPacketHeaderSize( |
- framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, |
- !kIncludePathId, !kIncludeDiversificationNonce, |
- PACKET_4BYTE_PACKET_NUMBER); |
- memset((framer_.version() <= QUIC_VERSION_33 ? packet : packet_34) + |
- header_size + 1, |
- 0x00, kMaxPacketSize - header_size - 1); |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError( |
- "constructed packet", data->data(), data->length(), |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34)); |
-} |
- |
-TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) { |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = false; |
- header.public_header.packet_number_length = PACKET_2BYTE_PACKET_NUMBER; |
- header.packet_number = kPacketNumber; |
- |
- QuicPaddingFrame padding_frame; |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(padding_frame)); |
- |
- // clang-format off |
- unsigned char packet[kMaxPacketSize] = { |
- // public flags (8 byte connection_id and 2 byte packet number) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x18 : 0x1C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, |
- // private flags |
- 0x00, |
- |
- // frame type (padding frame) |
- 0x00, |
- 0x00, 0x00, 0x00, 0x00 |
- }; |
- unsigned char packet_34[kMaxPacketSize] = { |
- // public flags (8 byte connection_id and 2 byte packet number) |
- 0x18, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, |
- |
- // frame type (padding frame) |
- 0x00, |
- 0x00, 0x00, 0x00, 0x00 |
- }; |
- // clang-format on |
- |
- uint64_t header_size = GetPacketHeaderSize( |
- framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, |
- !kIncludePathId, !kIncludeDiversificationNonce, |
- PACKET_2BYTE_PACKET_NUMBER); |
- memset((framer_.version() <= QUIC_VERSION_33 ? packet : packet_34) + |
- header_size + 1, |
- 0x00, kMaxPacketSize - header_size - 1); |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError( |
- "constructed packet", data->data(), data->length(), |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34)); |
-} |
- |
-TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) { |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = false; |
- header.public_header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER; |
- header.packet_number = kPacketNumber; |
- |
- QuicPaddingFrame padding_frame; |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(padding_frame)); |
- |
- // clang-format off |
- unsigned char packet[kMaxPacketSize] = { |
- // public flags (8 byte connection_id and 1 byte packet number) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x08 : 0x0C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, |
- // private flags |
- 0x00, |
- |
- // frame type (padding frame) |
- 0x00, |
- 0x00, 0x00, 0x00, 0x00 |
- }; |
- unsigned char packet_34[kMaxPacketSize] = { |
- // public flags (8 byte connection_id and 1 byte packet number) |
- 0x08, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, |
- |
- // frame type (padding frame) |
- 0x00, |
- 0x00, 0x00, 0x00, 0x00 |
- }; |
- // clang-format on |
- |
- uint64_t header_size = GetPacketHeaderSize( |
- framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, |
- !kIncludePathId, !kIncludeDiversificationNonce, |
- PACKET_1BYTE_PACKET_NUMBER); |
- memset((framer_.version() <= QUIC_VERSION_33 ? packet : packet_34) + |
- header_size + 1, |
- 0x00, kMaxPacketSize - header_size - 1); |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError( |
- "constructed packet", data->data(), data->length(), |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildStreamFramePacket) { |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = true; |
- header.packet_number = kPacketNumber; |
- |
- QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset, |
- StringPiece("hello world!")); |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(&stream_frame)); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags (entropy) |
- 0x01, |
- |
- // 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', '!', |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // 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', '!', |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError( |
- "constructed packet", data->data(), data->length(), |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) { |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = true; |
- header.fec_flag = false; |
- header.entropy_flag = true; |
- header.packet_number = kPacketNumber; |
- |
- QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset, |
- StringPiece("hello world!")); |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(&stream_frame)); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (version, 8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x3D : 0x3D), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // version tag |
- 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(), |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // private flags (entropy) |
- 0x01, |
- |
- // 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', '!', |
- }; |
- unsigned char packet_34[] = { |
- // 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 number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- |
- // 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', '!', |
- }; |
- // clang-format on |
- |
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError( |
- "constructed packet", data->data(), data->length(), |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildStreamFramePacketWithMultipathFlag) { |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.multipath_flag = true; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = true; |
- header.path_id = kPathId; |
- header.packet_number = kPacketNumber; |
- |
- QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset, |
- StringPiece("hello world!")); |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(&stream_frame)); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x78 : 0x7C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // path_id |
- 0x42, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags (entropy) |
- 0x01, |
- |
- // 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', '!', |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x78, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // path_id |
- 0x42, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // 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', '!', |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError( |
- "constructed packet", data->data(), data->length(), |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildStreamFramePacketWithBothVersionAndMultipathFlag) { |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.multipath_flag = true; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = true; |
- header.fec_flag = false; |
- header.entropy_flag = true; |
- header.path_id = kPathId; |
- header.packet_number = kPacketNumber; |
- |
- QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset, |
- StringPiece("hello world!")); |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(&stream_frame)); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x7D : 0x7D), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // version tag |
- 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(), |
- // path_id |
- 0x42, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags (entropy) |
- 0x01, |
- |
- // 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', '!', |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x7D, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // version tag |
- 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(), |
- // path_id |
- 0x42, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // 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', '!', |
- }; |
- // clang-format on |
- |
- QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError( |
- "constructed packet", data->data(), data->length(), |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) { |
- // clang-format off |
- 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(), |
- }; |
- // clang-format on |
- |
- QuicConnectionId connection_id = kConnectionId; |
- std::unique_ptr<QuicEncryptedPacket> data( |
- framer_.BuildVersionNegotiationPacket(connection_id, |
- SupportedVersions(GetParam()))); |
- test::CompareCharArraysWithHexError("constructed packet", data->data(), |
- data->length(), AsChars(packet), |
- arraysize(packet)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildAckFramePacket) { |
- if (framer_.version() > QUIC_VERSION_33) { |
- return; |
- } |
- |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = true; |
- header.packet_number = kPacketNumber; |
- |
- QuicAckFrame ack_frame; |
- ack_frame.entropy_hash = 0x43; |
- ack_frame.largest_observed = kLargestObserved; |
- ack_frame.ack_delay_time = QuicTime::Delta::Zero(); |
- ack_frame.packets.Add(kMissingPacket); |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(&ack_frame)); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x3C, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 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 number |
- 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // Zero delta time. |
- 0x00, 0x00, |
- // num received packets. |
- 0x00, |
- // num missing packet ranges |
- 0x01, |
- // missing packet delta |
- 0x01, |
- // 0 more missing packets in range. |
- 0x00, |
- // 0 revived packets. |
- 0x00, |
- }; |
- // clang-format on |
- |
- // clang-format off |
- unsigned char packet_version32[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 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 number |
- 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // Zero delta time. |
- 0x00, 0x00, |
- // num received packets. |
- 0x00, |
- // num missing packet ranges |
- 0x01, |
- // missing packet delta |
- 0x01, |
- // 0 more missing packets in range. |
- 0x00, |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- if (framer_.version() <= QUIC_VERSION_31) { |
- test::CompareCharArraysWithHexError("constructed packet", data->data(), |
- data->length(), AsChars(packet), |
- arraysize(packet)); |
- } else { |
- test::CompareCharArraysWithHexError( |
- "constructed packet", data->data(), data->length(), |
- AsChars(packet_version32), arraysize(packet_version32)); |
- } |
-} |
- |
-// 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, BuildTruncatedAckFrameLargePacket) { |
- if (framer_.version() > QUIC_VERSION_33) { |
- return; |
- } |
- |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = true; |
- header.packet_number = kPacketNumber; |
- |
- 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.ack_delay_time = QuicTime::Delta::Zero(); |
- for (size_t i = 1; i < 2 * 300; i += 2) { |
- ack_frame.packets.Add(i); |
- } |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(&ack_frame)); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x3C, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 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 number. |
- // Expected to be 510 (0x1FE), since only 255 nack ranges can fit. |
- 0xFE, 0x01, |
- // Zero delta time. |
- 0x00, 0x00, |
- // 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, |
- }; |
- // clang-format on |
- |
- // clang-format off |
- unsigned char packet_version32[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 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 number. |
- // Expected to be 510 (0x1FE), since only 255 nack ranges can fit. |
- 0xFE, 0x01, |
- // Zero delta time. |
- 0x00, 0x00, |
- // 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, |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- if (framer_.version() <= QUIC_VERSION_31) { |
- test::CompareCharArraysWithHexError("constructed packet", data->data(), |
- data->length(), AsChars(packet), |
- arraysize(packet)); |
- } else { |
- test::CompareCharArraysWithHexError( |
- "constructed packet", data->data(), data->length(), |
- AsChars(packet_version32), arraysize(packet_version32)); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, BuildTruncatedAckFrameSmallPacket) { |
- if (framer_.version() > QUIC_VERSION_33) { |
- return; |
- } |
- |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = true; |
- header.packet_number = kPacketNumber; |
- |
- 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.ack_delay_time = QuicTime::Delta::Zero(); |
- for (size_t i = 1; i < 2 * 300; i += 2) { |
- ack_frame.packets.Add(i); |
- } |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(&ack_frame)); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x3C, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 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 number. |
- // Expected to be 12 (0x0C), since only 6 nack ranges can fit. |
- 0x0C, 0x00, |
- // Zero delta time. |
- 0x00, 0x00, |
- // 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, |
- }; |
- // clang-format on |
- |
- // clang-format off |
- unsigned char packet_version32[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 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 number. |
- // Expected to be 12 (0x0C), since only 6 nack ranges can fit. |
- 0x0C, 0x00, |
- // Zero delta time. |
- 0x00, 0x00, |
- // 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, |
- }; |
- // clang-format on |
- |
- if (framer_.version() <= QUIC_VERSION_31) { |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames, 37u)); |
- ASSERT_TRUE(data != nullptr); |
- // 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)); |
- } else { |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames, 36u)); |
- ASSERT_TRUE(data != nullptr); |
- // Expect 1 byte unused since at least 2 bytes are needed to fit more nacks. |
- EXPECT_EQ(35u, data->length()); |
- test::CompareCharArraysWithHexError( |
- "constructed packet", data->data(), data->length(), |
- AsChars(packet_version32), arraysize(packet_version32)); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, BuildNewAckFramePacketOneAckBlock) { |
- if (framer_.version() <= QUIC_VERSION_33) { |
- return; |
- } |
- |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.packet_number = kPacketNumber; |
- |
- // Use kSmallLargestObserved to make this test finished in a short time. |
- QuicAckFrame ack_frame; |
- ack_frame.largest_observed = kSmallLargestObserved; |
- ack_frame.ack_delay_time = QuicTime::Delta::Zero(); |
- ack_frame.missing = false; |
- ack_frame.packets.Add(1, kSmallLargestObserved + 1); |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(&ack_frame)); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- |
- // frame type (ack frame) |
- // (no ack blocks, 2 byte largest observed, 2 byte block length) |
- 0x45, |
- // largest acked |
- 0x34, 0x12, |
- // Zero delta time. |
- 0x00, 0x00, |
- // first ack block length. |
- 0x34, 0x12, |
- // num timestamps. |
- 0x00, |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError("constructed packet", data->data(), |
- data->length(), AsChars(packet), |
- arraysize(packet)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildNewAckFramePacketMultipleAckBlocks) { |
- if (framer_.version() <= QUIC_VERSION_33) { |
- return; |
- } |
- |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.packet_number = kPacketNumber; |
- |
- // Use kSmallLargestObserved to make this test finished in a short time. |
- QuicAckFrame ack_frame; |
- ack_frame.largest_observed = kSmallLargestObserved; |
- ack_frame.ack_delay_time = QuicTime::Delta::Zero(); |
- ack_frame.missing = false; |
- ack_frame.packets.Add(1, 5); |
- ack_frame.packets.Add(10, 500); |
- ack_frame.packets.Add(900, kSmallMissingPacket); |
- ack_frame.packets.Add(kSmallMissingPacket + 1, kSmallLargestObserved + 1); |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(&ack_frame)); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- |
- // frame type (ack frame) |
- // (has ack blocks, 2 byte largest observed, 2 byte block length) |
- 0x65, |
- // largest acked |
- 0x34, 0x12, |
- // Zero delta time. |
- 0x00, 0x00, |
- // num ack blocks ranges. |
- 0x04, |
- // first ack block length. |
- 0x01, 0x00, |
- // gap to next block. |
- 0x01, |
- // ack block length. |
- 0xaf, 0x0e, |
- // gap to next block. |
- 0xff, |
- // ack block length. |
- 0x00, 0x00, |
- // gap to next block. |
- 0x91, |
- // ack block length. |
- 0xea, 0x01, |
- // gap to next block. |
- 0x05, |
- // ack block length. |
- 0x04, 0x00, |
- // num timestamps. |
- 0x00, |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError("constructed packet", data->data(), |
- data->length(), AsChars(packet), |
- arraysize(packet)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildNewAckFramePacketMaxAckBlocks) { |
- if (framer_.version() <= QUIC_VERSION_33) { |
- return; |
- } |
- |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.packet_number = kPacketNumber; |
- |
- // Use kSmallLargestObservedto make this test finished in a short time. |
- QuicAckFrame ack_frame; |
- ack_frame.largest_observed = kSmallLargestObserved; |
- ack_frame.ack_delay_time = QuicTime::Delta::Zero(); |
- ack_frame.missing = false; |
- // 300 ack blocks. |
- for (size_t i = 2; i < 2 * 300; i += 2) { |
- ack_frame.packets.Add(i); |
- } |
- ack_frame.packets.Add(600, kSmallLargestObserved + 1); |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(&ack_frame)); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // frame type (ack frame) |
- // (has ack blocks, 2 byte largest observed, 2 byte block length) |
- 0x65, |
- // largest acked |
- 0x34, 0x12, |
- // Zero delta time. |
- 0x00, 0x00, |
- // num ack blocks ranges. |
- 0xff, |
- // first ack block length. |
- 0xdd, 0x0f, |
- // 255 = 4 * 63 + 3 |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, |
- // num timestamps. |
- 0x00, |
- }; |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError("constructed packet", data->data(), |
- data->length(), AsChars(packet), |
- arraysize(packet)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildStopWaitingPacket) { |
- if (framer_.version() > QUIC_VERSION_33) { |
- return; |
- } |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = true; |
- header.packet_number = kPacketNumber; |
- |
- QuicStopWaitingFrame stop_waiting_frame; |
- stop_waiting_frame.entropy_hash = 0x14; |
- stop_waiting_frame.least_unacked = kLeastUnacked; |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(&stop_waiting_frame)); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 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 number awaiting an ack, delta from packet number. |
- 0x1C, 0x00, 0x00, 0x00, |
- 0x00, 0x00, |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError("constructed packet", data->data(), |
- data->length(), AsChars(packet), |
- arraysize(packet)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildNewStopWaitingPacket) { |
- if (framer_.version() <= QUIC_VERSION_33) { |
- return; |
- } |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = false; |
- header.packet_number = kPacketNumber; |
- |
- QuicStopWaitingFrame stop_waiting_frame; |
- stop_waiting_frame.least_unacked = kLeastUnacked; |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(&stop_waiting_frame)); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- |
- // frame type (stop waiting frame) |
- 0x06, |
- // least packet number awaiting an ack, delta from packet number. |
- 0x1C, 0x00, 0x00, 0x00, |
- 0x00, 0x00, |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError("constructed packet", data->data(), |
- data->length(), AsChars(packet), |
- arraysize(packet)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildRstFramePacketQuic) { |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = false; |
- header.packet_number = kPacketNumber; |
- |
- QuicRstStreamFrame rst_frame; |
- rst_frame.stream_id = kStreamId; |
- rst_frame.error_code = static_cast<QuicRstStreamErrorCode>(0x05060708); |
- rst_frame.byte_offset = 0x0807060504030201; |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (rst stream frame) |
- 0x01, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // sent byte offset |
- 0x01, 0x02, 0x03, 0x04, |
- 0x05, 0x06, 0x07, 0x08, |
- // error code |
- 0x08, 0x07, 0x06, 0x05, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (rst stream frame) |
- 0x01, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // sent byte offset |
- 0x01, 0x02, 0x03, 0x04, |
- 0x05, 0x06, 0x07, 0x08, |
- // error code |
- 0x08, 0x07, 0x06, 0x05, |
- }; |
- // clang-format on |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(&rst_frame)); |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError( |
- "constructed packet", data->data(), data->length(), |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildCloseFramePacket) { |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = true; |
- header.packet_number = kPacketNumber; |
- |
- QuicConnectionCloseFrame close_frame; |
- close_frame.error_code = static_cast<QuicErrorCode>(0x05060708); |
- close_frame.error_details = "because I can"; |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(&close_frame)); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags (entropy) |
- 0x01, |
- |
- // frame type (connection close frame) |
- 0x02, |
- // error code |
- 0x08, 0x07, 0x06, 0x05, |
- // error details length |
- 0x0d, 0x00, |
- // error details |
- 'b', 'e', 'c', 'a', |
- 'u', 's', 'e', ' ', |
- 'I', ' ', 'c', 'a', |
- 'n', |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (connection close frame) |
- 0x02, |
- // error code |
- 0x08, 0x07, 0x06, 0x05, |
- // error details length |
- 0x0d, 0x00, |
- // error details |
- 'b', 'e', 'c', 'a', |
- 'u', 's', 'e', ' ', |
- 'I', ' ', 'c', 'a', |
- 'n', |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError( |
- "constructed packet", data->data(), data->length(), |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildGoAwayPacket) { |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = true; |
- header.packet_number = kPacketNumber; |
- |
- QuicGoAwayFrame goaway_frame; |
- goaway_frame.error_code = static_cast<QuicErrorCode>(0x05060708); |
- goaway_frame.last_good_stream_id = kStreamId; |
- goaway_frame.reason_phrase = "because I can"; |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(&goaway_frame)); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags(entropy) |
- 0x01, |
- |
- // frame type (go away frame) |
- 0x03, |
- // error code |
- 0x08, 0x07, 0x06, 0x05, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // error details length |
- 0x0d, 0x00, |
- // error details |
- 'b', 'e', 'c', 'a', |
- 'u', 's', 'e', ' ', |
- 'I', ' ', 'c', 'a', |
- 'n', |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (go away frame) |
- 0x03, |
- // error code |
- 0x08, 0x07, 0x06, 0x05, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // error details length |
- 0x0d, 0x00, |
- // error details |
- 'b', 'e', 'c', 'a', |
- 'u', 's', 'e', ' ', |
- 'I', ' ', 'c', 'a', |
- 'n', |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError( |
- "constructed packet", data->data(), data->length(), |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildWindowUpdatePacket) { |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = true; |
- header.packet_number = kPacketNumber; |
- |
- QuicWindowUpdateFrame window_update_frame; |
- window_update_frame.stream_id = kStreamId; |
- window_update_frame.byte_offset = 0x1122334455667788; |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(&window_update_frame)); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags(entropy) |
- 0x01, |
- |
- // frame type (window update frame) |
- 0x04, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // byte offset |
- 0x88, 0x77, 0x66, 0x55, |
- 0x44, 0x33, 0x22, 0x11, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (window update frame) |
- 0x04, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // byte offset |
- 0x88, 0x77, 0x66, 0x55, |
- 0x44, 0x33, 0x22, 0x11, |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError( |
- "constructed packet", data->data(), data->length(), |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildBlockedPacket) { |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = true; |
- header.packet_number = kPacketNumber; |
- |
- QuicBlockedFrame blocked_frame; |
- blocked_frame.stream_id = kStreamId; |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(&blocked_frame)); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags(entropy) |
- 0x01, |
- |
- // frame type (blocked frame) |
- 0x05, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- 0x38, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (blocked frame) |
- 0x05, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError( |
- "constructed packet", data->data(), data->length(), |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildPingPacket) { |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = true; |
- header.packet_number = kPacketNumber; |
- |
- QuicPingFrame ping_frame; |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(ping_frame)); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags(entropy) |
- 0x01, |
- |
- // frame type (ping frame) |
- 0x07, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (ping frame) |
- 0x07, |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError( |
- "constructed packet", data->data(), data->length(), |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildPathClosePacket) { |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.multipath_flag = true; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = true; |
- header.path_id = kDefaultPathId; |
- header.packet_number = kPacketNumber; |
- |
- QuicPathCloseFrame path_close; |
- path_close.path_id = kPathId; |
- QuicFrames frames; |
- frames.push_back(QuicFrame(&path_close)); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (version) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x78 : 0X7C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // path_id |
- 0x00, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- // private flags (entropy) |
- 0x01, |
- |
- // frame type (path_close_frame) |
- 0x08, |
- // path id |
- 0x42, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (version) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x78 : 0X7C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, |
- // path_id |
- 0x00, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, |
- |
- // frame type (path_close_frame) |
- 0x08, |
- // path id |
- 0x42, |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError( |
- "constructed packet", data->data(), data->length(), |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34)); |
-} |
- |
-// Test that the MTU discovery packet is serialized correctly as a PING packet. |
-TEST_P(QuicFramerTest, BuildMtuDiscoveryPacket) { |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = true; |
- header.packet_number = kPacketNumber; |
- |
- QuicMtuDiscoveryFrame mtu_discovery_frame; |
- |
- QuicFrames frames; |
- frames.push_back(QuicFrame(mtu_discovery_frame)); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags(entropy) |
- 0x01, |
- |
- // frame type (ping frame) |
- 0x07, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (ping frame) |
- 0x07, |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError( |
- "constructed packet", data->data(), data->length(), |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildPublicResetPacketOld) { |
- FLAGS_quic_use_old_public_reset_packets = true; |
- QuicPublicResetPacket reset_packet; |
- reset_packet.public_header.connection_id = kConnectionId; |
- reset_packet.public_header.reset_flag = true; |
- reset_packet.public_header.version_flag = false; |
- reset_packet.rejected_packet_number = kPacketNumber; |
- reset_packet.nonce_proof = kNonceProof; |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (public reset, 8 byte ConnectionId) |
- 0x0E, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // message tag (kPRST) |
- 'P', 'R', 'S', 'T', |
- // num_entries (2) + padding |
- 0x02, 0x00, 0x00, 0x00, |
- // tag kRNON |
- 'R', 'N', 'O', 'N', |
- // end offset 8 |
- 0x08, 0x00, 0x00, 0x00, |
- // tag kRSEQ |
- 'R', 'S', 'E', 'Q', |
- // end offset 16 |
- 0x10, 0x00, 0x00, 0x00, |
- // nonce proof |
- 0x89, 0x67, 0x45, 0x23, |
- 0x01, 0xEF, 0xCD, 0xAB, |
- // rejected packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, 0x00, 0x00, |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicEncryptedPacket> data( |
- framer_.BuildPublicResetPacket(reset_packet)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError("constructed packet", data->data(), |
- data->length(), AsChars(packet), |
- arraysize(packet)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildPublicResetPacket) { |
- FLAGS_quic_use_old_public_reset_packets = false; |
- QuicPublicResetPacket reset_packet; |
- reset_packet.public_header.connection_id = kConnectionId; |
- reset_packet.public_header.reset_flag = true; |
- reset_packet.public_header.version_flag = false; |
- reset_packet.rejected_packet_number = kPacketNumber; |
- reset_packet.nonce_proof = kNonceProof; |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (public reset, 8 byte ConnectionId) |
- 0x0A, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // message tag (kPRST) |
- 'P', 'R', 'S', 'T', |
- // num_entries (2) + padding |
- 0x02, 0x00, 0x00, 0x00, |
- // tag kRNON |
- 'R', 'N', 'O', 'N', |
- // end offset 8 |
- 0x08, 0x00, 0x00, 0x00, |
- // tag kRSEQ |
- 'R', 'S', 'E', 'Q', |
- // end offset 16 |
- 0x10, 0x00, 0x00, 0x00, |
- // nonce proof |
- 0x89, 0x67, 0x45, 0x23, |
- 0x01, 0xEF, 0xCD, 0xAB, |
- // rejected packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, 0x00, 0x00, |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicEncryptedPacket> data( |
- framer_.BuildPublicResetPacket(reset_packet)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError("constructed packet", data->data(), |
- data->length(), AsChars(packet), |
- arraysize(packet)); |
-} |
- |
-TEST_P(QuicFramerTest, BuildPublicResetPacketWithClientAddress) { |
- FLAGS_quic_use_old_public_reset_packets = false; |
- QuicPublicResetPacket reset_packet; |
- reset_packet.public_header.connection_id = kConnectionId; |
- reset_packet.public_header.reset_flag = true; |
- reset_packet.public_header.version_flag = false; |
- reset_packet.rejected_packet_number = kPacketNumber; |
- reset_packet.nonce_proof = kNonceProof; |
- reset_packet.client_address = IPEndPoint(Loopback4(), 0x1234); |
- |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (public reset, 8 byte ConnectionId) |
- 0x0A, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // message tag (kPRST) |
- 'P', 'R', 'S', 'T', |
- // num_entries (3) + padding |
- 0x03, 0x00, 0x00, 0x00, |
- // tag kRNON |
- 'R', 'N', 'O', 'N', |
- // end offset 8 |
- 0x08, 0x00, 0x00, 0x00, |
- // tag kRSEQ |
- 'R', 'S', 'E', 'Q', |
- // end offset 16 |
- 0x10, 0x00, 0x00, 0x00, |
- // tag kCADR |
- 'C', 'A', 'D', 'R', |
- // end offset 24 |
- 0x18, 0x00, 0x00, 0x00, |
- // nonce proof |
- 0x89, 0x67, 0x45, 0x23, |
- 0x01, 0xEF, 0xCD, 0xAB, |
- // rejected packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, 0x00, 0x00, |
- // client address |
- 0x02, 0x00, |
- 0x7F, 0x00, 0x00, 0x01, |
- 0x34, 0x12, |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicEncryptedPacket> data( |
- framer_.BuildPublicResetPacket(reset_packet)); |
- ASSERT_TRUE(data != nullptr); |
- |
- test::CompareCharArraysWithHexError("constructed packet", data->data(), |
- data->length(), AsChars(packet), |
- arraysize(packet)); |
-} |
- |
-TEST_P(QuicFramerTest, EncryptPacket) { |
- QuicPacketNumber packet_number = kPacketNumber; |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // redundancy |
- 'a', 'b', 'c', 'd', |
- 'e', 'f', 'g', 'h', |
- 'i', 'j', 'k', 'l', |
- 'm', 'n', 'o', 'p', |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // redundancy |
- 'a', 'b', 'c', 'd', |
- 'e', 'f', 'g', 'h', |
- 'i', 'j', 'k', 'l', |
- 'm', 'n', 'o', 'p', |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicPacket> raw(new QuicPacket( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false, PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER)); |
- char buffer[kMaxPacketSize]; |
- size_t encrypted_length = |
- framer_.EncryptPayload(ENCRYPTION_NONE, kDefaultPathId, packet_number, |
- *raw, buffer, kMaxPacketSize); |
- |
- ASSERT_NE(0u, encrypted_length); |
- EXPECT_TRUE(CheckEncryption(kDefaultPathId, packet_number, raw.get())); |
-} |
- |
-TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) { |
- QuicPacketNumber packet_number = kPacketNumber; |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (version, 8 byte connection_id) |
- 0x39, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // version tag |
- 'Q', '.', '1', '0', |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // redundancy |
- 'a', 'b', 'c', 'd', |
- 'e', 'f', 'g', 'h', |
- 'i', 'j', 'k', 'l', |
- 'm', 'n', 'o', 'p', |
- }; |
- unsigned char packet_34[] = { |
- // public flags (version, 8 byte connection_id) |
- 0x39, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // version tag |
- 'Q', '.', '1', '0', |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // redundancy |
- 'a', 'b', 'c', 'd', |
- 'e', 'f', 'g', 'h', |
- 'i', 'j', 'k', 'l', |
- 'm', 'n', 'o', 'p', |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicPacket> raw(new QuicPacket( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false, PACKET_8BYTE_CONNECTION_ID, kIncludeVersion, !kIncludePathId, |
- !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER)); |
- char buffer[kMaxPacketSize]; |
- size_t encrypted_length = |
- framer_.EncryptPayload(ENCRYPTION_NONE, kDefaultPathId, packet_number, |
- *raw, buffer, kMaxPacketSize); |
- |
- ASSERT_NE(0u, encrypted_length); |
- EXPECT_TRUE(CheckEncryption(kDefaultPathId, packet_number, raw.get())); |
-} |
- |
-TEST_P(QuicFramerTest, EncryptPacketWithMultipathFlag) { |
- QuicPacketNumber packet_number = kPacketNumber; |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (version, 8 byte connection_id) |
- 0x78, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // path_id |
- 0x42, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // redundancy |
- 'a', 'b', 'c', 'd', |
- 'e', 'f', 'g', 'h', |
- 'i', 'j', 'k', 'l', |
- 'm', 'n', 'o', 'p', |
- }; |
- unsigned char packet_34[] = { |
- // public flags (version, 8 byte connection_id) |
- 0x78, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // path_id |
- 0x42, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // redundancy |
- 'a', 'b', 'c', 'd', |
- 'e', 'f', 'g', 'h', |
- 'i', 'j', 'k', 'l', |
- 'm', 'n', 'o', 'p', |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicPacket> raw(new QuicPacket( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false, PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, kIncludePathId, |
- !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER)); |
- char buffer[kMaxPacketSize]; |
- size_t encrypted_length = framer_.EncryptPayload( |
- ENCRYPTION_NONE, kPathId, packet_number, *raw, buffer, kMaxPacketSize); |
- |
- ASSERT_NE(0u, encrypted_length); |
- EXPECT_TRUE(CheckEncryption(kPathId, packet_number, raw.get())); |
-} |
- |
-TEST_P(QuicFramerTest, EncryptPacketWithBothVersionFlagAndMultipathFlag) { |
- QuicPacketNumber packet_number = kPacketNumber; |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (version, 8 byte connection_id) |
- 0x79, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // version tag |
- 'Q', '.', '1', '0', |
- // path_id |
- 0x42, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // redundancy |
- 'a', 'b', 'c', 'd', |
- 'e', 'f', 'g', 'h', |
- 'i', 'j', 'k', 'l', |
- 'm', 'n', 'o', 'p', |
- }; |
- unsigned char packet_34[] = { |
- // public flags (version, 8 byte connection_id) |
- 0x79, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // version tag |
- 'Q', '.', '1', '0', |
- // path_id |
- 0x42, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // redundancy |
- 'a', 'b', 'c', 'd', |
- 'e', 'f', 'g', 'h', |
- 'i', 'j', 'k', 'l', |
- 'm', 'n', 'o', 'p', |
- }; |
- // clang-format on |
- |
- std::unique_ptr<QuicPacket> raw(new QuicPacket( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false, PACKET_8BYTE_CONNECTION_ID, kIncludeVersion, kIncludePathId, |
- !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER)); |
- char buffer[kMaxPacketSize]; |
- size_t encrypted_length = framer_.EncryptPayload( |
- ENCRYPTION_NONE, kPathId, packet_number, *raw, buffer, kMaxPacketSize); |
- |
- ASSERT_NE(0u, encrypted_length); |
- EXPECT_TRUE(CheckEncryption(kPathId, packet_number, raw.get())); |
-} |
- |
-TEST_P(QuicFramerTest, AckTruncationLargePacket) { |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = false; |
- header.packet_number = kPacketNumber; |
- |
- QuicAckFrame ack_frame; |
- // Create a packet with just the ack. |
- if (framer_.version() <= QUIC_VERSION_33) { |
- ack_frame = MakeAckFrameWithNackRanges(300, 0u); |
- } else { |
- ack_frame = MakeAckFrameWithAckBlocks(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. |
- std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(raw_ack_packet != nullptr); |
- char buffer[kMaxPacketSize]; |
- size_t encrypted_length = framer_.EncryptPayload( |
- ENCRYPTION_NONE, kDefaultPathId, header.packet_number, *raw_ack_packet, |
- buffer, kMaxPacketSize); |
- ASSERT_NE(0u, encrypted_length); |
- // Now make sure we can turn our ack packet back into an ack frame. |
- ASSERT_TRUE(framer_.ProcessPacket( |
- QuicEncryptedPacket(buffer, encrypted_length, false))); |
- ASSERT_EQ(1u, visitor_.ack_frames_.size()); |
- QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0]; |
- if (framer_.version() <= QUIC_VERSION_33) { |
- EXPECT_TRUE(processed_ack_frame.is_truncated); |
- EXPECT_EQ(510u, processed_ack_frame.largest_observed); |
- EXPECT_TRUE(processed_ack_frame.missing); |
- ASSERT_EQ(255u, processed_ack_frame.packets.NumPacketsSlow()); |
- EXPECT_EQ(1u, processed_ack_frame.packets.Min()); |
- EXPECT_EQ(509u, processed_ack_frame.packets.Max()); |
- } else { |
- EXPECT_FALSE(processed_ack_frame.is_truncated); |
- EXPECT_FALSE(processed_ack_frame.missing); |
- EXPECT_EQ(600u, processed_ack_frame.largest_observed); |
- ASSERT_EQ(256u, processed_ack_frame.packets.NumPacketsSlow()); |
- EXPECT_EQ(90u, processed_ack_frame.packets.Min()); |
- EXPECT_EQ(600u, processed_ack_frame.packets.Max()); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, AckTruncationSmallPacket) { |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = false; |
- header.packet_number = kPacketNumber; |
- |
- // Create a packet with just the ack. |
- QuicAckFrame ack_frame; |
- if (framer_.version() <= QUIC_VERSION_33) { |
- ack_frame = MakeAckFrameWithNackRanges(300, 0u); |
- } else { |
- ack_frame = MakeAckFrameWithAckBlocks(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. |
- std::unique_ptr<QuicPacket> raw_ack_packet( |
- BuildDataPacket(header, frames, 500)); |
- ASSERT_TRUE(raw_ack_packet != nullptr); |
- char buffer[kMaxPacketSize]; |
- size_t encrypted_length = framer_.EncryptPayload( |
- ENCRYPTION_NONE, kDefaultPathId, header.packet_number, *raw_ack_packet, |
- buffer, kMaxPacketSize); |
- ASSERT_NE(0u, encrypted_length); |
- // Now make sure we can turn our ack packet back into an ack frame. |
- ASSERT_TRUE(framer_.ProcessPacket( |
- QuicEncryptedPacket(buffer, encrypted_length, false))); |
- ASSERT_EQ(1u, visitor_.ack_frames_.size()); |
- QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0]; |
- if (framer_.version() <= QUIC_VERSION_33) { |
- EXPECT_TRUE(processed_ack_frame.is_truncated); |
- EXPECT_EQ(476u, processed_ack_frame.largest_observed); |
- EXPECT_TRUE(processed_ack_frame.missing); |
- ASSERT_EQ(238u, processed_ack_frame.packets.NumPacketsSlow()); |
- EXPECT_EQ(1u, processed_ack_frame.packets.Min()); |
- EXPECT_EQ(475u, processed_ack_frame.packets.Max()); |
- } else { |
- EXPECT_FALSE(processed_ack_frame.is_truncated); |
- EXPECT_EQ(600u, processed_ack_frame.largest_observed); |
- EXPECT_FALSE(processed_ack_frame.missing); |
- ASSERT_EQ(239u, processed_ack_frame.packets.NumPacketsSlow()); |
- EXPECT_EQ(124u, processed_ack_frame.packets.Min()); |
- EXPECT_EQ(600u, processed_ack_frame.packets.Max()); |
- } |
-} |
- |
-TEST_P(QuicFramerTest, CleanTruncation) { |
- QuicPacketHeader header; |
- header.public_header.connection_id = kConnectionId; |
- header.public_header.reset_flag = false; |
- header.public_header.version_flag = false; |
- header.fec_flag = false; |
- header.entropy_flag = true; |
- header.packet_number = kPacketNumber; |
- |
- QuicAckFrame ack_frame; |
- ack_frame.largest_observed = 201; |
- ack_frame.packets.Add(1, ack_frame.largest_observed); |
- |
- // Create a packet with just the ack. |
- QuicFrame frame; |
- frame.type = ACK_FRAME; |
- frame.ack_frame = &ack_frame; |
- QuicFrames frames; |
- frames.push_back(frame); |
- |
- std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(raw_ack_packet != nullptr); |
- |
- char buffer[kMaxPacketSize]; |
- size_t encrypted_length = framer_.EncryptPayload( |
- ENCRYPTION_NONE, kDefaultPathId, header.packet_number, *raw_ack_packet, |
- buffer, kMaxPacketSize); |
- ASSERT_NE(0u, encrypted_length); |
- |
- // Now make sure we can turn our ack packet back into an ack frame. |
- ASSERT_TRUE(framer_.ProcessPacket( |
- QuicEncryptedPacket(buffer, encrypted_length, false))); |
- |
- // Test for clean truncation of the ack by comparing the length of the |
- // original packets to the re-serialized packets. |
- frames.clear(); |
- frame.type = ACK_FRAME; |
- frame.ack_frame = visitor_.ack_frames_[0]; |
- frames.push_back(frame); |
- |
- size_t original_raw_length = raw_ack_packet->length(); |
- raw_ack_packet.reset(BuildDataPacket(header, frames)); |
- ASSERT_TRUE(raw_ack_packet != nullptr); |
- EXPECT_EQ(original_raw_length, raw_ack_packet->length()); |
- ASSERT_TRUE(raw_ack_packet != nullptr); |
-} |
- |
-TEST_P(QuicFramerTest, EntropyFlagTest) { |
- if (framer_.version() > QUIC_VERSION_33) { |
- return; |
- } |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags (Entropy) |
- 0x01, |
- |
- // 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', '!', |
- }; |
- // clang-format on |
- |
- 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(visitor_.header_->entropy_flag); |
- EXPECT_EQ(1 << 4, visitor_.header_->entropy_hash); |
- EXPECT_FALSE(visitor_.header_->fec_flag); |
-}; |
- |
-TEST_P(QuicFramerTest, StopPacketProcessing) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // Entropy |
- 0x01, |
- |
- // frame type (stream frame with fin) |
- 0xFF, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- // data length |
- 0x0c, 0x00, |
- // data |
- 'h', 'e', 'l', 'l', |
- 'o', ' ', 'w', 'o', |
- 'r', 'l', 'd', '!', |
- |
- // frame type (ack frame) |
- 0x40, |
- // entropy hash of sent packets till least awaiting - 1. |
- 0x14, |
- // least packet number awaiting an ack |
- 0xA0, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // entropy hash of all received packets. |
- 0x43, |
- // largest observed packet number |
- 0xBF, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // num missing packets |
- 0x01, |
- // missing packet |
- 0xBE, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- }; |
- unsigned char packet_34[] = { |
- // public flags (8 byte connection_id) |
- static_cast<unsigned char>( |
- framer_.version() > QUIC_VERSION_32 ? 0x38 : 0x3C), |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- |
- // frame type (stream frame with fin) |
- 0xFF, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- // data length |
- 0x0c, 0x00, |
- // data |
- 'h', 'e', 'l', 'l', |
- 'o', ' ', 'w', 'o', |
- 'r', 'l', 'd', '!', |
- |
- // frame type (ack frame) |
- 0x40, |
- // entropy hash of sent packets till least awaiting - 1. |
- 0x14, |
- // least packet number awaiting an ack |
- 0xA0, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // entropy hash of all received packets. |
- 0x43, |
- // largest observed packet number |
- 0xBF, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // num missing packets |
- 0x01, |
- // missing packet |
- 0xBE, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- }; |
- // clang-format on |
- |
- MockFramerVisitor visitor; |
- framer_.set_visitor(&visitor); |
- EXPECT_CALL(visitor, OnPacket()); |
- EXPECT_CALL(visitor, OnPacketHeader(_)); |
- EXPECT_CALL(visitor, OnStreamFrame(_)).WillOnce(Return(false)); |
- EXPECT_CALL(visitor, OnAckFrame(_)).Times(0); |
- EXPECT_CALL(visitor, OnPacketComplete()); |
- EXPECT_CALL(visitor, OnUnauthenticatedPublicHeader(_)).WillOnce(Return(true)); |
- EXPECT_CALL(visitor, OnUnauthenticatedHeader(_)).WillOnce(Return(true)); |
- EXPECT_CALL(visitor, OnDecryptedPacket(_)); |
- |
- QuicEncryptedPacket encrypted( |
- AsChars(framer_.version() <= QUIC_VERSION_33 ? packet : packet_34), |
- framer_.version() <= QUIC_VERSION_33 ? arraysize(packet) |
- : arraysize(packet_34), |
- false); |
- EXPECT_TRUE(framer_.ProcessPacket(encrypted)); |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
-} |
- |
-static char kTestString[] = "At least 20 characters."; |
-static QuicStreamId kTestQuicStreamId = 1; |
-static bool ExpectedStreamFrame(const QuicStreamFrame& frame) { |
- return frame.stream_id == kTestQuicStreamId && !frame.fin && |
- frame.offset == 0 && |
- string(frame.data_buffer, frame.data_length) == kTestString; |
- // FIN is hard-coded false in ConstructEncryptedPacket. |
- // Offset 0 is hard-coded in ConstructEncryptedPacket. |
-} |
- |
-// Verify that the packet returned by ConstructEncryptedPacket() can be properly |
-// parsed by the framer. |
-TEST_P(QuicFramerTest, ConstructEncryptedPacket) { |
- // Since we are using ConstructEncryptedPacket, we have to set the framer's |
- // crypto to be Null. |
- framer_.SetDecrypter(ENCRYPTION_NONE, QuicDecrypter::Create(kNULL)); |
- framer_.SetEncrypter(ENCRYPTION_NONE, QuicEncrypter::Create(kNULL)); |
- QuicVersionVector versions; |
- versions.push_back(framer_.version()); |
- std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket( |
- 42, false, false, false, kDefaultPathId, kTestQuicStreamId, kTestString, |
- PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, &versions)); |
- |
- MockFramerVisitor visitor; |
- framer_.set_visitor(&visitor); |
- EXPECT_CALL(visitor, OnPacket()).Times(1); |
- EXPECT_CALL(visitor, OnUnauthenticatedPublicHeader(_)) |
- .Times(1) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(visitor, OnUnauthenticatedHeader(_)) |
- .Times(1) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(visitor, OnPacketHeader(_)).Times(1).WillOnce(Return(true)); |
- EXPECT_CALL(visitor, OnDecryptedPacket(_)).Times(1); |
- EXPECT_CALL(visitor, OnError(_)).Times(0); |
- EXPECT_CALL(visitor, OnStreamFrame(_)).Times(0); |
- EXPECT_CALL(visitor, OnStreamFrame(Truly(ExpectedStreamFrame))).Times(1); |
- EXPECT_CALL(visitor, OnAckFrame(_)).Times(0); |
- EXPECT_CALL(visitor, OnPacketComplete()).Times(1); |
- |
- EXPECT_TRUE(framer_.ProcessPacket(*packet)); |
- EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); |
-} |
- |
-// Verify that the packet returned by ConstructMisFramedEncryptedPacket() |
-// does cause the framer to return an error. |
-TEST_P(QuicFramerTest, ConstructMisFramedEncryptedPacket) { |
- // Since we are using ConstructEncryptedPacket, we have to set the framer's |
- // crypto to be Null. |
- framer_.SetDecrypter(ENCRYPTION_NONE, QuicDecrypter::Create(kNULL)); |
- framer_.SetEncrypter(ENCRYPTION_NONE, QuicEncrypter::Create(kNULL)); |
- QuicVersionVector versions; |
- versions.push_back(framer_.version()); |
- std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket( |
- 42, false, false, false, kDefaultPathId, kTestQuicStreamId, kTestString, |
- PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, &versions, |
- Perspective::IS_SERVER)); |
- |
- MockFramerVisitor visitor; |
- framer_.set_visitor(&visitor); |
- EXPECT_CALL(visitor, OnPacket()).Times(1); |
- EXPECT_CALL(visitor, OnUnauthenticatedPublicHeader(_)) |
- .Times(1) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(visitor, OnUnauthenticatedHeader(_)) |
- .Times(1) |
- .WillOnce(Return(true)); |
- if (framer_.version() <= QUIC_VERSION_33) { |
- EXPECT_CALL(visitor, OnPacketHeader(_)).Times(0); |
- } else { |
- EXPECT_CALL(visitor, OnPacketHeader(_)).Times(1); |
- } |
- EXPECT_CALL(visitor, OnDecryptedPacket(_)).Times(1); |
- EXPECT_CALL(visitor, OnError(_)).Times(1); |
- EXPECT_CALL(visitor, OnStreamFrame(_)).Times(0); |
- EXPECT_CALL(visitor, OnAckFrame(_)).Times(0); |
- EXPECT_CALL(visitor, OnPacketComplete()).Times(0); |
- |
- EXPECT_FALSE(framer_.ProcessPacket(*packet)); |
- if (framer_.version() <= QUIC_VERSION_33) { |
- EXPECT_EQ(QUIC_INVALID_PACKET_HEADER, framer_.error()); |
- } else { |
- EXPECT_EQ(QUIC_INVALID_FRAME_DATA, framer_.error()); |
- } |
-} |
- |
-// Tests for fuzzing with Dr. Fuzz |
-// Xref http://www.chromium.org/developers/testing/dr-fuzz for more details. |
-#ifdef __cplusplus |
-extern "C" { |
-#endif |
- |
-// target function to be fuzzed by Dr. Fuzz |
-void QuicFramerFuzzFunc(unsigned char* data, size_t size) { |
- QuicFramer framer(QuicSupportedVersions(), QuicTime::Zero(), |
- Perspective::IS_SERVER); |
- const char* const packet_bytes = reinterpret_cast<const char*>(data); |
- |
- // Test the CryptoFramer. |
- StringPiece crypto_input(packet_bytes, size); |
- std::unique_ptr<CryptoHandshakeMessage> handshake_message( |
- CryptoFramer::ParseMessage(crypto_input)); |
- |
- // Test the regular QuicFramer with the same input. |
- NoOpFramerVisitor visitor; |
- framer.set_visitor(&visitor); |
- QuicEncryptedPacket packet(packet_bytes, size); |
- framer.ProcessPacket(packet); |
-} |
- |
-#ifdef __cplusplus |
-} |
-#endif |
- |
-TEST_P(QuicFramerTest, FramerFuzzTest) { |
- // clang-format off |
- unsigned char packet[] = { |
- // public flags (8 byte connection_id) |
- 0x3C, |
- // connection_id |
- 0x10, 0x32, 0x54, 0x76, |
- 0x98, 0xBA, 0xDC, 0xFE, |
- // packet number |
- 0xBC, 0x9A, 0x78, 0x56, |
- 0x34, 0x12, |
- // private flags |
- 0x00, |
- |
- // frame type (stream frame with fin) |
- 0xFF, |
- // stream id |
- 0x04, 0x03, 0x02, 0x01, |
- // offset |
- 0x54, 0x76, 0x10, 0x32, |
- 0xDC, 0xFE, 0x98, 0xBA, |
- // data length |
- 0x0c, 0x00, |
- // data |
- 'h', 'e', 'l', 'l', |
- 'o', ' ', 'w', 'o', |
- 'r', 'l', 'd', '!', |
- }; |
- // clang-format on |
- |
- QuicFramerFuzzFunc(packet, arraysize(packet)); |
-} |
- |
-} // namespace test |
-} // namespace net |