| 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 69373e0590d98bc4c3d6e5c4fa103384372cd342..0000000000000000000000000000000000000000
|
| --- a/net/quic/quic_framer_test.cc
|
| +++ /dev/null
|
| @@ -1,4271 +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 <algorithm>
|
| -#include <map>
|
| -#include <string>
|
| -#include <vector>
|
| -
|
| -#include "base/containers/hash_tables.h"
|
| -#include "base/logging.h"
|
| -#include "base/memory/scoped_ptr.h"
|
| -#include "base/port.h"
|
| -#include "base/stl_util.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::hash_set;
|
| -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::_;
|
| -
|
| -namespace net {
|
| -namespace test {
|
| -
|
| -const QuicPacketSequenceNumber kEpoch = GG_UINT64_C(1) << 48;
|
| -const QuicPacketSequenceNumber kMask = kEpoch - 1;
|
| -
|
| -// 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 sequence number offset in the header.
|
| -size_t GetSequenceNumberOffset(QuicConnectionIdLength connection_id_length,
|
| - bool include_version) {
|
| - return kConnectionIdOffset + connection_id_length +
|
| - (include_version ? kQuicVersionSize : 0);
|
| -}
|
| -
|
| -size_t GetSequenceNumberOffset(bool include_version) {
|
| - return GetSequenceNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version);
|
| -}
|
| -
|
| -// Index into the private flags offset in the data packet header.
|
| -size_t GetPrivateFlagsOffset(QuicConnectionIdLength connection_id_length,
|
| - bool include_version) {
|
| - return GetSequenceNumberOffset(connection_id_length, include_version) +
|
| - PACKET_6BYTE_SEQUENCE_NUMBER;
|
| -}
|
| -
|
| -size_t GetPrivateFlagsOffset(bool include_version) {
|
| - return GetPrivateFlagsOffset(PACKET_8BYTE_CONNECTION_ID, include_version);
|
| -}
|
| -
|
| -size_t GetPrivateFlagsOffset(bool include_version,
|
| - QuicSequenceNumberLength sequence_number_length) {
|
| - return GetSequenceNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version) +
|
| - sequence_number_length;
|
| -}
|
| -
|
| -// Index into the fec group offset in the header.
|
| -size_t GetFecGroupOffset(QuicConnectionIdLength connection_id_length,
|
| - bool include_version) {
|
| - return GetPrivateFlagsOffset(connection_id_length, include_version) +
|
| - kPrivateFlagsSize;
|
| -}
|
| -
|
| -size_t GetFecGroupOffset(bool include_version) {
|
| - return GetPrivateFlagsOffset(PACKET_8BYTE_CONNECTION_ID, include_version) +
|
| - kPrivateFlagsSize;
|
| -}
|
| -
|
| -size_t GetFecGroupOffset(bool include_version,
|
| - QuicSequenceNumberLength sequence_number_length) {
|
| - return GetPrivateFlagsOffset(include_version, sequence_number_length) +
|
| - kPrivateFlagsSize;
|
| -}
|
| -
|
| -// 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 Encrypt(StringPiece nonce,
|
| - StringPiece associated_data,
|
| - StringPiece plaintext,
|
| - unsigned char* output) override {
|
| - CHECK(false) << "Not implemented";
|
| - return false;
|
| - }
|
| - bool EncryptPacket(QuicPacketSequenceNumber sequence_number,
|
| - StringPiece associated_data,
|
| - StringPiece plaintext,
|
| - char* output,
|
| - size_t* output_length,
|
| - size_t max_output_length) override {
|
| - sequence_number_ = sequence_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(); }
|
| - QuicPacketSequenceNumber sequence_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 DecryptPacket(QuicPacketSequenceNumber sequence_number,
|
| - const StringPiece& associated_data,
|
| - const StringPiece& ciphertext,
|
| - char* output,
|
| - size_t* output_length,
|
| - size_t max_output_length) override {
|
| - sequence_number_ = sequence_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(); }
|
| - QuicPacketSequenceNumber sequence_number_;
|
| - string associated_data_;
|
| - string ciphertext_;
|
| -};
|
| -
|
| -class TestQuicVisitor : public ::net::QuicFramerVisitorInterface {
|
| - public:
|
| - TestQuicVisitor()
|
| - : error_count_(0),
|
| - version_mismatch_(0),
|
| - packet_count_(0),
|
| - frame_count_(0),
|
| - fec_count_(0),
|
| - complete_packets_(0),
|
| - revived_packets_(0),
|
| - accept_packet_(true),
|
| - accept_public_header_(true) {
|
| - }
|
| -
|
| - ~TestQuicVisitor() override {
|
| - STLDeleteElements(&stream_frames_);
|
| - STLDeleteElements(&ack_frames_);
|
| - STLDeleteElements(&stop_waiting_frames_);
|
| - STLDeleteElements(&ping_frames_);
|
| - STLDeleteElements(&fec_data_);
|
| - STLDeleteElements(&stream_data_);
|
| - STLDeleteElements(&fec_data_redundancy_);
|
| - }
|
| -
|
| - 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));
|
| - }
|
| -
|
| - void OnRevivedPacket() override { ++revived_packets_; }
|
| -
|
| - 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 {
|
| - ++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.
|
| - stream_data_.push_back(frame.GetDataAsString());
|
| - QuicStreamFrame* stream_frame = new QuicStreamFrame(frame);
|
| - // Make sure that the stream frame points to this data.
|
| - stream_frame->data.Clear();
|
| - stream_frame->data.Append(const_cast<char*>(stream_data_.back()->data()),
|
| - stream_data_.back()->size());
|
| - stream_frames_.push_back(stream_frame);
|
| - return true;
|
| - }
|
| -
|
| - void OnFecProtectedPayload(StringPiece payload) override {
|
| - fec_protected_payload_ = payload.as_string();
|
| - }
|
| -
|
| - 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 OnPingFrame(const QuicPingFrame& frame) override {
|
| - ++frame_count_;
|
| - ping_frames_.push_back(new QuicPingFrame(frame));
|
| - return true;
|
| - }
|
| -
|
| - void OnFecData(const QuicFecData& fec) override {
|
| - ++fec_count_;
|
| - QuicFecData* fec_data = new QuicFecData();
|
| - fec_data->fec_group = fec.fec_group;
|
| - // Save a copy of the data so it is valid after the packet is processed.
|
| - string* redundancy = new string(fec.redundancy.as_string());
|
| - fec_data_redundancy_.push_back(redundancy);
|
| - fec_data->redundancy = StringPiece(*redundancy);
|
| - fec_data_.push_back(fec_data);
|
| - }
|
| -
|
| - 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;
|
| - }
|
| -
|
| - // Counters from the visitor_ callbacks.
|
| - int error_count_;
|
| - int version_mismatch_;
|
| - int packet_count_;
|
| - int frame_count_;
|
| - int fec_count_;
|
| - int complete_packets_;
|
| - int revived_packets_;
|
| - bool accept_packet_;
|
| - bool accept_public_header_;
|
| -
|
| - scoped_ptr<QuicPacketHeader> header_;
|
| - scoped_ptr<QuicPacketPublicHeader> public_header_;
|
| - scoped_ptr<QuicPublicResetPacket> public_reset_packet_;
|
| - scoped_ptr<QuicVersionNegotiationPacket> version_negotiation_packet_;
|
| - vector<QuicStreamFrame*> stream_frames_;
|
| - vector<QuicAckFrame*> ack_frames_;
|
| - vector<QuicStopWaitingFrame*> stop_waiting_frames_;
|
| - vector<QuicPingFrame*> ping_frames_;
|
| - vector<QuicFecData*> fec_data_;
|
| - string fec_protected_payload_;
|
| - QuicRstStreamFrame rst_stream_frame_;
|
| - QuicConnectionCloseFrame connection_close_frame_;
|
| - QuicGoAwayFrame goaway_frame_;
|
| - QuicWindowUpdateFrame window_update_frame_;
|
| - QuicBlockedFrame blocked_frame_;
|
| - vector<string*> stream_data_;
|
| - vector<string*> fec_data_redundancy_;
|
| -};
|
| -
|
| -class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> {
|
| - public:
|
| - QuicFramerTest()
|
| - : encrypter_(new test::TestEncrypter()),
|
| - decrypter_(new test::TestDecrypter()),
|
| - start_(QuicTime::Zero().Add(QuicTime::Delta::FromMicroseconds(0x10))),
|
| - framer_(QuicSupportedVersions(), start_, true) {
|
| - version_ = GetParam();
|
| - framer_.set_version(version_);
|
| - framer_.SetDecrypter(decrypter_, ENCRYPTION_NONE);
|
| - 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(QuicPacketSequenceNumber sequence_number,
|
| - QuicPacket* packet) {
|
| - if (sequence_number != encrypter_->sequence_number_) {
|
| - LOG(ERROR) << "Encrypted incorrect packet sequence number. expected "
|
| - << sequence_number << " actual: "
|
| - << encrypter_->sequence_number_;
|
| - return false;
|
| - }
|
| - if (packet->AssociatedData() != encrypter_->associated_data_) {
|
| - LOG(ERROR) << "Encrypted incorrect associated data. expected "
|
| - << packet->AssociatedData() << " actual: "
|
| - << encrypter_->associated_data_;
|
| - return false;
|
| - }
|
| - if (packet->Plaintext() != encrypter_->plaintext_) {
|
| - LOG(ERROR) << "Encrypted incorrect plaintext data. expected "
|
| - << packet->Plaintext() << " actual: "
|
| - << encrypter_->plaintext_;
|
| - return false;
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - bool CheckDecryption(const QuicEncryptedPacket& encrypted,
|
| - bool includes_version) {
|
| - if (visitor_.header_->packet_sequence_number !=
|
| - decrypter_->sequence_number_) {
|
| - LOG(ERROR) << "Decrypted incorrect packet sequence number. expected "
|
| - << visitor_.header_->packet_sequence_number << " actual: "
|
| - << decrypter_->sequence_number_;
|
| - return false;
|
| - }
|
| - if (QuicFramer::GetAssociatedDataFromEncryptedPacket(
|
| - encrypted, PACKET_8BYTE_CONNECTION_ID,
|
| - includes_version, PACKET_6BYTE_SEQUENCE_NUMBER) !=
|
| - decrypter_->associated_data_) {
|
| - LOG(ERROR) << "Decrypted incorrect associated data. expected "
|
| - << QuicFramer::GetAssociatedDataFromEncryptedPacket(
|
| - encrypted, PACKET_8BYTE_CONNECTION_ID,
|
| - includes_version, PACKET_6BYTE_SEQUENCE_NUMBER)
|
| - << " actual: " << decrypter_->associated_data_;
|
| - return false;
|
| - }
|
| - StringPiece ciphertext(encrypted.AsStringPiece().substr(
|
| - GetStartOfEncryptedData(PACKET_8BYTE_CONNECTION_ID, includes_version,
|
| - PACKET_6BYTE_SEQUENCE_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) {
|
| - scoped_ptr<string> frame_data(frame->GetDataAsString());
|
| - EXPECT_EQ(str, *frame_data);
|
| - }
|
| -
|
| - 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(PACKET_8BYTE_CONNECTION_ID, include_version,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER,
|
| - NOT_IN_FEC_GROUP),
|
| - expected_error, QUIC_INVALID_STREAM_DATA);
|
| - }
|
| - }
|
| -
|
| - void CheckCalculatePacketSequenceNumber(
|
| - QuicPacketSequenceNumber expected_sequence_number,
|
| - QuicPacketSequenceNumber last_sequence_number) {
|
| - QuicPacketSequenceNumber wire_sequence_number =
|
| - expected_sequence_number & kMask;
|
| - QuicFramerPeer::SetLastSequenceNumber(&framer_, last_sequence_number);
|
| - EXPECT_EQ(expected_sequence_number,
|
| - QuicFramerPeer::CalculatePacketSequenceNumberFromWire(
|
| - &framer_, PACKET_6BYTE_SEQUENCE_NUMBER, wire_sequence_number))
|
| - << "last_sequence_number: " << last_sequence_number
|
| - << " wire_sequence_number: " << wire_sequence_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, CalculatePacketSequenceNumberFromWireNearEpochStart) {
|
| - // A few quick manual sanity checks
|
| - CheckCalculatePacketSequenceNumber(GG_UINT64_C(1), GG_UINT64_C(0));
|
| - CheckCalculatePacketSequenceNumber(kEpoch + 1, kMask);
|
| - CheckCalculatePacketSequenceNumber(kEpoch, kMask);
|
| -
|
| - // Cases where the last number was close to the start of the range
|
| - for (uint64 last = 0; last < 10; last++) {
|
| - // Small numbers should not wrap (even if they're out of order).
|
| - for (uint64 j = 0; j < 10; j++) {
|
| - CheckCalculatePacketSequenceNumber(j, last);
|
| - }
|
| -
|
| - // Large numbers should not wrap either (because we're near 0 already).
|
| - for (uint64 j = 0; j < 10; j++) {
|
| - CheckCalculatePacketSequenceNumber(kEpoch - 1 - j, last);
|
| - }
|
| - }
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearEpochEnd) {
|
| - // Cases where the last number was close to the end of the range
|
| - for (uint64 i = 0; i < 10; i++) {
|
| - QuicPacketSequenceNumber last = kEpoch - i;
|
| -
|
| - // Small numbers should wrap.
|
| - for (uint64 j = 0; j < 10; j++) {
|
| - CheckCalculatePacketSequenceNumber(kEpoch + j, last);
|
| - }
|
| -
|
| - // Large numbers should not (even if they're out of order).
|
| - for (uint64 j = 0; j < 10; j++) {
|
| - CheckCalculatePacketSequenceNumber(kEpoch - 1 - j, last);
|
| - }
|
| - }
|
| -}
|
| -
|
| -// Next check where we're in a non-zero epoch to verify we handle
|
| -// reverse wrapping, too.
|
| -TEST_P(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearPrevEpoch) {
|
| - const uint64 prev_epoch = 1 * kEpoch;
|
| - const uint64 cur_epoch = 2 * kEpoch;
|
| - // Cases where the last number was close to the start of the range
|
| - for (uint64 i = 0; i < 10; i++) {
|
| - uint64 last = cur_epoch + i;
|
| - // Small number should not wrap (even if they're out of order).
|
| - for (uint64 j = 0; j < 10; j++) {
|
| - CheckCalculatePacketSequenceNumber(cur_epoch + j, last);
|
| - }
|
| -
|
| - // But large numbers should reverse wrap.
|
| - for (uint64 j = 0; j < 10; j++) {
|
| - uint64 num = kEpoch - 1 - j;
|
| - CheckCalculatePacketSequenceNumber(prev_epoch + num, last);
|
| - }
|
| - }
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearNextEpoch) {
|
| - const uint64 cur_epoch = 2 * kEpoch;
|
| - const uint64 next_epoch = 3 * kEpoch;
|
| - // Cases where the last number was close to the end of the range
|
| - for (uint64 i = 0; i < 10; i++) {
|
| - QuicPacketSequenceNumber last = next_epoch - 1 - i;
|
| -
|
| - // Small numbers should wrap.
|
| - for (uint64 j = 0; j < 10; j++) {
|
| - CheckCalculatePacketSequenceNumber(next_epoch + j, last);
|
| - }
|
| -
|
| - // but large numbers should not (even if they're out of order).
|
| - for (uint64 j = 0; j < 10; j++) {
|
| - uint64 num = kEpoch - 1 - j;
|
| - CheckCalculatePacketSequenceNumber(cur_epoch + num, last);
|
| - }
|
| - }
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, CalculatePacketSequenceNumberFromWireNearNextMax) {
|
| - const uint64 max_number = numeric_limits<uint64>::max();
|
| - const uint64 max_epoch = max_number & ~kMask;
|
| -
|
| - // Cases where the last number was close to the end of the range
|
| - for (uint64 i = 0; i < 10; i++) {
|
| - // Subtract 1, because the expected next sequence number is 1 more than the
|
| - // last sequence number.
|
| - QuicPacketSequenceNumber last = max_number - i - 1;
|
| -
|
| - // Small numbers should not wrap, because they have nowhere to go.
|
| - for (uint64 j = 0; j < 10; j++) {
|
| - CheckCalculatePacketSequenceNumber(max_epoch + j, last);
|
| - }
|
| -
|
| - // Large numbers should not wrap either.
|
| - for (uint64 j = 0; j < 10; j++) {
|
| - uint64 num = kEpoch - 1 - j;
|
| - CheckCalculatePacketSequenceNumber(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) {
|
| - unsigned char packet[kMaxPacketSize + 1] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10,
|
| - 0x32,
|
| - 0x54,
|
| - 0x76,
|
| - 0x98,
|
| - 0xBA,
|
| - 0xDC,
|
| - 0xFE,
|
| - // packet sequence number
|
| - 0xBC,
|
| - 0x9A,
|
| - 0x78,
|
| - 0x56,
|
| - 0x34,
|
| - 0x12,
|
| - // private flags
|
| - 0x00,
|
| - };
|
| -
|
| - memset(packet + GetPacketHeaderSize(
|
| - PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP), 0,
|
| - kMaxPacketSize - GetPacketHeaderSize(
|
| - PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP) + 1);
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_FALSE(framer_.ProcessPacket(encrypted));
|
| -
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - // Make sure we've parsed the packet header, so we can send an error.
|
| - EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
|
| - 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) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_FALSE(framer_.ProcessPacket(encrypted));
|
| - EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
|
| - visitor_.header_->public_header.connection_id);
|
| - 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(GG_UINT64_C(0x123456789ABC),
|
| - visitor_.header_->packet_sequence_number);
|
| - EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
|
| - EXPECT_EQ(0x00u, visitor_.header_->fec_group);
|
| -
|
| - // Now test framing boundaries.
|
| - for (size_t i = 0;
|
| - i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
|
| - ++i) {
|
| - string expected_error;
|
| - if (i < kConnectionIdOffset) {
|
| - expected_error = "Unable to read public flags.";
|
| - } else if (i < GetSequenceNumberOffset(!kIncludeVersion)) {
|
| - expected_error = "Unable to read ConnectionId.";
|
| - } else if (i < GetPrivateFlagsOffset(!kIncludeVersion)) {
|
| - expected_error = "Unable to read sequence number.";
|
| - } else if (i < GetFecGroupOffset(!kIncludeVersion)) {
|
| - expected_error = "Unable to read private flags.";
|
| - } else {
|
| - expected_error = "Unable to read first fec protected packet offset.";
|
| - }
|
| - CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
|
| - }
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, PacketHeaderWith4ByteConnectionId) {
|
| - QuicFramerPeer::SetLastSerializedConnectionId(
|
| - &framer_, GG_UINT64_C(0xFEDCBA9876543210));
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (4 byte connection_id)
|
| - 0x38,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_FALSE(framer_.ProcessPacket(encrypted));
|
| - EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
|
| - visitor_.header_->public_header.connection_id);
|
| - 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(GG_UINT64_C(0x123456789ABC),
|
| - visitor_.header_->packet_sequence_number);
|
| - EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
|
| - EXPECT_EQ(0x00u, visitor_.header_->fec_group);
|
| -
|
| - // Now test framing boundaries.
|
| - for (size_t i = 0;
|
| - i < GetPacketHeaderSize(PACKET_4BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
|
| - ++i) {
|
| - string expected_error;
|
| - if (i < kConnectionIdOffset) {
|
| - expected_error = "Unable to read public flags.";
|
| - } else if (i < GetSequenceNumberOffset(PACKET_4BYTE_CONNECTION_ID,
|
| - !kIncludeVersion)) {
|
| - expected_error = "Unable to read ConnectionId.";
|
| - } else if (i < GetPrivateFlagsOffset(PACKET_4BYTE_CONNECTION_ID,
|
| - !kIncludeVersion)) {
|
| - expected_error = "Unable to read sequence number.";
|
| - } else if (i < GetFecGroupOffset(PACKET_4BYTE_CONNECTION_ID,
|
| - !kIncludeVersion)) {
|
| - expected_error = "Unable to read private flags.";
|
| - } else {
|
| - expected_error = "Unable to read first fec protected packet offset.";
|
| - }
|
| - CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
|
| - }
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, PacketHeader1ByteConnectionId) {
|
| - QuicFramerPeer::SetLastSerializedConnectionId(
|
| - &framer_, GG_UINT64_C(0xFEDCBA9876543210));
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (1 byte connection_id)
|
| - 0x34,
|
| - // connection_id
|
| - 0x10,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_FALSE(framer_.ProcessPacket(encrypted));
|
| - EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
|
| - visitor_.header_->public_header.connection_id);
|
| - 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(GG_UINT64_C(0x123456789ABC),
|
| - visitor_.header_->packet_sequence_number);
|
| - EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
|
| - EXPECT_EQ(0x00u, visitor_.header_->fec_group);
|
| -
|
| - // Now test framing boundaries.
|
| - for (size_t i = 0;
|
| - i < GetPacketHeaderSize(PACKET_1BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
|
| - ++i) {
|
| - string expected_error;
|
| - if (i < kConnectionIdOffset) {
|
| - expected_error = "Unable to read public flags.";
|
| - } else if (i < GetSequenceNumberOffset(PACKET_1BYTE_CONNECTION_ID,
|
| - !kIncludeVersion)) {
|
| - expected_error = "Unable to read ConnectionId.";
|
| - } else if (i < GetPrivateFlagsOffset(PACKET_1BYTE_CONNECTION_ID,
|
| - !kIncludeVersion)) {
|
| - expected_error = "Unable to read sequence number.";
|
| - } else if (i < GetFecGroupOffset(PACKET_1BYTE_CONNECTION_ID,
|
| - !kIncludeVersion)) {
|
| - expected_error = "Unable to read private flags.";
|
| - } else {
|
| - expected_error = "Unable to read first fec protected packet offset.";
|
| - }
|
| - CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
|
| - }
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) {
|
| - QuicFramerPeer::SetLastSerializedConnectionId(
|
| - &framer_, GG_UINT64_C(0xFEDCBA9876543210));
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (0 byte connection_id)
|
| - 0x30,
|
| - // connection_id
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_FALSE(framer_.ProcessPacket(encrypted));
|
| - EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
|
| - visitor_.header_->public_header.connection_id);
|
| - 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(GG_UINT64_C(0x123456789ABC),
|
| - visitor_.header_->packet_sequence_number);
|
| - EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
|
| - EXPECT_EQ(0x00u, visitor_.header_->fec_group);
|
| -
|
| - // Now test framing boundaries.
|
| - for (size_t i = 0;
|
| - i < GetPacketHeaderSize(PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
|
| - ++i) {
|
| - string expected_error;
|
| - if (i < kConnectionIdOffset) {
|
| - expected_error = "Unable to read public flags.";
|
| - } else if (i < GetSequenceNumberOffset(PACKET_0BYTE_CONNECTION_ID,
|
| - !kIncludeVersion)) {
|
| - expected_error = "Unable to read ConnectionId.";
|
| - } else if (i < GetPrivateFlagsOffset(PACKET_0BYTE_CONNECTION_ID,
|
| - !kIncludeVersion)) {
|
| - expected_error = "Unable to read sequence number.";
|
| - } else if (i < GetFecGroupOffset(PACKET_0BYTE_CONNECTION_ID,
|
| - !kIncludeVersion)) {
|
| - expected_error = "Unable to read private flags.";
|
| - } else {
|
| - expected_error = "Unable to read first fec protected packet offset.";
|
| - }
|
| - CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
|
| - }
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) {
|
| - unsigned char packet[] = {
|
| - // public flags (version)
|
| - 0x3D,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // version tag
|
| - 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_FALSE(framer_.ProcessPacket(encrypted));
|
| - EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
|
| - visitor_.header_->public_header.connection_id);
|
| - 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(GG_UINT64_C(0x123456789ABC),
|
| - visitor_.header_->packet_sequence_number);
|
| - EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
|
| - EXPECT_EQ(0x00u, visitor_.header_->fec_group);
|
| -
|
| - // Now test framing boundaries.
|
| - for (size_t i = 0;
|
| - i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
|
| - ++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 < GetSequenceNumberOffset(kIncludeVersion)) {
|
| - expected_error = "Unable to read protocol version.";
|
| - } else if (i < GetPrivateFlagsOffset(kIncludeVersion)) {
|
| - expected_error = "Unable to read sequence number.";
|
| - } else if (i < GetFecGroupOffset(kIncludeVersion)) {
|
| - expected_error = "Unable to read private flags.";
|
| - } else {
|
| - expected_error = "Unable to read first fec protected packet offset.";
|
| - }
|
| - CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
|
| - }
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, PacketHeaderWith4ByteSequenceNumber) {
|
| - QuicFramerPeer::SetLastSequenceNumber(&framer_,
|
| - GG_UINT64_C(0x123456789ABA));
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id and 4 byte sequence number)
|
| - 0x2C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - // private flags
|
| - 0x00,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_FALSE(framer_.ProcessPacket(encrypted));
|
| - EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
|
| - visitor_.header_->public_header.connection_id);
|
| - 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(GG_UINT64_C(0x123456789ABC),
|
| - visitor_.header_->packet_sequence_number);
|
| - EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
|
| - EXPECT_EQ(0x00u, visitor_.header_->fec_group);
|
| -
|
| - // Now test framing boundaries.
|
| - for (size_t i = 0;
|
| - i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_4BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
|
| - ++i) {
|
| - string expected_error;
|
| - if (i < kConnectionIdOffset) {
|
| - expected_error = "Unable to read public flags.";
|
| - } else if (i < GetSequenceNumberOffset(!kIncludeVersion)) {
|
| - expected_error = "Unable to read ConnectionId.";
|
| - } else if (i < GetPrivateFlagsOffset(!kIncludeVersion,
|
| - PACKET_4BYTE_SEQUENCE_NUMBER)) {
|
| - expected_error = "Unable to read sequence number.";
|
| - } else if (i < GetFecGroupOffset(!kIncludeVersion,
|
| - PACKET_4BYTE_SEQUENCE_NUMBER)) {
|
| - expected_error = "Unable to read private flags.";
|
| - } else {
|
| - expected_error = "Unable to read first fec protected packet offset.";
|
| - }
|
| - CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
|
| - }
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, PacketHeaderWith2ByteSequenceNumber) {
|
| - QuicFramerPeer::SetLastSequenceNumber(&framer_,
|
| - GG_UINT64_C(0x123456789ABA));
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id and 2 byte sequence number)
|
| - 0x1C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A,
|
| - // private flags
|
| - 0x00,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_FALSE(framer_.ProcessPacket(encrypted));
|
| - EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
|
| - visitor_.header_->public_header.connection_id);
|
| - 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(GG_UINT64_C(0x123456789ABC),
|
| - visitor_.header_->packet_sequence_number);
|
| - EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
|
| - EXPECT_EQ(0x00u, visitor_.header_->fec_group);
|
| -
|
| - // Now test framing boundaries.
|
| - for (size_t i = 0;
|
| - i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_2BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
|
| - ++i) {
|
| - string expected_error;
|
| - if (i < kConnectionIdOffset) {
|
| - expected_error = "Unable to read public flags.";
|
| - } else if (i < GetSequenceNumberOffset(!kIncludeVersion)) {
|
| - expected_error = "Unable to read ConnectionId.";
|
| - } else if (i < GetPrivateFlagsOffset(!kIncludeVersion,
|
| - PACKET_2BYTE_SEQUENCE_NUMBER)) {
|
| - expected_error = "Unable to read sequence number.";
|
| - } else if (i < GetFecGroupOffset(!kIncludeVersion,
|
| - PACKET_2BYTE_SEQUENCE_NUMBER)) {
|
| - expected_error = "Unable to read private flags.";
|
| - } else {
|
| - expected_error = "Unable to read first fec protected packet offset.";
|
| - }
|
| - CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
|
| - }
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, PacketHeaderWith1ByteSequenceNumber) {
|
| - QuicFramerPeer::SetLastSequenceNumber(&framer_,
|
| - GG_UINT64_C(0x123456789ABA));
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id and 1 byte sequence number)
|
| - 0x0C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC,
|
| - // private flags
|
| - 0x00,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_FALSE(framer_.ProcessPacket(encrypted));
|
| - EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
|
| - visitor_.header_->public_header.connection_id);
|
| - 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(GG_UINT64_C(0x123456789ABC),
|
| - visitor_.header_->packet_sequence_number);
|
| - EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
|
| - EXPECT_EQ(0x00u, visitor_.header_->fec_group);
|
| -
|
| - // Now test framing boundaries.
|
| - for (size_t i = 0;
|
| - i < GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_1BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
|
| - ++i) {
|
| - string expected_error;
|
| - if (i < kConnectionIdOffset) {
|
| - expected_error = "Unable to read public flags.";
|
| - } else if (i < GetSequenceNumberOffset(!kIncludeVersion)) {
|
| - expected_error = "Unable to read ConnectionId.";
|
| - } else if (i < GetPrivateFlagsOffset(!kIncludeVersion,
|
| - PACKET_1BYTE_SEQUENCE_NUMBER)) {
|
| - expected_error = "Unable to read sequence number.";
|
| - } else if (i < GetFecGroupOffset(!kIncludeVersion,
|
| - PACKET_1BYTE_SEQUENCE_NUMBER)) {
|
| - expected_error = "Unable to read private flags.";
|
| - } else {
|
| - expected_error = "Unable to read first fec protected packet offset.";
|
| - }
|
| - CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER);
|
| - }
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, InvalidPublicFlag) {
|
| - unsigned char packet[] = {
|
| - // public flags: all flags set but the public reset flag and version flag.
|
| - 0xFC,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (padding)
|
| - 0x00,
|
| - 0x00, 0x00, 0x00, 0x00
|
| - };
|
| - 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, InvalidPublicFlagWithMatchingVersions) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id and version flag and an unknown flag)
|
| - 0x4D,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // version tag
|
| - 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (padding)
|
| - 0x00,
|
| - 0x00, 0x00, 0x00, 0x00
|
| - };
|
| - CheckProcessingFails(packet,
|
| - arraysize(packet),
|
| - "Illegal public flags value.",
|
| - QUIC_INVALID_PACKET_HEADER);
|
| -};
|
| -
|
| -TEST_P(QuicFramerTest, LargePublicFlagWithMismatchedVersions) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id, version flag and an unknown flag)
|
| - 0x7D,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // version tag
|
| - 'Q', '0', '0', '0',
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (padding frame)
|
| - 0x00,
|
| - 0x00, 0x00, 0x00, 0x00
|
| - };
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_TRUE(framer_.ProcessPacket(encrypted));
|
| - EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_EQ(0, visitor_.frame_count_);
|
| - EXPECT_EQ(1, visitor_.version_mismatch_);
|
| -};
|
| -
|
| -TEST_P(QuicFramerTest, InvalidPrivateFlag) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x10,
|
| -
|
| - // frame type (padding)
|
| - 0x00,
|
| - 0x00, 0x00, 0x00, 0x00
|
| - };
|
| - CheckProcessingFails(packet,
|
| - arraysize(packet),
|
| - "Illegal private flags value.",
|
| - QUIC_INVALID_PACKET_HEADER);
|
| -};
|
| -
|
| -TEST_P(QuicFramerTest, InvalidFECGroupOffset) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0x01, 0x00, 0x00, 0x00,
|
| - 0x00, 0x00,
|
| - // private flags (fec group)
|
| - 0x02,
|
| - // first fec protected packet offset
|
| - 0x10
|
| - };
|
| - CheckProcessingFails(packet,
|
| - arraysize(packet),
|
| - "First fec protected packet offset must be less "
|
| - "than the sequence number.",
|
| - QUIC_INVALID_PACKET_HEADER);
|
| -};
|
| -
|
| -TEST_P(QuicFramerTest, PaddingFrame) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (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', '!',
|
| - };
|
| -
|
| - 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));
|
| -
|
| - 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(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
|
| - "Packet has no frames.", QUIC_MISSING_PAYLOAD);
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, StreamFrame) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (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', '!',
|
| - };
|
| -
|
| - 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));
|
| -
|
| - ASSERT_EQ(1u, visitor_.stream_frames_.size());
|
| - EXPECT_EQ(0u, visitor_.ack_frames_.size());
|
| - EXPECT_EQ(static_cast<uint64>(0x01020304),
|
| - visitor_.stream_frames_[0]->stream_id);
|
| - EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
|
| - EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654),
|
| - visitor_.stream_frames_[0]->offset);
|
| - CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
|
| -
|
| - // Now test framing boundaries.
|
| - CheckStreamFrameBoundaries(packet, kQuicMaxStreamIdSize, !kIncludeVersion);
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, StreamFrame3ByteStreamId) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (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', '!',
|
| - };
|
| -
|
| - 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));
|
| -
|
| - ASSERT_EQ(1u, visitor_.stream_frames_.size());
|
| - EXPECT_EQ(0u, visitor_.ack_frames_.size());
|
| - EXPECT_EQ(GG_UINT64_C(0x00020304), visitor_.stream_frames_[0]->stream_id);
|
| - EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
|
| - EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654),
|
| - visitor_.stream_frames_[0]->offset);
|
| - CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
|
| -
|
| - // Now test framing boundaries.
|
| - const size_t stream_id_size = 3;
|
| - CheckStreamFrameBoundaries(packet, stream_id_size, !kIncludeVersion);
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, StreamFrame2ByteStreamId) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (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', '!',
|
| - };
|
| -
|
| - 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));
|
| -
|
| - ASSERT_EQ(1u, visitor_.stream_frames_.size());
|
| - EXPECT_EQ(0u, visitor_.ack_frames_.size());
|
| - EXPECT_EQ(static_cast<uint64>(0x00000304),
|
| - visitor_.stream_frames_[0]->stream_id);
|
| - EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
|
| - EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654),
|
| - visitor_.stream_frames_[0]->offset);
|
| - CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
|
| -
|
| - // Now test framing boundaries.
|
| - const size_t stream_id_size = 2;
|
| - CheckStreamFrameBoundaries(packet, stream_id_size, !kIncludeVersion);
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, StreamFrame1ByteStreamId) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (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', '!',
|
| - };
|
| -
|
| - 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));
|
| -
|
| - ASSERT_EQ(1u, visitor_.stream_frames_.size());
|
| - EXPECT_EQ(0u, visitor_.ack_frames_.size());
|
| - EXPECT_EQ(static_cast<uint64>(0x00000004),
|
| - visitor_.stream_frames_[0]->stream_id);
|
| - EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
|
| - EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654),
|
| - visitor_.stream_frames_[0]->offset);
|
| - CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
|
| -
|
| - // Now test framing boundaries.
|
| - const size_t stream_id_size = 1;
|
| - CheckStreamFrameBoundaries(packet, stream_id_size, !kIncludeVersion);
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, StreamFrameWithVersion) {
|
| - 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(),
|
| - // packet sequence 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', '!',
|
| - };
|
| -
|
| - 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_->public_header.version_flag);
|
| - EXPECT_EQ(GetParam(), visitor_.header_->public_header.versions[0]);
|
| - EXPECT_TRUE(CheckDecryption(encrypted, kIncludeVersion));
|
| -
|
| - ASSERT_EQ(1u, visitor_.stream_frames_.size());
|
| - EXPECT_EQ(0u, visitor_.ack_frames_.size());
|
| - EXPECT_EQ(static_cast<uint64>(0x01020304),
|
| - visitor_.stream_frames_[0]->stream_id);
|
| - EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
|
| - EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654),
|
| - visitor_.stream_frames_[0]->offset);
|
| - CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
|
| -
|
| - // Now test framing boundaries.
|
| - CheckStreamFrameBoundaries(packet, kQuicMaxStreamIdSize, kIncludeVersion);
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, RejectPacket) {
|
| - visitor_.accept_packet_ = false;
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (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', '!',
|
| - };
|
| -
|
| - 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));
|
| -
|
| - ASSERT_EQ(0u, visitor_.stream_frames_.size());
|
| - EXPECT_EQ(0u, visitor_.ack_frames_.size());
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, RejectPublicHeader) {
|
| - visitor_.accept_public_header_ = false;
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - };
|
| -
|
| - 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, RevivedStreamFrame) {
|
| - unsigned char payload[] = {
|
| - // 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', '!',
|
| - };
|
| -
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = true;
|
| - header.entropy_flag = true;
|
| - header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
|
| - header.fec_group = 0;
|
| -
|
| - // Do not encrypt the payload because the revived payload is post-encryption.
|
| - EXPECT_TRUE(framer_.ProcessRevivedPacket(&header,
|
| - StringPiece(AsChars(payload),
|
| - arraysize(payload))));
|
| -
|
| - EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
|
| - ASSERT_EQ(1, visitor_.revived_packets_);
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
|
| - visitor_.header_->public_header.connection_id);
|
| - EXPECT_FALSE(visitor_.header_->public_header.reset_flag);
|
| - EXPECT_FALSE(visitor_.header_->public_header.version_flag);
|
| - EXPECT_TRUE(visitor_.header_->fec_flag);
|
| - EXPECT_TRUE(visitor_.header_->entropy_flag);
|
| - EXPECT_EQ(1 << (header.packet_sequence_number % 8),
|
| - visitor_.header_->entropy_hash);
|
| - EXPECT_EQ(GG_UINT64_C(0x123456789ABC),
|
| - visitor_.header_->packet_sequence_number);
|
| - EXPECT_EQ(NOT_IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
|
| - EXPECT_EQ(0x00u, visitor_.header_->fec_group);
|
| -
|
| - ASSERT_EQ(1u, visitor_.stream_frames_.size());
|
| - EXPECT_EQ(0u, visitor_.ack_frames_.size());
|
| - EXPECT_EQ(GG_UINT64_C(0x01020304), visitor_.stream_frames_[0]->stream_id);
|
| - EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
|
| - EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654),
|
| - visitor_.stream_frames_[0]->offset);
|
| - CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, StreamFrameInFecGroup) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x12, 0x34,
|
| - // private flags (fec group)
|
| - 0x02,
|
| - // first fec protected packet offset
|
| - 0x02,
|
| -
|
| - // 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', '!',
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_TRUE(framer_.ProcessPacket(encrypted));
|
| -
|
| - EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
|
| - EXPECT_EQ(IN_FEC_GROUP, visitor_.header_->is_in_fec_group);
|
| - EXPECT_EQ(GG_UINT64_C(0x341256789ABA),
|
| - visitor_.header_->fec_group);
|
| - const size_t fec_offset =
|
| - GetStartOfFecProtectedData(PACKET_8BYTE_CONNECTION_ID,
|
| - !kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER);
|
| - EXPECT_EQ(
|
| - string(AsChars(packet) + fec_offset, arraysize(packet) - fec_offset),
|
| - visitor_.fec_protected_payload_);
|
| -
|
| - ASSERT_EQ(1u, visitor_.stream_frames_.size());
|
| - EXPECT_EQ(0u, visitor_.ack_frames_.size());
|
| - EXPECT_EQ(GG_UINT64_C(0x01020304), visitor_.stream_frames_[0]->stream_id);
|
| - EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
|
| - EXPECT_EQ(GG_UINT64_C(0xBA98FEDC32107654),
|
| - visitor_.stream_frames_[0]->offset);
|
| - CheckStreamFrameData("hello world!", visitor_.stream_frames_[0]);
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, AckFrameTwoTimestamp) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12,
|
| - // private flags (entropy)
|
| - 0x01,
|
| -
|
| - // frame type (ack frame)
|
| - // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
|
| - 0x6C,
|
| - // entropy hash of all received packets.
|
| - 0xBA,
|
| - // largest observed packet sequence number
|
| - 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12,
|
| - // Zero delta time.
|
| - 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,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_TRUE(framer_.ProcessPacket(encrypted));
|
| -
|
| - EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
|
| -
|
| - EXPECT_EQ(0u, visitor_.stream_frames_.size());
|
| - ASSERT_EQ(1u, visitor_.ack_frames_.size());
|
| - const QuicAckFrame& frame = *visitor_.ack_frames_[0];
|
| - EXPECT_EQ(0xBA, frame.entropy_hash);
|
| - EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed);
|
| - ASSERT_EQ(1u, frame.missing_packets.size());
|
| - ASSERT_EQ(2u, frame.received_packet_times.size());
|
| - SequenceNumberSet::const_iterator missing_iter =
|
| - frame.missing_packets.begin();
|
| - EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter);
|
| -
|
| - const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
|
| - const size_t kLargestObservedOffset = kReceivedEntropyOffset +
|
| - kQuicEntropyHashSize;
|
| - const size_t kMissingDeltaTimeOffset = kLargestObservedOffset +
|
| - PACKET_6BYTE_SEQUENCE_NUMBER;
|
| - const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset +
|
| - kQuicDeltaTimeLargestObservedSize;
|
| - const size_t kTimestampDeltaLargestObserved1 = kNumTimestampsOffset +
|
| - kQuicNumTimestampsSize;
|
| - const size_t kTimestampTimeDeltaLargestObserved1 =
|
| - kTimestampDeltaLargestObserved1 + 1;
|
| - const size_t kTimestampDeltaLargestObserved2 =
|
| - kTimestampTimeDeltaLargestObserved1 + 4;
|
| - const size_t kTimestampTimeDeltaLargestObserved2 =
|
| - kTimestampDeltaLargestObserved2 + 1;
|
| - const size_t kNumMissingPacketOffset =
|
| - kTimestampTimeDeltaLargestObserved2 + 2;
|
| - const size_t kMissingPacketsOffset = kNumMissingPacketOffset +
|
| - kNumberOfNackRangesSize;
|
| - const size_t kMissingPacketsRange = kMissingPacketsOffset +
|
| - PACKET_1BYTE_SEQUENCE_NUMBER;
|
| - const size_t kRevivedPacketsLength = kMissingPacketsRange +
|
| - PACKET_1BYTE_SEQUENCE_NUMBER;
|
| - // Now test framing boundaries.
|
| - const size_t ack_frame_size = kRevivedPacketsLength +
|
| - PACKET_1BYTE_SEQUENCE_NUMBER;
|
| - for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) {
|
| - string expected_error;
|
| - if (i < kLargestObservedOffset) {
|
| - expected_error = "Unable to read entropy hash for received packets.";
|
| - } else if (i < kMissingDeltaTimeOffset) {
|
| - expected_error = "Unable to read largest observed.";
|
| - } else if (i < kNumTimestampsOffset) {
|
| - expected_error = "Unable to read delta time largest observed.";
|
| - } else if (i < kTimestampDeltaLargestObserved1) {
|
| - expected_error = "Unable to read num received packets.";
|
| - } else if (i < kTimestampTimeDeltaLargestObserved1) {
|
| - expected_error = "Unable to read sequence delta in received packets.";
|
| - } else if (i < kTimestampDeltaLargestObserved2) {
|
| - expected_error = "Unable to read time delta in received packets.";
|
| - } else if (i < kTimestampTimeDeltaLargestObserved2) {
|
| - expected_error = "Unable to read sequence delta in received packets.";
|
| - } else if (i < kNumMissingPacketOffset) {
|
| - expected_error =
|
| - "Unable to read incremental time delta in received packets.";
|
| - } else if (i < kMissingPacketsOffset) {
|
| - expected_error = "Unable to read num missing packet ranges.";
|
| - } else if (i < kMissingPacketsRange) {
|
| - expected_error = "Unable to read missing sequence number delta.";
|
| - } else if (i < kRevivedPacketsLength) {
|
| - expected_error = "Unable to read missing sequence number range.";
|
| - } else {
|
| - expected_error = "Unable to read num revived packets.";
|
| - }
|
| - CheckProcessingFails(
|
| - packet,
|
| - i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
|
| - expected_error, QUIC_INVALID_ACK_DATA);
|
| - }
|
| -}
|
| -
|
| -
|
| -TEST_P(QuicFramerTest, AckFrameOneTimestamp) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12,
|
| - // private flags (entropy)
|
| - 0x01,
|
| -
|
| - // frame type (ack frame)
|
| - // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
|
| - 0x6C,
|
| - // entropy hash of all received packets.
|
| - 0xBA,
|
| - // largest observed packet sequence number
|
| - 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12,
|
| - // Zero delta time.
|
| - 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,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_TRUE(framer_.ProcessPacket(encrypted));
|
| -
|
| - EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
|
| -
|
| - EXPECT_EQ(0u, visitor_.stream_frames_.size());
|
| - ASSERT_EQ(1u, visitor_.ack_frames_.size());
|
| - const QuicAckFrame& frame = *visitor_.ack_frames_[0];
|
| - EXPECT_EQ(0xBA, frame.entropy_hash);
|
| - EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed);
|
| - ASSERT_EQ(1u, frame.missing_packets.size());
|
| - ASSERT_EQ(1u, frame.received_packet_times.size());
|
| - SequenceNumberSet::const_iterator missing_iter =
|
| - frame.missing_packets.begin();
|
| - EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter);
|
| -
|
| - const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
|
| - const size_t kLargestObservedOffset = kReceivedEntropyOffset +
|
| - kQuicEntropyHashSize;
|
| - const size_t kMissingDeltaTimeOffset = kLargestObservedOffset +
|
| - PACKET_6BYTE_SEQUENCE_NUMBER;
|
| - const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset +
|
| - kQuicDeltaTimeLargestObservedSize;
|
| - const size_t kTimestampDeltaLargestObserved = kNumTimestampsOffset +
|
| - kQuicNumTimestampsSize;
|
| - const size_t kTimestampTimeDeltaLargestObserved =
|
| - kTimestampDeltaLargestObserved + 1;
|
| - const size_t kNumMissingPacketOffset = kTimestampTimeDeltaLargestObserved + 4;
|
| - const size_t kMissingPacketsOffset = kNumMissingPacketOffset +
|
| - kNumberOfNackRangesSize;
|
| - const size_t kMissingPacketsRange = kMissingPacketsOffset +
|
| - PACKET_1BYTE_SEQUENCE_NUMBER;
|
| - const size_t kRevivedPacketsLength = kMissingPacketsRange +
|
| - PACKET_1BYTE_SEQUENCE_NUMBER;
|
| - // Now test framing boundaries.
|
| - const size_t ack_frame_size = kRevivedPacketsLength +
|
| - PACKET_1BYTE_SEQUENCE_NUMBER;
|
| - for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) {
|
| - string expected_error;
|
| - if (i < kLargestObservedOffset) {
|
| - expected_error = "Unable to read entropy hash for received packets.";
|
| - } else if (i < kMissingDeltaTimeOffset) {
|
| - expected_error = "Unable to read largest observed.";
|
| - } else if (i < kNumTimestampsOffset) {
|
| - expected_error = "Unable to read delta time largest observed.";
|
| - } else if (i < kTimestampDeltaLargestObserved) {
|
| - expected_error = "Unable to read num received packets.";
|
| - } else if (i < kTimestampTimeDeltaLargestObserved) {
|
| - expected_error = "Unable to read sequence delta in received packets.";
|
| - } else if (i < kNumMissingPacketOffset) {
|
| - expected_error = "Unable to read time delta in received packets.";
|
| - } else if (i < kMissingPacketsOffset) {
|
| - expected_error = "Unable to read num missing packet ranges.";
|
| - } else if (i < kMissingPacketsRange) {
|
| - expected_error = "Unable to read missing sequence number delta.";
|
| - } else if (i < kRevivedPacketsLength) {
|
| - expected_error = "Unable to read missing sequence number range.";
|
| - } else {
|
| - expected_error = "Unable to read num revived packets.";
|
| - }
|
| - CheckProcessingFails(
|
| - packet,
|
| - i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
|
| - expected_error, QUIC_INVALID_ACK_DATA);
|
| - }
|
| -}
|
| -
|
| -
|
| -TEST_P(QuicFramerTest, AckFrame) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12,
|
| - // private flags (entropy)
|
| - 0x01,
|
| -
|
| - // frame type (ack frame)
|
| - // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
|
| - 0x6C,
|
| - // entropy hash of all received packets.
|
| - 0xBA,
|
| - // largest observed packet sequence number
|
| - 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12,
|
| - // Zero delta time.
|
| - 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,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_TRUE(framer_.ProcessPacket(encrypted));
|
| -
|
| - EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
|
| -
|
| - EXPECT_EQ(0u, visitor_.stream_frames_.size());
|
| - ASSERT_EQ(1u, visitor_.ack_frames_.size());
|
| - const QuicAckFrame& frame = *visitor_.ack_frames_[0];
|
| - EXPECT_EQ(0xBA, frame.entropy_hash);
|
| - EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed);
|
| - ASSERT_EQ(1u, frame.missing_packets.size());
|
| - SequenceNumberSet::const_iterator missing_iter =
|
| - frame.missing_packets.begin();
|
| - EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter);
|
| -
|
| - const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
|
| - const size_t kLargestObservedOffset = kReceivedEntropyOffset +
|
| - kQuicEntropyHashSize;
|
| - const size_t kMissingDeltaTimeOffset = kLargestObservedOffset +
|
| - PACKET_6BYTE_SEQUENCE_NUMBER;
|
| - const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset +
|
| - kQuicDeltaTimeLargestObservedSize;
|
| - const size_t kNumMissingPacketOffset = kNumTimestampsOffset +
|
| - kQuicNumTimestampsSize;
|
| - const size_t kMissingPacketsOffset = kNumMissingPacketOffset +
|
| - kNumberOfNackRangesSize;
|
| - const size_t kMissingPacketsRange = kMissingPacketsOffset +
|
| - PACKET_1BYTE_SEQUENCE_NUMBER;
|
| - const size_t kRevivedPacketsLength = kMissingPacketsRange +
|
| - PACKET_1BYTE_SEQUENCE_NUMBER;
|
| - // Now test framing boundaries.
|
| - const size_t ack_frame_size = kRevivedPacketsLength +
|
| - PACKET_1BYTE_SEQUENCE_NUMBER;
|
| - for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) {
|
| - string expected_error;
|
| - if (i < kLargestObservedOffset) {
|
| - expected_error = "Unable to read entropy hash for received packets.";
|
| - } else if (i < kMissingDeltaTimeOffset) {
|
| - expected_error = "Unable to read largest observed.";
|
| - } else if (i < kNumTimestampsOffset) {
|
| - expected_error = "Unable to read delta time largest observed.";
|
| - } else if (i < kNumMissingPacketOffset) {
|
| - expected_error = "Unable to read num received packets.";
|
| - } else if (i < kMissingPacketsOffset) {
|
| - expected_error = "Unable to read num missing packet ranges.";
|
| - } else if (i < kMissingPacketsRange) {
|
| - expected_error = "Unable to read missing sequence number delta.";
|
| - } else if (i < kRevivedPacketsLength) {
|
| - expected_error = "Unable to read missing sequence number range.";
|
| - } else {
|
| - expected_error = "Unable to read num revived packets.";
|
| - }
|
| - CheckProcessingFails(
|
| - packet,
|
| - i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
|
| - expected_error, QUIC_INVALID_ACK_DATA);
|
| - }
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, AckFrameRevivedPackets) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12,
|
| - // private flags (entropy)
|
| - 0x01,
|
| -
|
| - // frame type (ack frame)
|
| - // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
|
| - 0x6C,
|
| - // entropy hash of all received packets.
|
| - 0xBA,
|
| - // largest observed packet sequence number
|
| - 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12,
|
| - // Zero delta time.
|
| - 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 sequence number.
|
| - 0xBE, 0x9A, 0x78, 0x56, 0x34, 0x12,
|
| - // Number of revived packets.
|
| - 0x00,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_TRUE(framer_.ProcessPacket(encrypted));
|
| -
|
| - EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
|
| -
|
| - EXPECT_EQ(0u, visitor_.stream_frames_.size());
|
| - ASSERT_EQ(1u, visitor_.ack_frames_.size());
|
| - const QuicAckFrame& frame = *visitor_.ack_frames_[0];
|
| - EXPECT_EQ(0xBA, frame.entropy_hash);
|
| - EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.largest_observed);
|
| - ASSERT_EQ(1u, frame.missing_packets.size());
|
| - SequenceNumberSet::const_iterator missing_iter =
|
| - frame.missing_packets.begin();
|
| - EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter);
|
| -
|
| - const size_t kReceivedEntropyOffset = kQuicFrameTypeSize;
|
| - const size_t kLargestObservedOffset = kReceivedEntropyOffset +
|
| - kQuicEntropyHashSize;
|
| - const size_t kMissingDeltaTimeOffset = kLargestObservedOffset +
|
| - PACKET_6BYTE_SEQUENCE_NUMBER;
|
| - const size_t kNumTimestampsOffset = kMissingDeltaTimeOffset +
|
| - kQuicDeltaTimeLargestObservedSize;
|
| - const size_t kNumMissingPacketOffset = kNumTimestampsOffset +
|
| - kQuicNumTimestampsSize;
|
| - const size_t kMissingPacketsOffset = kNumMissingPacketOffset +
|
| - kNumberOfNackRangesSize;
|
| - const size_t kMissingPacketsRange = kMissingPacketsOffset +
|
| - PACKET_1BYTE_SEQUENCE_NUMBER;
|
| - const size_t kRevivedPacketsLength = kMissingPacketsRange +
|
| - PACKET_1BYTE_SEQUENCE_NUMBER;
|
| - const size_t kRevivedPacketSequenceNumberLength = kRevivedPacketsLength +
|
| - PACKET_1BYTE_SEQUENCE_NUMBER;
|
| - // Now test framing boundaries.
|
| - const size_t ack_frame_size = kRevivedPacketSequenceNumberLength +
|
| - PACKET_6BYTE_SEQUENCE_NUMBER;
|
| - for (size_t i = kQuicFrameTypeSize; i < ack_frame_size; ++i) {
|
| - string expected_error;
|
| - if (i < kReceivedEntropyOffset) {
|
| - expected_error = "Unable to read least unacked delta.";
|
| - } else if (i < kLargestObservedOffset) {
|
| - expected_error = "Unable to read entropy hash for received packets.";
|
| - } else if (i < kMissingDeltaTimeOffset) {
|
| - expected_error = "Unable to read largest observed.";
|
| - } else if (i < kNumTimestampsOffset) {
|
| - expected_error = "Unable to read delta time largest observed.";
|
| - } else if (i < kNumMissingPacketOffset) {
|
| - expected_error = "Unable to read num received packets.";
|
| - } else if (i < kMissingPacketsOffset) {
|
| - expected_error = "Unable to read num missing packet ranges.";
|
| - } else if (i < kMissingPacketsRange) {
|
| - expected_error = "Unable to read missing sequence number delta.";
|
| - } else if (i < kRevivedPacketsLength) {
|
| - expected_error = "Unable to read missing sequence number range.";
|
| - } else if (i < kRevivedPacketSequenceNumberLength) {
|
| - expected_error = "Unable to read num revived packets.";
|
| - } else {
|
| - expected_error = "Unable to read revived packet.";
|
| - }
|
| - CheckProcessingFails(
|
| - packet,
|
| - i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
|
| - expected_error, QUIC_INVALID_ACK_DATA);
|
| - }
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, AckFrameNoNacks) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12,
|
| - // private flags (entropy)
|
| - 0x01,
|
| -
|
| - // frame type (ack frame)
|
| - // (no nacks, not truncated, 6 byte largest observed, 1 byte delta)
|
| - 0x4C,
|
| - // entropy hash of all received packets.
|
| - 0xBA,
|
| - // largest observed packet sequence number
|
| - 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12,
|
| - // Zero delta time.
|
| - 0x00, 0x00,
|
| - // Number of received packets.
|
| - 0x00,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_TRUE(framer_.ProcessPacket(encrypted));
|
| -
|
| - EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
|
| -
|
| - EXPECT_EQ(0u, visitor_.stream_frames_.size());
|
| - ASSERT_EQ(1u, visitor_.ack_frames_.size());
|
| - QuicAckFrame* frame = visitor_.ack_frames_[0];
|
| - EXPECT_EQ(0xBA, frame->entropy_hash);
|
| - EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame->largest_observed);
|
| - ASSERT_EQ(0u, frame->missing_packets.size());
|
| -
|
| - // Verify that the packet re-serializes identically.
|
| - QuicFrames frames;
|
| - frames.push_back(QuicFrame(frame));
|
| - scoped_ptr<QuicPacket> data(BuildDataPacket(*visitor_.header_, frames));
|
| - ASSERT_TRUE(data != nullptr);
|
| -
|
| - test::CompareCharArraysWithHexError("constructed packet", data->data(),
|
| - data->length(), AsChars(packet),
|
| - arraysize(packet));
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, AckFrame500Nacks) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12,
|
| - // private flags (entropy)
|
| - 0x01,
|
| -
|
| - // frame type (ack frame)
|
| - // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
|
| - 0x6C,
|
| - // entropy hash of all received packets.
|
| - 0xBA,
|
| - // largest observed packet sequence number
|
| - 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12,
|
| - // Zero delta time.
|
| - 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,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_TRUE(framer_.ProcessPacket(encrypted));
|
| -
|
| - EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
|
| -
|
| - EXPECT_EQ(0u, visitor_.stream_frames_.size());
|
| - ASSERT_EQ(1u, visitor_.ack_frames_.size());
|
| - QuicAckFrame* frame = visitor_.ack_frames_[0];
|
| - EXPECT_EQ(0xBA, frame->entropy_hash);
|
| - EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame->largest_observed);
|
| - EXPECT_EQ(0u, frame->revived_packets.size());
|
| - ASSERT_EQ(500u, frame->missing_packets.size());
|
| - SequenceNumberSet::const_iterator first_missing_iter =
|
| - frame->missing_packets.begin();
|
| - EXPECT_EQ(GG_UINT64_C(0x0123456789ABE) - 499, *first_missing_iter);
|
| - SequenceNumberSet::const_reverse_iterator last_missing_iter =
|
| - frame->missing_packets.rbegin();
|
| - EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *last_missing_iter);
|
| -
|
| - // Verify that the packet re-serializes identically.
|
| - QuicFrames frames;
|
| - frames.push_back(QuicFrame(frame));
|
| - scoped_ptr<QuicPacket> data(BuildDataPacket(*visitor_.header_, frames));
|
| - ASSERT_TRUE(data != nullptr);
|
| -
|
| - test::CompareCharArraysWithHexError("constructed packet",
|
| - data->data(), data->length(),
|
| - AsChars(packet), arraysize(packet));
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, StopWaitingFrame) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xA8, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags (entropy)
|
| - 0x01,
|
| -
|
| - // frame type (ack frame)
|
| - // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
|
| - 0x06,
|
| - // entropy hash of sent packets till least awaiting - 1.
|
| - 0xAB,
|
| - // least packet sequence number awaiting an ack, delta from sequence number.
|
| - 0x08, 0x00, 0x00, 0x00,
|
| - 0x00, 0x00,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_TRUE(framer_.ProcessPacket(encrypted));
|
| -
|
| - EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
|
| -
|
| - EXPECT_EQ(0u, visitor_.stream_frames_.size());
|
| - ASSERT_EQ(1u, visitor_.stop_waiting_frames_.size());
|
| - const QuicStopWaitingFrame& frame = *visitor_.stop_waiting_frames_[0];
|
| - EXPECT_EQ(0xAB, frame.entropy_hash);
|
| - EXPECT_EQ(GG_UINT64_C(0x0123456789AA0), frame.least_unacked);
|
| -
|
| - const size_t kSentEntropyOffset = kQuicFrameTypeSize;
|
| - const size_t kLeastUnackedOffset = kSentEntropyOffset + kQuicEntropyHashSize;
|
| - const size_t frame_size = 7;
|
| - for (size_t i = kQuicFrameTypeSize; i < frame_size; ++i) {
|
| - string expected_error;
|
| - if (i < kLeastUnackedOffset) {
|
| - expected_error = "Unable to read entropy hash for sent packets.";
|
| - } else {
|
| - expected_error = "Unable to read least unacked delta.";
|
| - }
|
| - CheckProcessingFails(
|
| - packet,
|
| - i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
|
| - expected_error, QUIC_INVALID_STOP_WAITING_DATA);
|
| - }
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, RstStreamFrameQuic) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (rst stream frame)
|
| - 0x01,
|
| - // stream id
|
| - 0x04, 0x03, 0x02, 0x01,
|
| -
|
| - // sent byte offset
|
| - 0x01, 0x02, 0x03, 0x04,
|
| - 0x05, 0x06, 0x07, 0x08,
|
| -
|
| - // error code
|
| - 0x01, 0x00, 0x00, 0x00,
|
| -
|
| - // error details length
|
| - 0x0d, 0x00,
|
| - // error details
|
| - 'b', 'e', 'c', 'a',
|
| - 'u', 's', 'e', ' ',
|
| - 'I', ' ', 'c', 'a',
|
| - 'n',
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_TRUE(framer_.ProcessPacket(encrypted));
|
| -
|
| - EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
|
| -
|
| - EXPECT_EQ(GG_UINT64_C(0x01020304), visitor_.rst_stream_frame_.stream_id);
|
| - EXPECT_EQ(0x01, visitor_.rst_stream_frame_.error_code);
|
| - EXPECT_EQ("because I can", visitor_.rst_stream_frame_.error_details);
|
| - EXPECT_EQ(GG_UINT64_C(0x0807060504030201),
|
| - visitor_.rst_stream_frame_.byte_offset);
|
| -
|
| - // Now test framing boundaries.
|
| - for (size_t i = kQuicFrameTypeSize;
|
| - i < QuicFramer::GetMinRstStreamFrameSize(); ++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.";
|
| - } else {
|
| - expected_error = "Unable to read rst stream error details.";
|
| - }
|
| - CheckProcessingFails(
|
| - packet,
|
| - i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
|
| - expected_error, QUIC_INVALID_RST_STREAM_DATA);
|
| - }
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, ConnectionCloseFrame) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (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',
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_TRUE(framer_.ProcessPacket(encrypted));
|
| -
|
| - EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
|
| -
|
| - EXPECT_EQ(0u, visitor_.stream_frames_.size());
|
| -
|
| - 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(
|
| - packet,
|
| - i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
|
| - expected_error, QUIC_INVALID_CONNECTION_CLOSE_DATA);
|
| - }
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, GoAwayFrame) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (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',
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_TRUE(framer_.ProcessPacket(encrypted));
|
| -
|
| - EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
|
| -
|
| - EXPECT_EQ(GG_UINT64_C(0x01020304),
|
| - visitor_.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(
|
| - packet,
|
| - i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
|
| - expected_error, QUIC_INVALID_GOAWAY_DATA);
|
| - }
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, WindowUpdateFrame) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (window update frame)
|
| - 0x04,
|
| - // stream id
|
| - 0x04, 0x03, 0x02, 0x01,
|
| - // byte offset
|
| - 0x05, 0x06, 0x07, 0x08,
|
| - 0x09, 0x0a, 0x0b, 0x0c,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| -
|
| - EXPECT_TRUE(framer_.ProcessPacket(encrypted));
|
| -
|
| - EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
|
| -
|
| - EXPECT_EQ(GG_UINT64_C(0x01020304),
|
| - visitor_.window_update_frame_.stream_id);
|
| - EXPECT_EQ(GG_UINT64_C(0x0c0b0a0908070605),
|
| - 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(
|
| - packet,
|
| - i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
|
| - expected_error, QUIC_INVALID_WINDOW_UPDATE_DATA);
|
| - }
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, BlockedFrame) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (blocked frame)
|
| - 0x05,
|
| - // stream id
|
| - 0x04, 0x03, 0x02, 0x01,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| -
|
| - EXPECT_TRUE(framer_.ProcessPacket(encrypted));
|
| -
|
| - EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
|
| -
|
| - EXPECT_EQ(GG_UINT64_C(0x01020304),
|
| - visitor_.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(
|
| - packet,
|
| - i + GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP),
|
| - expected_error, QUIC_INVALID_BLOCKED_DATA);
|
| - }
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, PingFrame) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (ping frame)
|
| - 0x07,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_TRUE(framer_.ProcessPacket(encrypted));
|
| -
|
| - EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
|
| -
|
| - EXPECT_EQ(1u, visitor_.ping_frames_.size());
|
| -
|
| - // No need to check the PING frame boundaries because it has no payload.
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, PublicResetPacket) {
|
| - unsigned char packet[] = {
|
| - // public flags (public reset, 8 byte connection_id)
|
| - 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 sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12, 0x00, 0x00,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_TRUE(framer_.ProcessPacket(encrypted));
|
| - ASSERT_EQ(QUIC_NO_ERROR, framer_.error());
|
| - ASSERT_TRUE(visitor_.public_reset_packet_.get());
|
| - EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
|
| - visitor_.public_reset_packet_->public_header.connection_id);
|
| - EXPECT_TRUE(visitor_.public_reset_packet_->public_header.reset_flag);
|
| - EXPECT_FALSE(visitor_.public_reset_packet_->public_header.version_flag);
|
| - EXPECT_EQ(GG_UINT64_C(0xABCDEF0123456789),
|
| - visitor_.public_reset_packet_->nonce_proof);
|
| - EXPECT_EQ(GG_UINT64_C(0x123456789ABC),
|
| - visitor_.public_reset_packet_->rejected_sequence_number);
|
| - EXPECT_TRUE(
|
| - visitor_.public_reset_packet_->client_address.address().empty());
|
| -
|
| - // Now test framing boundaries.
|
| - for (size_t i = 0; i < arraysize(packet); ++i) {
|
| - string expected_error;
|
| - DVLOG(1) << "iteration: " << i;
|
| - if (i < kConnectionIdOffset) {
|
| - expected_error = "Unable to read public flags.";
|
| - CheckProcessingFails(packet, i, expected_error,
|
| - QUIC_INVALID_PACKET_HEADER);
|
| - } else if (i < 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) {
|
| - 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 sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12, 0x00, 0x00,
|
| - // trailing junk
|
| - 'j', 'u', 'n', 'k',
|
| - };
|
| -
|
| - string expected_error = "Unable to read reset message.";
|
| - CheckProcessingFails(packet, arraysize(packet), expected_error,
|
| - QUIC_INVALID_PUBLIC_RST_PACKET);
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, PublicResetPacketWithClientAddress) {
|
| - 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 (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 sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12, 0x00, 0x00,
|
| - // client address: 4.31.198.44:443
|
| - 0x02, 0x00,
|
| - 0x04, 0x1F, 0xC6, 0x2C,
|
| - 0xBB, 0x01,
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_TRUE(framer_.ProcessPacket(encrypted));
|
| - ASSERT_EQ(QUIC_NO_ERROR, framer_.error());
|
| - ASSERT_TRUE(visitor_.public_reset_packet_.get());
|
| - EXPECT_EQ(GG_UINT64_C(0xFEDCBA9876543210),
|
| - visitor_.public_reset_packet_->public_header.connection_id);
|
| - EXPECT_TRUE(visitor_.public_reset_packet_->public_header.reset_flag);
|
| - EXPECT_FALSE(visitor_.public_reset_packet_->public_header.version_flag);
|
| - EXPECT_EQ(GG_UINT64_C(0xABCDEF0123456789),
|
| - visitor_.public_reset_packet_->nonce_proof);
|
| - EXPECT_EQ(GG_UINT64_C(0x123456789ABC),
|
| - visitor_.public_reset_packet_->rejected_sequence_number);
|
| - EXPECT_EQ("4.31.198.44",
|
| - IPAddressToString(visitor_.public_reset_packet_->
|
| - client_address.address()));
|
| - 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) {
|
| - 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',
|
| - };
|
| -
|
| - QuicFramerPeer::SetIsServer(&framer_, false);
|
| -
|
| - 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, FecPacket) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags (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',
|
| - };
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_TRUE(framer_.ProcessPacket(encrypted));
|
| -
|
| - EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
|
| - ASSERT_TRUE(visitor_.header_.get());
|
| - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion));
|
| -
|
| - EXPECT_EQ(0u, visitor_.stream_frames_.size());
|
| - EXPECT_EQ(0u, visitor_.ack_frames_.size());
|
| - ASSERT_EQ(1, visitor_.fec_count_);
|
| - const QuicFecData& fec_data = *visitor_.fec_data_[0];
|
| - EXPECT_EQ(GG_UINT64_C(0x0123456789ABB), fec_data.fec_group);
|
| - EXPECT_EQ("abcdefghijklmnop", fec_data.redundancy);
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = false;
|
| - header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
|
| - header.fec_group = 0;
|
| -
|
| - QuicPaddingFrame padding_frame;
|
| -
|
| - QuicFrames frames;
|
| - frames.push_back(QuicFrame(&padding_frame));
|
| -
|
| - unsigned char packet[kMaxPacketSize] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (padding frame)
|
| - 0x00,
|
| - 0x00, 0x00, 0x00, 0x00
|
| - };
|
| -
|
| - uint64 header_size =
|
| - GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
|
| - memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
|
| -
|
| - scoped_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, Build4ByteSequenceNumberPaddingFramePacket) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = false;
|
| - header.public_header.sequence_number_length = PACKET_4BYTE_SEQUENCE_NUMBER;
|
| - header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
|
| - header.fec_group = 0;
|
| -
|
| - QuicPaddingFrame padding_frame;
|
| -
|
| - QuicFrames frames;
|
| - frames.push_back(QuicFrame(&padding_frame));
|
| -
|
| - unsigned char packet[kMaxPacketSize] = {
|
| - // public flags (8 byte connection_id and 4 byte sequence number)
|
| - 0x2C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (padding frame)
|
| - 0x00,
|
| - 0x00, 0x00, 0x00, 0x00
|
| - };
|
| -
|
| - uint64 header_size =
|
| - GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_4BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
|
| - memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
|
| -
|
| - scoped_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, Build2ByteSequenceNumberPaddingFramePacket) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = false;
|
| - header.public_header.sequence_number_length = PACKET_2BYTE_SEQUENCE_NUMBER;
|
| - header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
|
| - header.fec_group = 0;
|
| -
|
| - QuicPaddingFrame padding_frame;
|
| -
|
| - QuicFrames frames;
|
| - frames.push_back(QuicFrame(&padding_frame));
|
| -
|
| - unsigned char packet[kMaxPacketSize] = {
|
| - // public flags (8 byte connection_id and 2 byte sequence number)
|
| - 0x1C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (padding frame)
|
| - 0x00,
|
| - 0x00, 0x00, 0x00, 0x00
|
| - };
|
| -
|
| - uint64 header_size =
|
| - GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_2BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
|
| - memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
|
| -
|
| - scoped_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, Build1ByteSequenceNumberPaddingFramePacket) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = false;
|
| - header.public_header.sequence_number_length = PACKET_1BYTE_SEQUENCE_NUMBER;
|
| - header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
|
| - header.fec_group = 0;
|
| -
|
| - QuicPaddingFrame padding_frame;
|
| -
|
| - QuicFrames frames;
|
| - frames.push_back(QuicFrame(&padding_frame));
|
| -
|
| - unsigned char packet[kMaxPacketSize] = {
|
| - // public flags (8 byte connection_id and 1 byte sequence number)
|
| - 0x0C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (padding frame)
|
| - 0x00,
|
| - 0x00, 0x00, 0x00, 0x00
|
| - };
|
| -
|
| - uint64 header_size =
|
| - GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
|
| - PACKET_1BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
|
| - memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1);
|
| -
|
| - scoped_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, BuildStreamFramePacket) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = true;
|
| - header.packet_sequence_number = GG_UINT64_C(0x77123456789ABC);
|
| - header.fec_group = 0;
|
| -
|
| - QuicStreamFrame stream_frame;
|
| - stream_frame.stream_id = 0x01020304;
|
| - stream_frame.fin = true;
|
| - stream_frame.offset = GG_UINT64_C(0xBA98FEDC32107654);
|
| - stream_frame.data = MakeIOVector("hello world!");
|
| -
|
| - QuicFrames frames;
|
| - frames.push_back(QuicFrame(&stream_frame));
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags (entropy)
|
| - 0x01,
|
| -
|
| - // frame type (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', '!',
|
| - };
|
| -
|
| - scoped_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, BuildStreamFramePacketInFecGroup) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = true;
|
| - header.packet_sequence_number = GG_UINT64_C(0x77123456789ABC);
|
| - header.is_in_fec_group = IN_FEC_GROUP;
|
| - header.fec_group = GG_UINT64_C(0x77123456789ABC);
|
| -
|
| - QuicStreamFrame stream_frame;
|
| - stream_frame.stream_id = 0x01020304;
|
| - stream_frame.fin = true;
|
| - stream_frame.offset = GG_UINT64_C(0xBA98FEDC32107654);
|
| - stream_frame.data = MakeIOVector("hello world!");
|
| -
|
| - QuicFrames frames;
|
| - frames.push_back(QuicFrame(&stream_frame));
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
|
| - // private flags (entropy, is_in_fec_group)
|
| - 0x03,
|
| - // FEC group
|
| - 0x00,
|
| - // frame type (stream frame with fin and data length field)
|
| - 0xFF,
|
| - // stream id
|
| - 0x04, 0x03, 0x02, 0x01,
|
| - // offset
|
| - 0x54, 0x76, 0x10, 0x32, 0xDC, 0xFE, 0x98, 0xBA,
|
| - // data length (since packet is in an FEC group)
|
| - 0x0C, 0x00,
|
| - // data
|
| - 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!',
|
| - };
|
| -
|
| - scoped_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, BuildStreamFramePacketWithVersionFlag) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = true;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = true;
|
| - header.packet_sequence_number = GG_UINT64_C(0x77123456789ABC);
|
| - header.fec_group = 0;
|
| -
|
| - QuicStreamFrame stream_frame;
|
| - stream_frame.stream_id = 0x01020304;
|
| - stream_frame.fin = true;
|
| - stream_frame.offset = GG_UINT64_C(0xBA98FEDC32107654);
|
| - stream_frame.data = MakeIOVector("hello world!");
|
| -
|
| - QuicFrames frames;
|
| - frames.push_back(QuicFrame(&stream_frame));
|
| -
|
| - 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(),
|
| - // packet sequence 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',
|
| - '!',
|
| - };
|
| -
|
| - QuicFramerPeer::SetIsServer(&framer_, false);
|
| - scoped_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, BuildVersionNegotiationPacket) {
|
| - QuicPacketPublicHeader header;
|
| - header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.reset_flag = false;
|
| - header.version_flag = true;
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (version, 8 byte connection_id)
|
| - 0x0D,
|
| - // connection_id
|
| - 0x10,
|
| - 0x32,
|
| - 0x54,
|
| - 0x76,
|
| - 0x98,
|
| - 0xBA,
|
| - 0xDC,
|
| - 0xFE,
|
| - // version tag
|
| - 'Q',
|
| - '0',
|
| - GetQuicVersionDigitTens(),
|
| - GetQuicVersionDigitOnes(),
|
| - };
|
| -
|
| - QuicVersionVector versions;
|
| - versions.push_back(GetParam());
|
| - scoped_ptr<QuicEncryptedPacket> data(
|
| - framer_.BuildVersionNegotiationPacket(header, versions));
|
| -
|
| - test::CompareCharArraysWithHexError("constructed packet", data->data(),
|
| - data->length(), AsChars(packet),
|
| - arraysize(packet));
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, BuildAckFramePacket) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = true;
|
| - header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8);
|
| - header.fec_group = 0;
|
| -
|
| - QuicAckFrame ack_frame;
|
| - ack_frame.entropy_hash = 0x43;
|
| - ack_frame.largest_observed = GG_UINT64_C(0x770123456789ABF);
|
| - ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero();
|
| - ack_frame.missing_packets.insert(GG_UINT64_C(0x770123456789ABE));
|
| -
|
| - QuicFrames frames;
|
| - frames.push_back(QuicFrame(&ack_frame));
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12,
|
| - // private flags (entropy)
|
| - 0x01,
|
| -
|
| - // frame type (ack frame)
|
| - // (has nacks, not truncated, 6 byte largest observed, 1 byte delta)
|
| - 0x6C,
|
| - // entropy hash of all received packets.
|
| - 0x43,
|
| - // largest observed packet sequence number
|
| - 0xBF, 0x9A, 0x78, 0x56, 0x34, 0x12,
|
| - // Zero delta time.
|
| - 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,
|
| - };
|
| -
|
| - scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
|
| - ASSERT_TRUE(data != nullptr);
|
| -
|
| - test::CompareCharArraysWithHexError("constructed packet",
|
| - data->data(), data->length(),
|
| - AsChars(packet), arraysize(packet));
|
| -}
|
| -
|
| -// 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) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = true;
|
| - header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8);
|
| - header.fec_group = 0;
|
| -
|
| - QuicAckFrame ack_frame;
|
| - // This entropy hash is different from what shows up in the packet below,
|
| - // since entropy is recomputed by the framer on ack truncation (by
|
| - // TestEntropyCalculator for this test.)
|
| - ack_frame.entropy_hash = 0x43;
|
| - ack_frame.largest_observed = 2 * 300;
|
| - ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero();
|
| - for (size_t i = 1; i < 2 * 300; i += 2) {
|
| - ack_frame.missing_packets.insert(i);
|
| - }
|
| -
|
| - QuicFrames frames;
|
| - frames.push_back(QuicFrame(&ack_frame));
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12,
|
| - // private flags (entropy)
|
| - 0x01,
|
| -
|
| - // frame type (ack frame)
|
| - // (has nacks, is truncated, 2 byte largest observed, 1 byte delta)
|
| - 0x74,
|
| - // entropy hash of all received packets, set to 1 by TestEntropyCalculator
|
| - // since ack is truncated.
|
| - 0x01,
|
| - // 2-byte largest observed packet sequence number.
|
| - // Expected to be 510 (0x1FE), since only 255 nack ranges can fit.
|
| - 0xFE, 0x01,
|
| - // Zero delta time.
|
| - 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,
|
| - };
|
| -
|
| - scoped_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, BuildTruncatedAckFrameSmallPacket) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = true;
|
| - header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8);
|
| - header.fec_group = 0;
|
| -
|
| - QuicAckFrame ack_frame;
|
| - // This entropy hash is different from what shows up in the packet below,
|
| - // since entropy is recomputed by the framer on ack truncation (by
|
| - // TestEntropyCalculator for this test.)
|
| - ack_frame.entropy_hash = 0x43;
|
| - ack_frame.largest_observed = 2 * 300;
|
| - ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero();
|
| - for (size_t i = 1; i < 2 * 300; i += 2) {
|
| - ack_frame.missing_packets.insert(i);
|
| - }
|
| -
|
| - QuicFrames frames;
|
| - frames.push_back(QuicFrame(&ack_frame));
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12,
|
| - // private flags (entropy)
|
| - 0x01,
|
| -
|
| - // frame type (ack frame)
|
| - // (has nacks, is truncated, 2 byte largest observed, 1 byte delta)
|
| - 0x74,
|
| - // entropy hash of all received packets, set to 1 by TestEntropyCalculator
|
| - // since ack is truncated.
|
| - 0x01,
|
| - // 2-byte largest observed packet sequence number.
|
| - // Expected to be 12 (0x0C), since only 6 nack ranges can fit.
|
| - 0x0C, 0x00,
|
| - // Zero delta time.
|
| - 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,
|
| - };
|
| -
|
| - scoped_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));
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, BuildStopWaitingPacket) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = true;
|
| - header.packet_sequence_number = GG_UINT64_C(0x770123456789AA8);
|
| - header.fec_group = 0;
|
| -
|
| - QuicStopWaitingFrame stop_waiting_frame;
|
| - stop_waiting_frame.entropy_hash = 0x14;
|
| - stop_waiting_frame.least_unacked = GG_UINT64_C(0x770123456789AA0);
|
| -
|
| - QuicFrames frames;
|
| - frames.push_back(QuicFrame(&stop_waiting_frame));
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xA8, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags (entropy)
|
| - 0x01,
|
| -
|
| - // frame type (stop waiting frame)
|
| - 0x06,
|
| - // entropy hash of sent packets till least awaiting - 1.
|
| - 0x14,
|
| - // least packet sequence number awaiting an ack, delta from sequence number.
|
| - 0x08, 0x00, 0x00, 0x00,
|
| - 0x00, 0x00,
|
| - };
|
| -
|
| - scoped_ptr<QuicPacket> data(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 = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = false;
|
| - header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
|
| - header.fec_group = 0;
|
| -
|
| - QuicRstStreamFrame rst_frame;
|
| - rst_frame.stream_id = 0x01020304;
|
| - rst_frame.error_code = static_cast<QuicRstStreamErrorCode>(0x05060708);
|
| - rst_frame.error_details = "because I can";
|
| - rst_frame.byte_offset = 0x0807060504030201;
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags
|
| - 0x00,
|
| -
|
| - // frame type (rst stream frame)
|
| - 0x01,
|
| - // stream id
|
| - 0x04, 0x03, 0x02, 0x01,
|
| - // sent byte offset
|
| - 0x01, 0x02, 0x03, 0x04,
|
| - 0x05, 0x06, 0x07, 0x08,
|
| - // error code
|
| - 0x08, 0x07, 0x06, 0x05,
|
| - // error details length
|
| - 0x0d, 0x00,
|
| - // error details
|
| - 'b', 'e', 'c', 'a',
|
| - 'u', 's', 'e', ' ',
|
| - 'I', ' ', 'c', 'a',
|
| - 'n',
|
| - };
|
| -
|
| - QuicFrames frames;
|
| - frames.push_back(QuicFrame(&rst_frame));
|
| -
|
| - scoped_ptr<QuicPacket> data(BuildDataPacket(header, frames));
|
| - ASSERT_TRUE(data != nullptr);
|
| -
|
| - test::CompareCharArraysWithHexError("constructed packet",
|
| - data->data(), data->length(),
|
| - AsChars(packet), arraysize(packet));
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, BuildCloseFramePacket) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = true;
|
| - header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
|
| - header.fec_group = 0;
|
| -
|
| - 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));
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags (entropy)
|
| - 0x01,
|
| -
|
| - // frame type (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',
|
| - };
|
| -
|
| - scoped_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, BuildGoAwayPacket) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = true;
|
| - header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
|
| - header.fec_group = 0;
|
| -
|
| - QuicGoAwayFrame goaway_frame;
|
| - goaway_frame.error_code = static_cast<QuicErrorCode>(0x05060708);
|
| - goaway_frame.last_good_stream_id = 0x01020304;
|
| - goaway_frame.reason_phrase = "because I can";
|
| -
|
| - QuicFrames frames;
|
| - frames.push_back(QuicFrame(&goaway_frame));
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags(entropy)
|
| - 0x01,
|
| -
|
| - // frame type (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',
|
| - };
|
| -
|
| - scoped_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, BuildWindowUpdatePacket) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = true;
|
| - header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
|
| - header.fec_group = 0;
|
| -
|
| - QuicWindowUpdateFrame window_update_frame;
|
| - window_update_frame.stream_id = 0x01020304;
|
| - window_update_frame.byte_offset = 0x1122334455667788;
|
| -
|
| - QuicFrames frames;
|
| - frames.push_back(QuicFrame(&window_update_frame));
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags(entropy)
|
| - 0x01,
|
| -
|
| - // frame type (window update frame)
|
| - 0x04,
|
| - // stream id
|
| - 0x04, 0x03, 0x02, 0x01,
|
| - // byte offset
|
| - 0x88, 0x77, 0x66, 0x55,
|
| - 0x44, 0x33, 0x22, 0x11,
|
| - };
|
| -
|
| - scoped_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, BuildBlockedPacket) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = true;
|
| - header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
|
| - header.fec_group = 0;
|
| -
|
| - QuicBlockedFrame blocked_frame;
|
| - blocked_frame.stream_id = 0x01020304;
|
| -
|
| - QuicFrames frames;
|
| - frames.push_back(QuicFrame(&blocked_frame));
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags(entropy)
|
| - 0x01,
|
| -
|
| - // frame type (blocked frame)
|
| - 0x05,
|
| - // stream id
|
| - 0x04, 0x03, 0x02, 0x01,
|
| - };
|
| -
|
| - scoped_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, BuildPingPacket) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = true;
|
| - header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
|
| - header.fec_group = 0;
|
| -
|
| - QuicPingFrame ping_frame;
|
| -
|
| - QuicFrames frames;
|
| - frames.push_back(QuicFrame(&ping_frame));
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags(entropy)
|
| - 0x01,
|
| -
|
| - // frame type (ping frame)
|
| - 0x07,
|
| - };
|
| -
|
| - scoped_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, BuildPublicResetPacket) {
|
| - QuicPublicResetPacket reset_packet;
|
| - reset_packet.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - reset_packet.public_header.reset_flag = true;
|
| - reset_packet.public_header.version_flag = false;
|
| - reset_packet.rejected_sequence_number = GG_UINT64_C(0x123456789ABC);
|
| - reset_packet.nonce_proof = GG_UINT64_C(0xABCDEF0123456789);
|
| -
|
| - 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 sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12, 0x00, 0x00,
|
| - };
|
| -
|
| - scoped_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) {
|
| - QuicPublicResetPacket reset_packet;
|
| - reset_packet.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - reset_packet.public_header.reset_flag = true;
|
| - reset_packet.public_header.version_flag = false;
|
| - reset_packet.rejected_sequence_number = GG_UINT64_C(0x123456789ABC);
|
| - reset_packet.nonce_proof = GG_UINT64_C(0xABCDEF0123456789);
|
| - reset_packet.client_address = IPEndPoint(Loopback4(), 0x1234);
|
| -
|
| - 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 (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 sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12, 0x00, 0x00,
|
| - // client address
|
| - 0x02, 0x00,
|
| - 0x7F, 0x00, 0x00, 0x01,
|
| - 0x34, 0x12,
|
| - };
|
| -
|
| - scoped_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, BuildFecPacket) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = true;
|
| - header.entropy_flag = true;
|
| - header.packet_sequence_number = (GG_UINT64_C(0x123456789ABC));
|
| - header.is_in_fec_group = IN_FEC_GROUP;
|
| - header.fec_group = GG_UINT64_C(0x123456789ABB);;
|
| -
|
| - QuicFecData fec_data;
|
| - fec_data.fec_group = 1;
|
| - fec_data.redundancy = "abcdefghijklmnop";
|
| -
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags (entropy & fec group & fec packet)
|
| - 0x07,
|
| - // first fec protected packet offset
|
| - 0x01,
|
| -
|
| - // redundancy
|
| - 'a', 'b', 'c', 'd',
|
| - 'e', 'f', 'g', 'h',
|
| - 'i', 'j', 'k', 'l',
|
| - 'm', 'n', 'o', 'p',
|
| - };
|
| -
|
| - scoped_ptr<QuicPacket> data(framer_.BuildFecPacket(header, fec_data));
|
| - ASSERT_TRUE(data != nullptr);
|
| -
|
| - test::CompareCharArraysWithHexError("constructed packet",
|
| - data->data(), data->length(),
|
| - AsChars(packet), arraysize(packet));
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, EncryptPacket) {
|
| - QuicPacketSequenceNumber sequence_number = GG_UINT64_C(0x123456789ABC);
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags (fec group & fec packet)
|
| - 0x06,
|
| - // first fec protected packet offset
|
| - 0x01,
|
| -
|
| - // redundancy
|
| - 'a', 'b', 'c', 'd',
|
| - 'e', 'f', 'g', 'h',
|
| - 'i', 'j', 'k', 'l',
|
| - 'm', 'n', 'o', 'p',
|
| - };
|
| -
|
| - scoped_ptr<QuicPacket> raw(new QuicPacket(
|
| - AsChars(packet), arraysize(packet), false, PACKET_8BYTE_CONNECTION_ID,
|
| - !kIncludeVersion, PACKET_6BYTE_SEQUENCE_NUMBER));
|
| - scoped_ptr<QuicEncryptedPacket> encrypted(
|
| - framer_.EncryptPacket(ENCRYPTION_NONE, sequence_number, *raw));
|
| -
|
| - ASSERT_TRUE(encrypted.get() != nullptr);
|
| - EXPECT_TRUE(CheckEncryption(sequence_number, raw.get()));
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) {
|
| - QuicPacketSequenceNumber sequence_number = GG_UINT64_C(0x123456789ABC);
|
| - unsigned char packet[] = {
|
| - // public flags (version, 8 byte connection_id)
|
| - 0x3D,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // version tag
|
| - 'Q', '.', '1', '0',
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags (fec group & fec flags)
|
| - 0x06,
|
| - // first fec protected packet offset
|
| - 0x01,
|
| -
|
| - // redundancy
|
| - 'a', 'b', 'c', 'd',
|
| - 'e', 'f', 'g', 'h',
|
| - 'i', 'j', 'k', 'l',
|
| - 'm', 'n', 'o', 'p',
|
| - };
|
| -
|
| - scoped_ptr<QuicPacket> raw(new QuicPacket(
|
| - AsChars(packet), arraysize(packet), false, PACKET_8BYTE_CONNECTION_ID,
|
| - kIncludeVersion, PACKET_6BYTE_SEQUENCE_NUMBER));
|
| - scoped_ptr<QuicEncryptedPacket> encrypted(
|
| - framer_.EncryptPacket(ENCRYPTION_NONE, sequence_number, *raw));
|
| -
|
| - ASSERT_TRUE(encrypted.get() != nullptr);
|
| - EXPECT_TRUE(CheckEncryption(sequence_number, raw.get()));
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, AckTruncationLargePacket) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = false;
|
| - header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
|
| - header.fec_group = 0;
|
| -
|
| - // Create a packet with just the ack.
|
| - QuicAckFrame ack_frame = MakeAckFrameWithNackRanges(300, 0u);
|
| - QuicFrame frame;
|
| - frame.type = ACK_FRAME;
|
| - frame.ack_frame = &ack_frame;
|
| - QuicFrames frames;
|
| - frames.push_back(frame);
|
| -
|
| - // Build an ack packet with truncation due to limit in number of nack ranges.
|
| - scoped_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
|
| - ASSERT_TRUE(raw_ack_packet != nullptr);
|
| - scoped_ptr<QuicEncryptedPacket> ack_packet(
|
| - framer_.EncryptPacket(ENCRYPTION_NONE, header.packet_sequence_number,
|
| - *raw_ack_packet));
|
| - // Now make sure we can turn our ack packet back into an ack frame.
|
| - ASSERT_TRUE(framer_.ProcessPacket(*ack_packet));
|
| - ASSERT_EQ(1u, visitor_.ack_frames_.size());
|
| - QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
|
| - EXPECT_TRUE(processed_ack_frame.is_truncated);
|
| - EXPECT_EQ(510u, processed_ack_frame.largest_observed);
|
| - ASSERT_EQ(255u, processed_ack_frame.missing_packets.size());
|
| - SequenceNumberSet::const_iterator missing_iter =
|
| - processed_ack_frame.missing_packets.begin();
|
| - EXPECT_EQ(1u, *missing_iter);
|
| - SequenceNumberSet::const_reverse_iterator last_missing_iter =
|
| - processed_ack_frame.missing_packets.rbegin();
|
| - EXPECT_EQ(509u, *last_missing_iter);
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, AckTruncationSmallPacket) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = false;
|
| - header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
|
| - header.fec_group = 0;
|
| -
|
| - // Create a packet with just the ack.
|
| - QuicAckFrame ack_frame = MakeAckFrameWithNackRanges(300, 0u);
|
| - QuicFrame frame;
|
| - frame.type = ACK_FRAME;
|
| - frame.ack_frame = &ack_frame;
|
| - QuicFrames frames;
|
| - frames.push_back(frame);
|
| -
|
| - // Build an ack packet with truncation due to limit in number of nack ranges.
|
| - scoped_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames, 500));
|
| - ASSERT_TRUE(raw_ack_packet != nullptr);
|
| - scoped_ptr<QuicEncryptedPacket> ack_packet(
|
| - framer_.EncryptPacket(ENCRYPTION_NONE, header.packet_sequence_number,
|
| - *raw_ack_packet));
|
| - // Now make sure we can turn our ack packet back into an ack frame.
|
| - ASSERT_TRUE(framer_.ProcessPacket(*ack_packet));
|
| - ASSERT_EQ(1u, visitor_.ack_frames_.size());
|
| - QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
|
| - EXPECT_TRUE(processed_ack_frame.is_truncated);
|
| - EXPECT_EQ(476u, processed_ack_frame.largest_observed);
|
| - ASSERT_EQ(238u, processed_ack_frame.missing_packets.size());
|
| - SequenceNumberSet::const_iterator missing_iter =
|
| - processed_ack_frame.missing_packets.begin();
|
| - EXPECT_EQ(1u, *missing_iter);
|
| - SequenceNumberSet::const_reverse_iterator last_missing_iter =
|
| - processed_ack_frame.missing_packets.rbegin();
|
| - EXPECT_EQ(475u, *last_missing_iter);
|
| -}
|
| -
|
| -TEST_P(QuicFramerTest, CleanTruncation) {
|
| - QuicPacketHeader header;
|
| - header.public_header.connection_id = GG_UINT64_C(0xFEDCBA9876543210);
|
| - header.public_header.reset_flag = false;
|
| - header.public_header.version_flag = false;
|
| - header.fec_flag = false;
|
| - header.entropy_flag = true;
|
| - header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
|
| - header.fec_group = 0;
|
| -
|
| - QuicAckFrame ack_frame;
|
| - ack_frame.largest_observed = 201;
|
| - for (uint64 i = 1; i < ack_frame.largest_observed; ++i) {
|
| - ack_frame.missing_packets.insert(i);
|
| - }
|
| -
|
| - // Create a packet with just the ack.
|
| - QuicFrame frame;
|
| - frame.type = ACK_FRAME;
|
| - frame.ack_frame = &ack_frame;
|
| - QuicFrames frames;
|
| - frames.push_back(frame);
|
| -
|
| - scoped_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
|
| - ASSERT_TRUE(raw_ack_packet != nullptr);
|
| -
|
| - scoped_ptr<QuicEncryptedPacket> ack_packet(
|
| - framer_.EncryptPacket(ENCRYPTION_NONE, header.packet_sequence_number,
|
| - *raw_ack_packet));
|
| -
|
| - // Now make sure we can turn our ack packet back into an ack frame.
|
| - ASSERT_TRUE(framer_.ProcessPacket(*ack_packet));
|
| -
|
| - // 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) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags (Entropy)
|
| - 0x01,
|
| -
|
| - // frame type (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', '!',
|
| - };
|
| -
|
| - 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, FecEntropyTest) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // private flags (Entropy & fec group & FEC)
|
| - 0x07,
|
| - // first fec protected packet offset
|
| - 0xFF,
|
| -
|
| - // 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', '!',
|
| - };
|
| -
|
| - 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_->fec_flag);
|
| - EXPECT_TRUE(visitor_.header_->entropy_flag);
|
| - EXPECT_EQ(1 << 4, visitor_.header_->entropy_hash);
|
| -};
|
| -
|
| -TEST_P(QuicFramerTest, StopPacketProcessing) {
|
| - unsigned char packet[] = {
|
| - // public flags (8 byte connection_id)
|
| - 0x3C,
|
| - // connection_id
|
| - 0x10, 0x32, 0x54, 0x76,
|
| - 0x98, 0xBA, 0xDC, 0xFE,
|
| - // packet sequence number
|
| - 0xBC, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // 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 sequence number awaiting an ack
|
| - 0xA0, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // entropy hash of all received packets.
|
| - 0x43,
|
| - // largest observed packet sequence number
|
| - 0xBF, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - // num missing packets
|
| - 0x01,
|
| - // missing packet
|
| - 0xBE, 0x9A, 0x78, 0x56,
|
| - 0x34, 0x12,
|
| - };
|
| -
|
| - 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));
|
| -
|
| - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
|
| - EXPECT_TRUE(framer_.ProcessPacket(encrypted));
|
| - EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
|
| -}
|
| -
|
| -} // namespace test
|
| -} // namespace net
|
|
|