|  | // 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/third_party/quiche/src/quic/core/quic_packet_creator.h" | 
|  |  | 
|  | #include <cstdint> | 
|  | #include <memory> | 
|  | #include <ostream> | 
|  | #include <string> | 
|  |  | 
|  | #include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h" | 
|  | #include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" | 
|  | #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h" | 
|  | #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h" | 
|  | #include "net/third_party/quiche/src/quic/core/quic_data_writer.h" | 
|  | #include "net/third_party/quiche/src/quic/core/quic_pending_retransmission.h" | 
|  | #include "net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h" | 
|  | #include "net/third_party/quiche/src/quic/core/quic_types.h" | 
|  | #include "net/third_party/quiche/src/quic/core/quic_utils.h" | 
|  | #include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h" | 
|  | #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" | 
|  | #include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h" | 
|  | #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" | 
|  | #include "net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h" | 
|  | #include "net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.h" | 
|  | #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" | 
|  | #include "net/third_party/quiche/src/quic/test_tools/simple_data_producer.h" | 
|  |  | 
|  | using testing::_; | 
|  | using testing::DoAll; | 
|  | using testing::InSequence; | 
|  | using testing::Invoke; | 
|  | using testing::Return; | 
|  | using testing::SaveArg; | 
|  | using testing::StrictMock; | 
|  |  | 
|  | namespace quic { | 
|  | namespace test { | 
|  | namespace { | 
|  |  | 
|  | // Run tests with combinations of {ParsedQuicVersion, | 
|  | // ToggleVersionSerialization}. | 
|  | struct TestParams { | 
|  | TestParams(ParsedQuicVersion version, bool version_serialization) | 
|  | : version(version), version_serialization(version_serialization) {} | 
|  |  | 
|  | ParsedQuicVersion version; | 
|  | bool version_serialization; | 
|  | }; | 
|  |  | 
|  | // Used by ::testing::PrintToStringParamName(). | 
|  | std::string PrintToString(const TestParams& p) { | 
|  | return QuicStrCat(ParsedQuicVersionToString(p.version), "_", | 
|  | (p.version_serialization ? "Include" : "No"), "Version"); | 
|  | } | 
|  |  | 
|  | // Constructs various test permutations. | 
|  | std::vector<TestParams> GetTestParams() { | 
|  | std::vector<TestParams> params; | 
|  | ParsedQuicVersionVector all_supported_versions = AllSupportedVersions(); | 
|  | for (size_t i = 0; i < all_supported_versions.size(); ++i) { | 
|  | params.push_back(TestParams(all_supported_versions[i], true)); | 
|  | params.push_back(TestParams(all_supported_versions[i], false)); | 
|  | } | 
|  | return params; | 
|  | } | 
|  |  | 
|  | class MockDebugDelegate : public QuicPacketCreator::DebugDelegate { | 
|  | public: | 
|  | ~MockDebugDelegate() override = default; | 
|  |  | 
|  | MOCK_METHOD1(OnFrameAddedToPacket, void(const QuicFrame& frame)); | 
|  | }; | 
|  |  | 
|  | class TestPacketCreator : public QuicPacketCreator { | 
|  | public: | 
|  | TestPacketCreator(QuicConnectionId connection_id, | 
|  | QuicFramer* framer, | 
|  | DelegateInterface* delegate, | 
|  | SimpleDataProducer* producer) | 
|  | : QuicPacketCreator(connection_id, framer, delegate), | 
|  | producer_(producer), | 
|  | version_(framer->transport_version()) {} | 
|  |  | 
|  | bool ConsumeDataToFillCurrentPacket(QuicStreamId id, | 
|  | const struct iovec* iov, | 
|  | int iov_count, | 
|  | size_t total_length, | 
|  | size_t iov_offset, | 
|  | QuicStreamOffset offset, | 
|  | bool fin, | 
|  | bool needs_full_padding, | 
|  | TransmissionType transmission_type, | 
|  | QuicFrame* frame) { | 
|  | // Save data before data is consumed. | 
|  | QuicByteCount data_length = total_length - iov_offset; | 
|  | if (data_length > 0) { | 
|  | producer_->SaveStreamData(id, iov, iov_count, iov_offset, data_length); | 
|  | } | 
|  | return QuicPacketCreator::ConsumeDataToFillCurrentPacket( | 
|  | id, data_length - iov_offset, offset, fin, needs_full_padding, | 
|  | transmission_type, frame); | 
|  | } | 
|  |  | 
|  | void StopSendingVersion() { | 
|  | if (VersionHasIetfInvariantHeader(version_)) { | 
|  | set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | return; | 
|  | } | 
|  | QuicPacketCreator::StopSendingVersion(); | 
|  | } | 
|  |  | 
|  | SimpleDataProducer* producer_; | 
|  | QuicTransportVersion version_; | 
|  | }; | 
|  |  | 
|  | class QuicPacketCreatorTest : public QuicTestWithParam<TestParams> { | 
|  | public: | 
|  | void ClearSerializedPacketForTests(SerializedPacket* serialized_packet) { | 
|  | if (serialized_packet == nullptr) { | 
|  | return; | 
|  | } | 
|  | ClearSerializedPacket(serialized_packet); | 
|  | } | 
|  |  | 
|  | void SaveSerializedPacket(SerializedPacket* serialized_packet) { | 
|  | if (serialized_packet == nullptr) { | 
|  | return; | 
|  | } | 
|  | delete[] serialized_packet_.encrypted_buffer; | 
|  | serialized_packet_ = *serialized_packet; | 
|  | serialized_packet_.encrypted_buffer = CopyBuffer(*serialized_packet); | 
|  | serialized_packet->retransmittable_frames.clear(); | 
|  | } | 
|  |  | 
|  | void DeleteSerializedPacket() { | 
|  | delete[] serialized_packet_.encrypted_buffer; | 
|  | serialized_packet_.encrypted_buffer = nullptr; | 
|  | ClearSerializedPacket(&serialized_packet_); | 
|  | } | 
|  |  | 
|  | protected: | 
|  | QuicPacketCreatorTest() | 
|  | : connection_id_(TestConnectionId(2)), | 
|  | server_framer_(SupportedVersions(GetParam().version), | 
|  | QuicTime::Zero(), | 
|  | Perspective::IS_SERVER, | 
|  | connection_id_.length()), | 
|  | client_framer_(SupportedVersions(GetParam().version), | 
|  | QuicTime::Zero(), | 
|  | Perspective::IS_CLIENT, | 
|  | connection_id_.length()), | 
|  | data_("foo"), | 
|  | creator_(connection_id_, &client_framer_, &delegate_, &producer_), | 
|  | serialized_packet_(creator_.NoPacket()) { | 
|  | EXPECT_CALL(delegate_, GetPacketBuffer()).WillRepeatedly(Return(nullptr)); | 
|  | creator_.SetEncrypter(ENCRYPTION_INITIAL, std::make_unique<NullEncrypter>( | 
|  | Perspective::IS_CLIENT)); | 
|  | creator_.SetEncrypter(ENCRYPTION_HANDSHAKE, std::make_unique<NullEncrypter>( | 
|  | Perspective::IS_CLIENT)); | 
|  | creator_.SetEncrypter(ENCRYPTION_ZERO_RTT, std::make_unique<NullEncrypter>( | 
|  | Perspective::IS_CLIENT)); | 
|  | creator_.SetEncrypter( | 
|  | ENCRYPTION_FORWARD_SECURE, | 
|  | std::make_unique<NullEncrypter>(Perspective::IS_CLIENT)); | 
|  | client_framer_.set_visitor(&framer_visitor_); | 
|  | server_framer_.set_visitor(&framer_visitor_); | 
|  | client_framer_.set_data_producer(&producer_); | 
|  | if (server_framer_.version().KnowsWhichDecrypterToUse()) { | 
|  | server_framer_.InstallDecrypter( | 
|  | ENCRYPTION_INITIAL, | 
|  | std::make_unique<NullDecrypter>(Perspective::IS_SERVER)); | 
|  | server_framer_.InstallDecrypter( | 
|  | ENCRYPTION_ZERO_RTT, | 
|  | std::make_unique<NullDecrypter>(Perspective::IS_SERVER)); | 
|  | server_framer_.InstallDecrypter( | 
|  | ENCRYPTION_HANDSHAKE, | 
|  | std::make_unique<NullDecrypter>(Perspective::IS_SERVER)); | 
|  | server_framer_.InstallDecrypter( | 
|  | ENCRYPTION_FORWARD_SECURE, | 
|  | std::make_unique<NullDecrypter>(Perspective::IS_SERVER)); | 
|  | } else { | 
|  | server_framer_.SetDecrypter( | 
|  | ENCRYPTION_INITIAL, | 
|  | std::make_unique<NullDecrypter>(Perspective::IS_SERVER)); | 
|  | } | 
|  | } | 
|  |  | 
|  | ~QuicPacketCreatorTest() override { | 
|  | delete[] serialized_packet_.encrypted_buffer; | 
|  | ClearSerializedPacket(&serialized_packet_); | 
|  | } | 
|  |  | 
|  | SerializedPacket SerializeAllFrames(const QuicFrames& frames) { | 
|  | SerializedPacket packet = QuicPacketCreatorPeer::SerializeAllFrames( | 
|  | &creator_, frames, buffer_, kMaxOutgoingPacketSize); | 
|  | EXPECT_EQ(QuicPacketCreatorPeer::GetEncryptionLevel(&creator_), | 
|  | packet.encryption_level); | 
|  | return packet; | 
|  | } | 
|  |  | 
|  | void ProcessPacket(const SerializedPacket& packet) { | 
|  | QuicEncryptedPacket encrypted_packet(packet.encrypted_buffer, | 
|  | packet.encrypted_length); | 
|  | server_framer_.ProcessPacket(encrypted_packet); | 
|  | } | 
|  |  | 
|  | void CheckStreamFrame(const QuicFrame& frame, | 
|  | QuicStreamId stream_id, | 
|  | const std::string& data, | 
|  | QuicStreamOffset offset, | 
|  | bool fin) { | 
|  | EXPECT_EQ(STREAM_FRAME, frame.type); | 
|  | EXPECT_EQ(stream_id, frame.stream_frame.stream_id); | 
|  | char buf[kMaxOutgoingPacketSize]; | 
|  | QuicDataWriter writer(kMaxOutgoingPacketSize, buf, HOST_BYTE_ORDER); | 
|  | if (frame.stream_frame.data_length > 0) { | 
|  | producer_.WriteStreamData(stream_id, frame.stream_frame.offset, | 
|  | frame.stream_frame.data_length, &writer); | 
|  | } | 
|  | EXPECT_EQ(data, QuicStringPiece(buf, frame.stream_frame.data_length)); | 
|  | EXPECT_EQ(offset, frame.stream_frame.offset); | 
|  | EXPECT_EQ(fin, frame.stream_frame.fin); | 
|  | } | 
|  |  | 
|  | // Returns the number of bytes consumed by the header of packet, including | 
|  | // the version. | 
|  | size_t GetPacketHeaderOverhead(QuicTransportVersion version) { | 
|  | return GetPacketHeaderSize( | 
|  | version, creator_.GetDestinationConnectionIdLength(), | 
|  | creator_.GetSourceConnectionIdLength(), | 
|  | QuicPacketCreatorPeer::SendVersionInPacket(&creator_), | 
|  | !kIncludeDiversificationNonce, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_), | 
|  | QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0, | 
|  | QuicPacketCreatorPeer::GetLengthLength(&creator_)); | 
|  | } | 
|  |  | 
|  | // Returns the number of bytes of overhead that will be added to a packet | 
|  | // of maximum length. | 
|  | size_t GetEncryptionOverhead() { | 
|  | return creator_.max_packet_length() - | 
|  | client_framer_.GetMaxPlaintextSize(creator_.max_packet_length()); | 
|  | } | 
|  |  | 
|  | // Returns the number of bytes consumed by the non-data fields of a stream | 
|  | // frame, assuming it is the last frame in the packet | 
|  | size_t GetStreamFrameOverhead(QuicTransportVersion version) { | 
|  | return QuicFramer::GetMinStreamFrameSize( | 
|  | version, GetNthClientInitiatedStreamId(1), kOffset, true, | 
|  | /* data_length= */ 0); | 
|  | } | 
|  |  | 
|  | QuicPendingRetransmission CreateRetransmission( | 
|  | const QuicFrames& retransmittable_frames, | 
|  | bool has_crypto_handshake, | 
|  | int num_padding_bytes, | 
|  | EncryptionLevel encryption_level, | 
|  | QuicPacketNumberLength packet_number_length) { | 
|  | return QuicPendingRetransmission(QuicPacketNumber(1u), NOT_RETRANSMISSION, | 
|  | retransmittable_frames, | 
|  | has_crypto_handshake, num_padding_bytes, | 
|  | encryption_level, packet_number_length); | 
|  | } | 
|  |  | 
|  | bool IsDefaultTestConfiguration() { | 
|  | TestParams p = GetParam(); | 
|  | return p.version == AllSupportedVersions()[0] && p.version_serialization; | 
|  | } | 
|  |  | 
|  | QuicStreamId GetNthClientInitiatedStreamId(int n) const { | 
|  | return QuicUtils::GetFirstBidirectionalStreamId( | 
|  | creator_.transport_version(), Perspective::IS_CLIENT) + | 
|  | n * 2; | 
|  | } | 
|  |  | 
|  | static const QuicStreamOffset kOffset = 0u; | 
|  |  | 
|  | char buffer_[kMaxOutgoingPacketSize]; | 
|  | QuicConnectionId connection_id_; | 
|  | QuicFrames frames_; | 
|  | QuicFramer server_framer_; | 
|  | QuicFramer client_framer_; | 
|  | StrictMock<MockFramerVisitor> framer_visitor_; | 
|  | StrictMock<MockPacketCreatorDelegate> delegate_; | 
|  | std::string data_; | 
|  | struct iovec iov_; | 
|  | TestPacketCreator creator_; | 
|  | SerializedPacket serialized_packet_; | 
|  | SimpleDataProducer producer_; | 
|  | SimpleBufferAllocator allocator_; | 
|  | }; | 
|  |  | 
|  | // Run all packet creator tests with all supported versions of QUIC, and with | 
|  | // and without version in the packet header, as well as doing a run for each | 
|  | // length of truncated connection id. | 
|  | INSTANTIATE_TEST_SUITE_P(QuicPacketCreatorTests, | 
|  | QuicPacketCreatorTest, | 
|  | ::testing::ValuesIn(GetTestParams()), | 
|  | ::testing::PrintToStringParamName()); | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, SerializeFrames) { | 
|  | for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) { | 
|  | EncryptionLevel level = static_cast<EncryptionLevel>(i); | 
|  | creator_.set_encryption_level(level); | 
|  | frames_.push_back(QuicFrame(new QuicAckFrame(InitAckFrame(1)))); | 
|  | QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( | 
|  | client_framer_.transport_version(), Perspective::IS_CLIENT); | 
|  | if (level != ENCRYPTION_INITIAL && level != ENCRYPTION_HANDSHAKE) { | 
|  | frames_.push_back( | 
|  | QuicFrame(QuicStreamFrame(stream_id, false, 0u, QuicStringPiece()))); | 
|  | frames_.push_back( | 
|  | QuicFrame(QuicStreamFrame(stream_id, true, 0u, QuicStringPiece()))); | 
|  | } | 
|  | SerializedPacket serialized = SerializeAllFrames(frames_); | 
|  | EXPECT_EQ(level, serialized.encryption_level); | 
|  | delete frames_[0].ack_frame; | 
|  | frames_.clear(); | 
|  |  | 
|  | { | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnAckFrameStart(_, _)) | 
|  | .WillOnce(Return(true)); | 
|  | EXPECT_CALL(framer_visitor_, | 
|  | OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2))) | 
|  | .WillOnce(Return(true)); | 
|  | EXPECT_CALL(framer_visitor_, OnAckFrameEnd(QuicPacketNumber(1))) | 
|  | .WillOnce(Return(true)); | 
|  | if (level != ENCRYPTION_INITIAL && level != ENCRYPTION_HANDSHAKE) { | 
|  | EXPECT_CALL(framer_visitor_, OnStreamFrame(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnStreamFrame(_)); | 
|  | } | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  | } | 
|  | ProcessPacket(serialized); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, ReserializeFramesWithSequenceNumberLength) { | 
|  | if (VersionHasIetfInvariantHeader(client_framer_.transport_version())) { | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | } | 
|  | // If the original packet number length, the current packet number | 
|  | // length, and the configured send packet number length are different, the | 
|  | // retransmit must sent with the original length and the others do not change. | 
|  | QuicPacketCreatorPeer::SetPacketNumberLength(&creator_, | 
|  | PACKET_2BYTE_PACKET_NUMBER); | 
|  | QuicFrames frames; | 
|  | std::string data("a"); | 
|  | if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { | 
|  | QuicStreamFrame stream_frame( | 
|  | QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), | 
|  | /*fin=*/false, 0u, QuicStringPiece()); | 
|  | frames.push_back(QuicFrame(stream_frame)); | 
|  | } else { | 
|  | producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data); | 
|  | frames.push_back( | 
|  | QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, 0, data.length()))); | 
|  | } | 
|  | char buffer[kMaxOutgoingPacketSize]; | 
|  | QuicPendingRetransmission retransmission(CreateRetransmission( | 
|  | frames, true /* has_crypto_handshake */, -1 /* needs full padding */, | 
|  | ENCRYPTION_INITIAL, PACKET_4BYTE_PACKET_NUMBER)); | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | creator_.ReserializeAllFrames(retransmission, buffer, kMaxOutgoingPacketSize); | 
|  | // The packet number length is updated after every packet is sent, | 
|  | // so there is no need to restore the old length after sending. | 
|  | EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); | 
|  | EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER, | 
|  | serialized_packet_.packet_number_length); | 
|  |  | 
|  | { | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)); | 
|  | if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { | 
|  | EXPECT_CALL(framer_visitor_, OnStreamFrame(_)); | 
|  | } else { | 
|  | EXPECT_CALL(framer_visitor_, OnCryptoFrame(_)); | 
|  | } | 
|  | EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  | } | 
|  | ProcessPacket(serialized_packet_); | 
|  | DeleteFrames(&frames); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, ReserializeCryptoFrameWithForwardSecurity) { | 
|  | QuicFrames frames; | 
|  | std::string data("a"); | 
|  | if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { | 
|  | QuicStreamFrame stream_frame( | 
|  | QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), | 
|  | /*fin=*/false, 0u, QuicStringPiece()); | 
|  | frames.push_back(QuicFrame(stream_frame)); | 
|  | } else { | 
|  | producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data); | 
|  | frames.push_back( | 
|  | QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, 0, data.length()))); | 
|  | } | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | char buffer[kMaxOutgoingPacketSize]; | 
|  | QuicPendingRetransmission retransmission(CreateRetransmission( | 
|  | frames, true /* has_crypto_handshake */, -1 /* needs full padding */, | 
|  | ENCRYPTION_INITIAL, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_))); | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | creator_.ReserializeAllFrames(retransmission, buffer, kMaxOutgoingPacketSize); | 
|  | EXPECT_EQ(ENCRYPTION_INITIAL, serialized_packet_.encryption_level); | 
|  | DeleteFrames(&frames); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, ReserializeFrameWithForwardSecurity) { | 
|  | QuicStreamFrame stream_frame(0u, /*fin=*/false, 0u, QuicStringPiece()); | 
|  | QuicFrames frames; | 
|  | frames.push_back(QuicFrame(stream_frame)); | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | char buffer[kMaxOutgoingPacketSize]; | 
|  | QuicPendingRetransmission retransmission(CreateRetransmission( | 
|  | frames, false /* has_crypto_handshake */, 0 /* no padding */, | 
|  | ENCRYPTION_INITIAL, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_))); | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | creator_.ReserializeAllFrames(retransmission, buffer, kMaxOutgoingPacketSize); | 
|  | EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, serialized_packet_.encryption_level); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, ReserializeFramesWithFullPadding) { | 
|  | QuicFrame frame; | 
|  | std::string data = "fake handshake message data"; | 
|  | if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { | 
|  | MakeIOVector(data, &iov_); | 
|  | producer_.SaveStreamData( | 
|  | QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), &iov_, | 
|  | 1u, 0u, iov_.iov_len); | 
|  | QuicPacketCreatorPeer::CreateStreamFrame( | 
|  | &creator_, | 
|  | QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), | 
|  | iov_.iov_len, 0u, false, &frame); | 
|  | } else { | 
|  | producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data); | 
|  | EXPECT_TRUE(QuicPacketCreatorPeer::CreateCryptoFrame( | 
|  | &creator_, ENCRYPTION_INITIAL, data.length(), 0, &frame)); | 
|  | } | 
|  | QuicFrames frames; | 
|  | frames.push_back(frame); | 
|  | char buffer[kMaxOutgoingPacketSize]; | 
|  | QuicPendingRetransmission retransmission(CreateRetransmission( | 
|  | frames, true /* has_crypto_handshake */, -1 /* needs full padding */, | 
|  | ENCRYPTION_INITIAL, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_))); | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | creator_.ReserializeAllFrames(retransmission, buffer, kMaxOutgoingPacketSize); | 
|  | EXPECT_EQ(kDefaultMaxPacketSize, serialized_packet_.encrypted_length); | 
|  | DeleteFrames(&frames); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, DoNotRetransmitPendingPadding) { | 
|  | QuicFrame frame; | 
|  | std::string data = "fake message data"; | 
|  | if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { | 
|  | MakeIOVector(data, &iov_); | 
|  | producer_.SaveStreamData( | 
|  | QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), &iov_, | 
|  | 1u, 0u, iov_.iov_len); | 
|  | QuicPacketCreatorPeer::CreateStreamFrame( | 
|  | &creator_, | 
|  | QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), | 
|  | iov_.iov_len, 0u, false, &frame); | 
|  | } else { | 
|  | producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data); | 
|  | EXPECT_TRUE(QuicPacketCreatorPeer::CreateCryptoFrame( | 
|  | &creator_, ENCRYPTION_INITIAL, data.length(), 0, &frame)); | 
|  | } | 
|  |  | 
|  | const int kNumPaddingBytes1 = 4; | 
|  | int packet_size = 0; | 
|  | { | 
|  | QuicFrames frames; | 
|  | frames.push_back(frame); | 
|  | char buffer[kMaxOutgoingPacketSize]; | 
|  | QuicPendingRetransmission retransmission(CreateRetransmission( | 
|  | frames, false /* has_crypto_handshake */, | 
|  | kNumPaddingBytes1 /* padding bytes */, ENCRYPTION_INITIAL, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_))); | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | creator_.ReserializeAllFrames(retransmission, buffer, | 
|  | kMaxOutgoingPacketSize); | 
|  | packet_size = serialized_packet_.encrypted_length; | 
|  | } | 
|  |  | 
|  | { | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)); | 
|  | if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { | 
|  | EXPECT_CALL(framer_visitor_, OnCryptoFrame(_)); | 
|  | } else { | 
|  | EXPECT_CALL(framer_visitor_, OnStreamFrame(_)); | 
|  | } | 
|  | // Pending paddings are not retransmitted. | 
|  | EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)).Times(0); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  | } | 
|  | ProcessPacket(serialized_packet_); | 
|  |  | 
|  | const int kNumPaddingBytes2 = 44; | 
|  | QuicFrames frames; | 
|  | frames.push_back(frame); | 
|  | char buffer[kMaxOutgoingPacketSize]; | 
|  | QuicPendingRetransmission retransmission(CreateRetransmission( | 
|  | frames, false /* has_crypto_handshake */, | 
|  | kNumPaddingBytes2 /* padding bytes */, ENCRYPTION_INITIAL, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_))); | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | creator_.ReserializeAllFrames(retransmission, buffer, kMaxOutgoingPacketSize); | 
|  |  | 
|  | EXPECT_EQ(packet_size, serialized_packet_.encrypted_length); | 
|  | DeleteFrames(&frames); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, ReserializeFramesWithFullPacketAndPadding) { | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | const size_t overhead = | 
|  | GetPacketHeaderOverhead(client_framer_.transport_version()) + | 
|  | GetEncryptionOverhead() + | 
|  | GetStreamFrameOverhead(client_framer_.transport_version()); | 
|  | size_t capacity = kDefaultMaxPacketSize - overhead; | 
|  | for (int delta = -5; delta <= 0; ++delta) { | 
|  | std::string data(capacity + delta, 'A'); | 
|  | size_t bytes_free = 0 - delta; | 
|  |  | 
|  | QuicFrame frame; | 
|  | SimpleDataProducer producer; | 
|  | QuicPacketCreatorPeer::framer(&creator_)->set_data_producer(&producer); | 
|  | MakeIOVector(data, &iov_); | 
|  | QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( | 
|  | client_framer_.transport_version(), Perspective::IS_CLIENT); | 
|  | producer.SaveStreamData(stream_id, &iov_, 1u, 0u, iov_.iov_len); | 
|  | QuicPacketCreatorPeer::CreateStreamFrame(&creator_, stream_id, iov_.iov_len, | 
|  | kOffset, false, &frame); | 
|  | QuicFrames frames; | 
|  | frames.push_back(frame); | 
|  | char buffer[kMaxOutgoingPacketSize]; | 
|  | QuicPendingRetransmission retransmission(CreateRetransmission( | 
|  | frames, false /* has_crypto_handshake */, -1 /* needs full padding */, | 
|  | ENCRYPTION_FORWARD_SECURE, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_))); | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | creator_.ReserializeAllFrames(retransmission, buffer, | 
|  | kMaxOutgoingPacketSize); | 
|  |  | 
|  | // If there is not enough space in the packet to fit a padding frame | 
|  | // (1 byte) and to expand the stream frame (another 2 bytes) the packet | 
|  | // will not be padded. | 
|  | if (bytes_free < 3) { | 
|  | EXPECT_EQ(kDefaultMaxPacketSize - bytes_free, | 
|  | serialized_packet_.encrypted_length); | 
|  | } else { | 
|  | EXPECT_EQ(kDefaultMaxPacketSize, serialized_packet_.encrypted_length); | 
|  | } | 
|  |  | 
|  | frames_.clear(); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, SerializeConnectionClose) { | 
|  | QuicConnectionCloseFrame frame(GetParam().version.transport_version, | 
|  | QUIC_NO_ERROR, "error", | 
|  | /*transport_close_frame_type=*/0); | 
|  |  | 
|  | QuicFrames frames; | 
|  | frames.push_back(QuicFrame(&frame)); | 
|  | SerializedPacket serialized = SerializeAllFrames(frames); | 
|  | EXPECT_EQ(ENCRYPTION_INITIAL, serialized.encryption_level); | 
|  | ASSERT_EQ(QuicPacketNumber(1u), serialized.packet_number); | 
|  | ASSERT_EQ(QuicPacketNumber(1u), creator_.packet_number()); | 
|  |  | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnConnectionCloseFrame(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  |  | 
|  | ProcessPacket(serialized); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, ConsumeCryptoDataToFillCurrentPacket) { | 
|  | std::string data = "crypto data"; | 
|  | QuicFrame frame; | 
|  | ASSERT_TRUE(creator_.ConsumeCryptoDataToFillCurrentPacket( | 
|  | ENCRYPTION_INITIAL, data.length(), 0, | 
|  | /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame)); | 
|  | EXPECT_EQ(frame.crypto_frame->data_length, data.length()); | 
|  | EXPECT_TRUE(creator_.HasPendingFrames()); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, ConsumeDataToFillCurrentPacket) { | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | QuicFrame frame; | 
|  | MakeIOVector("test", &iov_); | 
|  | QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( | 
|  | client_framer_.transport_version(), Perspective::IS_CLIENT); | 
|  | ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( | 
|  | stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, false, false, | 
|  | NOT_RETRANSMISSION, &frame)); | 
|  | size_t consumed = frame.stream_frame.data_length; | 
|  | EXPECT_EQ(4u, consumed); | 
|  | CheckStreamFrame(frame, stream_id, "test", 0u, false); | 
|  | EXPECT_TRUE(creator_.HasPendingFrames()); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, ConsumeDataFin) { | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | QuicFrame frame; | 
|  | MakeIOVector("test", &iov_); | 
|  | QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( | 
|  | client_framer_.transport_version(), Perspective::IS_CLIENT); | 
|  | ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( | 
|  | stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, true, false, | 
|  | NOT_RETRANSMISSION, &frame)); | 
|  | size_t consumed = frame.stream_frame.data_length; | 
|  | EXPECT_EQ(4u, consumed); | 
|  | CheckStreamFrame(frame, stream_id, "test", 0u, true); | 
|  | EXPECT_TRUE(creator_.HasPendingFrames()); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, ConsumeDataFinOnly) { | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | QuicFrame frame; | 
|  | QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( | 
|  | client_framer_.transport_version(), Perspective::IS_CLIENT); | 
|  | ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( | 
|  | stream_id, nullptr, 0u, 0u, 0u, 0u, true, false, NOT_RETRANSMISSION, | 
|  | &frame)); | 
|  | size_t consumed = frame.stream_frame.data_length; | 
|  | EXPECT_EQ(0u, consumed); | 
|  | CheckStreamFrame(frame, stream_id, std::string(), 0u, true); | 
|  | EXPECT_TRUE(creator_.HasPendingFrames()); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, CreateAllFreeBytesForStreamFrames) { | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | const size_t overhead = | 
|  | GetPacketHeaderOverhead(client_framer_.transport_version()) + | 
|  | GetEncryptionOverhead(); | 
|  | for (size_t i = overhead + QuicPacketCreator::MinPlaintextPacketSize( | 
|  | client_framer_.version()); | 
|  | i < overhead + 100; ++i) { | 
|  | SCOPED_TRACE(i); | 
|  | creator_.SetMaxPacketLength(i); | 
|  | const bool should_have_room = | 
|  | i > | 
|  | overhead + GetStreamFrameOverhead(client_framer_.transport_version()); | 
|  | ASSERT_EQ(should_have_room, | 
|  | creator_.HasRoomForStreamFrame(GetNthClientInitiatedStreamId(1), | 
|  | kOffset, /* data_size=*/0xffff)); | 
|  | if (should_have_room) { | 
|  | QuicFrame frame; | 
|  | MakeIOVector("testdata", &iov_); | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillRepeatedly(Invoke( | 
|  | this, &QuicPacketCreatorTest::ClearSerializedPacketForTests)); | 
|  | ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( | 
|  | GetNthClientInitiatedStreamId(1), &iov_, 1u, iov_.iov_len, 0u, | 
|  | kOffset, false, false, NOT_RETRANSMISSION, &frame)); | 
|  | size_t bytes_consumed = frame.stream_frame.data_length; | 
|  | EXPECT_LT(0u, bytes_consumed); | 
|  | creator_.FlushCurrentPacket(); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, StreamFrameConsumption) { | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | // Compute the total overhead for a single frame in packet. | 
|  | const size_t overhead = | 
|  | GetPacketHeaderOverhead(client_framer_.transport_version()) + | 
|  | GetEncryptionOverhead() + | 
|  | GetStreamFrameOverhead(client_framer_.transport_version()); | 
|  | size_t capacity = kDefaultMaxPacketSize - overhead; | 
|  | // Now, test various sizes around this size. | 
|  | for (int delta = -5; delta <= 5; ++delta) { | 
|  | std::string data(capacity + delta, 'A'); | 
|  | size_t bytes_free = delta > 0 ? 0 : 0 - delta; | 
|  | QuicFrame frame; | 
|  | MakeIOVector(data, &iov_); | 
|  | ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( | 
|  | GetNthClientInitiatedStreamId(1), &iov_, 1u, iov_.iov_len, 0u, kOffset, | 
|  | false, false, NOT_RETRANSMISSION, &frame)); | 
|  |  | 
|  | // BytesFree() returns bytes available for the next frame, which will | 
|  | // be two bytes smaller since the stream frame would need to be grown. | 
|  | EXPECT_EQ(2u, creator_.ExpansionOnNewFrame()); | 
|  | size_t expected_bytes_free = bytes_free < 3 ? 0 : bytes_free - 2; | 
|  | EXPECT_EQ(expected_bytes_free, creator_.BytesFree()) << "delta: " << delta; | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | creator_.FlushCurrentPacket(); | 
|  | ASSERT_TRUE(serialized_packet_.encrypted_buffer); | 
|  | DeleteSerializedPacket(); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, CryptoStreamFramePacketPadding) { | 
|  | // This test serializes crypto payloads slightly larger than a packet, which | 
|  | // Causes the multi-packet ClientHello check to fail. | 
|  | SetQuicFlag(FLAGS_quic_enforce_single_packet_chlo, false); | 
|  | // Compute the total overhead for a single frame in packet. | 
|  | size_t overhead = | 
|  | GetPacketHeaderOverhead(client_framer_.transport_version()) + | 
|  | GetEncryptionOverhead(); | 
|  | if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { | 
|  | overhead += | 
|  | QuicFramer::GetMinCryptoFrameSize(kOffset, kMaxOutgoingPacketSize); | 
|  | } else { | 
|  | overhead += GetStreamFrameOverhead(client_framer_.transport_version()); | 
|  | } | 
|  | ASSERT_GT(kMaxOutgoingPacketSize, overhead); | 
|  | size_t capacity = kDefaultMaxPacketSize - overhead; | 
|  | // Now, test various sizes around this size. | 
|  | for (int delta = -5; delta <= 5; ++delta) { | 
|  | SCOPED_TRACE(delta); | 
|  | std::string data(capacity + delta, 'A'); | 
|  | size_t bytes_free = delta > 0 ? 0 : 0 - delta; | 
|  |  | 
|  | QuicFrame frame; | 
|  | MakeIOVector(data, &iov_); | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillRepeatedly( | 
|  | Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { | 
|  | ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( | 
|  | QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), | 
|  | &iov_, 1u, iov_.iov_len, 0u, kOffset, false, true, NOT_RETRANSMISSION, | 
|  | &frame)); | 
|  | size_t bytes_consumed = frame.stream_frame.data_length; | 
|  | EXPECT_LT(0u, bytes_consumed); | 
|  | } else { | 
|  | producer_.SaveCryptoData(ENCRYPTION_INITIAL, kOffset, data); | 
|  | ASSERT_TRUE(creator_.ConsumeCryptoDataToFillCurrentPacket( | 
|  | ENCRYPTION_INITIAL, data.length(), kOffset, | 
|  | /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame)); | 
|  | size_t bytes_consumed = frame.crypto_frame->data_length; | 
|  | EXPECT_LT(0u, bytes_consumed); | 
|  | } | 
|  | creator_.FlushCurrentPacket(); | 
|  | ASSERT_TRUE(serialized_packet_.encrypted_buffer); | 
|  | // If there is not enough space in the packet to fit a padding frame | 
|  | // (1 byte) and to expand the stream frame (another 2 bytes) the packet | 
|  | // will not be padded. | 
|  | if (bytes_free < 3 && | 
|  | !QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { | 
|  | EXPECT_EQ(kDefaultMaxPacketSize - bytes_free, | 
|  | serialized_packet_.encrypted_length); | 
|  | } else { | 
|  | EXPECT_EQ(kDefaultMaxPacketSize, serialized_packet_.encrypted_length); | 
|  | } | 
|  | DeleteSerializedPacket(); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, NonCryptoStreamFramePacketNonPadding) { | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | // Compute the total overhead for a single frame in packet. | 
|  | const size_t overhead = | 
|  | GetPacketHeaderOverhead(client_framer_.transport_version()) + | 
|  | GetEncryptionOverhead() + | 
|  | GetStreamFrameOverhead(client_framer_.transport_version()); | 
|  | ASSERT_GT(kDefaultMaxPacketSize, overhead); | 
|  | size_t capacity = kDefaultMaxPacketSize - overhead; | 
|  | // Now, test various sizes around this size. | 
|  | for (int delta = -5; delta <= 5; ++delta) { | 
|  | std::string data(capacity + delta, 'A'); | 
|  | size_t bytes_free = delta > 0 ? 0 : 0 - delta; | 
|  |  | 
|  | QuicFrame frame; | 
|  | MakeIOVector(data, &iov_); | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( | 
|  | GetNthClientInitiatedStreamId(1), &iov_, 1u, iov_.iov_len, 0u, kOffset, | 
|  | false, false, NOT_RETRANSMISSION, &frame)); | 
|  | size_t bytes_consumed = frame.stream_frame.data_length; | 
|  | EXPECT_LT(0u, bytes_consumed); | 
|  | creator_.FlushCurrentPacket(); | 
|  | ASSERT_TRUE(serialized_packet_.encrypted_buffer); | 
|  | if (bytes_free > 0) { | 
|  | EXPECT_EQ(kDefaultMaxPacketSize - bytes_free, | 
|  | serialized_packet_.encrypted_length); | 
|  | } else { | 
|  | EXPECT_EQ(kDefaultMaxPacketSize, serialized_packet_.encrypted_length); | 
|  | } | 
|  | DeleteSerializedPacket(); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, SerializeVersionNegotiationPacket) { | 
|  | QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_SERVER); | 
|  | ParsedQuicVersionVector versions; | 
|  | versions.push_back(test::QuicVersionMax()); | 
|  | const bool ietf_quic = | 
|  | VersionHasIetfInvariantHeader(GetParam().version.transport_version); | 
|  | const bool has_length_prefix = | 
|  | GetParam().version.HasLengthPrefixedConnectionIds(); | 
|  | std::unique_ptr<QuicEncryptedPacket> encrypted( | 
|  | creator_.SerializeVersionNegotiationPacket(ietf_quic, has_length_prefix, | 
|  | versions)); | 
|  |  | 
|  | { | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnVersionNegotiationPacket(_)); | 
|  | } | 
|  | QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_CLIENT); | 
|  | client_framer_.ProcessPacket(*encrypted); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, SerializeConnectivityProbingPacket) { | 
|  | for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) { | 
|  | EncryptionLevel level = static_cast<EncryptionLevel>(i); | 
|  |  | 
|  | creator_.set_encryption_level(level); | 
|  |  | 
|  | OwningSerializedPacketPointer encrypted; | 
|  | if (VersionHasIetfQuicFrames(GetParam().version.transport_version)) { | 
|  | QuicPathFrameBuffer payload = { | 
|  | {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}}; | 
|  | encrypted = | 
|  | creator_.SerializePathChallengeConnectivityProbingPacket(&payload); | 
|  | } else { | 
|  | encrypted = creator_.SerializeConnectivityProbingPacket(); | 
|  | } | 
|  | { | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)); | 
|  | if (VersionHasIetfQuicFrames(GetParam().version.transport_version)) { | 
|  | EXPECT_CALL(framer_visitor_, OnPathChallengeFrame(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)); | 
|  | } else { | 
|  | EXPECT_CALL(framer_visitor_, OnPingFrame(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)); | 
|  | } | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  | } | 
|  | // QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_SERVER); | 
|  | server_framer_.ProcessPacket(QuicEncryptedPacket( | 
|  | encrypted->encrypted_buffer, encrypted->encrypted_length)); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, SerializePathChallengeProbePacket) { | 
|  | if (!VersionHasIetfQuicFrames(GetParam().version.transport_version)) { | 
|  | return; | 
|  | } | 
|  | QuicPathFrameBuffer payload = { | 
|  | {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}}; | 
|  |  | 
|  | for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) { | 
|  | EncryptionLevel level = static_cast<EncryptionLevel>(i); | 
|  |  | 
|  | creator_.set_encryption_level(level); | 
|  |  | 
|  | OwningSerializedPacketPointer encrypted( | 
|  | creator_.SerializePathChallengeConnectivityProbingPacket(&payload)); | 
|  | { | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPathChallengeFrame(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  | } | 
|  | // QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_SERVER); | 
|  | server_framer_.ProcessPacket(QuicEncryptedPacket( | 
|  | encrypted->encrypted_buffer, encrypted->encrypted_length)); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket1PayloadPadded) { | 
|  | if (!VersionHasIetfQuicFrames(GetParam().version.transport_version)) { | 
|  | return; | 
|  | } | 
|  | QuicPathFrameBuffer payload0 = { | 
|  | {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}}; | 
|  |  | 
|  | for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) { | 
|  | EncryptionLevel level = static_cast<EncryptionLevel>(i); | 
|  | creator_.set_encryption_level(level); | 
|  |  | 
|  | QuicDeque<QuicPathFrameBuffer> payloads; | 
|  | payloads.push_back(payload0); | 
|  |  | 
|  | OwningSerializedPacketPointer encrypted( | 
|  | creator_.SerializePathResponseConnectivityProbingPacket(payloads, | 
|  | true)); | 
|  | { | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  | } | 
|  | server_framer_.ProcessPacket(QuicEncryptedPacket( | 
|  | encrypted->encrypted_buffer, encrypted->encrypted_length)); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, | 
|  | SerializePathResponseProbePacket1PayloadUnPadded) { | 
|  | if (!VersionHasIetfQuicFrames(GetParam().version.transport_version)) { | 
|  | return; | 
|  | } | 
|  | QuicPathFrameBuffer payload0 = { | 
|  | {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}}; | 
|  |  | 
|  | for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) { | 
|  | EncryptionLevel level = static_cast<EncryptionLevel>(i); | 
|  | creator_.set_encryption_level(level); | 
|  |  | 
|  | QuicDeque<QuicPathFrameBuffer> payloads; | 
|  | payloads.push_back(payload0); | 
|  |  | 
|  | OwningSerializedPacketPointer encrypted( | 
|  | creator_.SerializePathResponseConnectivityProbingPacket(payloads, | 
|  | false)); | 
|  | { | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  | } | 
|  | server_framer_.ProcessPacket(QuicEncryptedPacket( | 
|  | encrypted->encrypted_buffer, encrypted->encrypted_length)); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket2PayloadsPadded) { | 
|  | if (!VersionHasIetfQuicFrames(GetParam().version.transport_version)) { | 
|  | return; | 
|  | } | 
|  | QuicPathFrameBuffer payload0 = { | 
|  | {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}}; | 
|  | QuicPathFrameBuffer payload1 = { | 
|  | {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}}; | 
|  |  | 
|  | for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) { | 
|  | EncryptionLevel level = static_cast<EncryptionLevel>(i); | 
|  | creator_.set_encryption_level(level); | 
|  |  | 
|  | QuicDeque<QuicPathFrameBuffer> payloads; | 
|  | payloads.push_back(payload0); | 
|  | payloads.push_back(payload1); | 
|  |  | 
|  | OwningSerializedPacketPointer encrypted( | 
|  | creator_.SerializePathResponseConnectivityProbingPacket(payloads, | 
|  | true)); | 
|  | { | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(2); | 
|  | EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  | } | 
|  | server_framer_.ProcessPacket(QuicEncryptedPacket( | 
|  | encrypted->encrypted_buffer, encrypted->encrypted_length)); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, | 
|  | SerializePathResponseProbePacket2PayloadsUnPadded) { | 
|  | if (!VersionHasIetfQuicFrames(GetParam().version.transport_version)) { | 
|  | return; | 
|  | } | 
|  | QuicPathFrameBuffer payload0 = { | 
|  | {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}}; | 
|  | QuicPathFrameBuffer payload1 = { | 
|  | {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}}; | 
|  |  | 
|  | for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) { | 
|  | EncryptionLevel level = static_cast<EncryptionLevel>(i); | 
|  | creator_.set_encryption_level(level); | 
|  |  | 
|  | QuicDeque<QuicPathFrameBuffer> payloads; | 
|  | payloads.push_back(payload0); | 
|  | payloads.push_back(payload1); | 
|  |  | 
|  | OwningSerializedPacketPointer encrypted( | 
|  | creator_.SerializePathResponseConnectivityProbingPacket(payloads, | 
|  | false)); | 
|  | { | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(2); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  | } | 
|  | server_framer_.ProcessPacket(QuicEncryptedPacket( | 
|  | encrypted->encrypted_buffer, encrypted->encrypted_length)); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket3PayloadsPadded) { | 
|  | if (!VersionHasIetfQuicFrames(GetParam().version.transport_version)) { | 
|  | return; | 
|  | } | 
|  | QuicPathFrameBuffer payload0 = { | 
|  | {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}}; | 
|  | QuicPathFrameBuffer payload1 = { | 
|  | {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}}; | 
|  | QuicPathFrameBuffer payload2 = { | 
|  | {0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde, 0xad}}; | 
|  |  | 
|  | for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) { | 
|  | EncryptionLevel level = static_cast<EncryptionLevel>(i); | 
|  | creator_.set_encryption_level(level); | 
|  |  | 
|  | QuicDeque<QuicPathFrameBuffer> payloads; | 
|  | payloads.push_back(payload0); | 
|  | payloads.push_back(payload1); | 
|  | payloads.push_back(payload2); | 
|  |  | 
|  | OwningSerializedPacketPointer encrypted( | 
|  | creator_.SerializePathResponseConnectivityProbingPacket(payloads, | 
|  | true)); | 
|  | { | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(3); | 
|  | EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  | } | 
|  | server_framer_.ProcessPacket(QuicEncryptedPacket( | 
|  | encrypted->encrypted_buffer, encrypted->encrypted_length)); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, | 
|  | SerializePathResponseProbePacket3PayloadsUnpadded) { | 
|  | if (!VersionHasIetfQuicFrames(GetParam().version.transport_version)) { | 
|  | return; | 
|  | } | 
|  | QuicPathFrameBuffer payload0 = { | 
|  | {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}}; | 
|  | QuicPathFrameBuffer payload1 = { | 
|  | {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}}; | 
|  | QuicPathFrameBuffer payload2 = { | 
|  | {0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde, 0xad}}; | 
|  |  | 
|  | for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) { | 
|  | EncryptionLevel level = static_cast<EncryptionLevel>(i); | 
|  | creator_.set_encryption_level(level); | 
|  |  | 
|  | QuicDeque<QuicPathFrameBuffer> payloads; | 
|  | payloads.push_back(payload0); | 
|  | payloads.push_back(payload1); | 
|  | payloads.push_back(payload2); | 
|  |  | 
|  | OwningSerializedPacketPointer encrypted( | 
|  | creator_.SerializePathResponseConnectivityProbingPacket(payloads, | 
|  | false)); | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(3); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  |  | 
|  | server_framer_.ProcessPacket(QuicEncryptedPacket( | 
|  | encrypted->encrypted_buffer, encrypted->encrypted_length)); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, UpdatePacketSequenceNumberLengthLeastAwaiting) { | 
|  | if (VersionHasIetfInvariantHeader(GetParam().version.transport_version) && | 
|  | !GetParam().version.SendsVariableLengthPacketNumberInLongHeader()) { | 
|  | EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | } else { | 
|  | EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); | 
|  | } | 
|  |  | 
|  | QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64); | 
|  | creator_.UpdatePacketNumberLength(QuicPacketNumber(2), | 
|  | 10000 / kDefaultMaxPacketSize); | 
|  | EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); | 
|  |  | 
|  | QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64 * 256); | 
|  | creator_.UpdatePacketNumberLength(QuicPacketNumber(2), | 
|  | 10000 / kDefaultMaxPacketSize); | 
|  | EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); | 
|  |  | 
|  | QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64 * 256 * 256); | 
|  | creator_.UpdatePacketNumberLength(QuicPacketNumber(2), | 
|  | 10000 / kDefaultMaxPacketSize); | 
|  | EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); | 
|  |  | 
|  | QuicPacketCreatorPeer::SetPacketNumber(&creator_, | 
|  | UINT64_C(64) * 256 * 256 * 256 * 256); | 
|  | creator_.UpdatePacketNumberLength(QuicPacketNumber(2), | 
|  | 10000 / kDefaultMaxPacketSize); | 
|  | EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, UpdatePacketSequenceNumberLengthCwnd) { | 
|  | QuicPacketCreatorPeer::SetPacketNumber(&creator_, 1); | 
|  | if (VersionHasIetfInvariantHeader(GetParam().version.transport_version) && | 
|  | !GetParam().version.SendsVariableLengthPacketNumberInLongHeader()) { | 
|  | EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | } else { | 
|  | EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); | 
|  | } | 
|  |  | 
|  | creator_.UpdatePacketNumberLength(QuicPacketNumber(1), | 
|  | 10000 / kDefaultMaxPacketSize); | 
|  | EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); | 
|  |  | 
|  | creator_.UpdatePacketNumberLength(QuicPacketNumber(1), | 
|  | 10000 * 256 / kDefaultMaxPacketSize); | 
|  | EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); | 
|  |  | 
|  | creator_.UpdatePacketNumberLength(QuicPacketNumber(1), | 
|  | 10000 * 256 * 256 / kDefaultMaxPacketSize); | 
|  | EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); | 
|  |  | 
|  | creator_.UpdatePacketNumberLength( | 
|  | QuicPacketNumber(1), | 
|  | UINT64_C(1000) * 256 * 256 * 256 * 256 / kDefaultMaxPacketSize); | 
|  | EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, SkipNPacketNumbers) { | 
|  | QuicPacketCreatorPeer::SetPacketNumber(&creator_, 1); | 
|  | if (VersionHasIetfInvariantHeader(GetParam().version.transport_version) && | 
|  | !GetParam().version.SendsVariableLengthPacketNumberInLongHeader()) { | 
|  | EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | } else { | 
|  | EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); | 
|  | } | 
|  | creator_.SkipNPacketNumbers(63, QuicPacketNumber(2), | 
|  | 10000 / kDefaultMaxPacketSize); | 
|  | EXPECT_EQ(QuicPacketNumber(64), creator_.packet_number()); | 
|  | EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); | 
|  |  | 
|  | creator_.SkipNPacketNumbers(64 * 255, QuicPacketNumber(2), | 
|  | 10000 / kDefaultMaxPacketSize); | 
|  | EXPECT_EQ(QuicPacketNumber(64 * 256), creator_.packet_number()); | 
|  | EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); | 
|  |  | 
|  | creator_.SkipNPacketNumbers(64 * 256 * 255, QuicPacketNumber(2), | 
|  | 10000 / kDefaultMaxPacketSize); | 
|  | EXPECT_EQ(QuicPacketNumber(64 * 256 * 256), creator_.packet_number()); | 
|  | EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, SerializeFrame) { | 
|  | if (!GetParam().version_serialization) { | 
|  | creator_.StopSendingVersion(); | 
|  | } | 
|  | std::string data("test data"); | 
|  | if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { | 
|  | QuicStreamFrame stream_frame( | 
|  | QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), | 
|  | /*fin=*/false, 0u, QuicStringPiece()); | 
|  | frames_.push_back(QuicFrame(stream_frame)); | 
|  | } else { | 
|  | producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data); | 
|  | frames_.push_back( | 
|  | QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, 0, data.length()))); | 
|  | } | 
|  | SerializedPacket serialized = SerializeAllFrames(frames_); | 
|  |  | 
|  | QuicPacketHeader header; | 
|  | { | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)) | 
|  | .WillOnce(DoAll(SaveArg<0>(&header), Return(true))); | 
|  | if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { | 
|  | EXPECT_CALL(framer_visitor_, OnCryptoFrame(_)); | 
|  | } else { | 
|  | EXPECT_CALL(framer_visitor_, OnStreamFrame(_)); | 
|  | } | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  | } | 
|  | ProcessPacket(serialized); | 
|  | EXPECT_EQ(GetParam().version_serialization, header.version_flag); | 
|  | DeleteFrames(&frames_); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, SerializeFrameShortData) { | 
|  | if (!GetParam().version_serialization) { | 
|  | creator_.StopSendingVersion(); | 
|  | } | 
|  | std::string data("a"); | 
|  | if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { | 
|  | QuicStreamFrame stream_frame( | 
|  | QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), | 
|  | /*fin=*/false, 0u, QuicStringPiece()); | 
|  | frames_.push_back(QuicFrame(stream_frame)); | 
|  | } else { | 
|  | producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data); | 
|  | frames_.push_back( | 
|  | QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, 0, data.length()))); | 
|  | } | 
|  | SerializedPacket serialized = SerializeAllFrames(frames_); | 
|  |  | 
|  | QuicPacketHeader header; | 
|  | { | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)) | 
|  | .WillOnce(DoAll(SaveArg<0>(&header), Return(true))); | 
|  | if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { | 
|  | EXPECT_CALL(framer_visitor_, OnCryptoFrame(_)); | 
|  | } else { | 
|  | EXPECT_CALL(framer_visitor_, OnStreamFrame(_)); | 
|  | } | 
|  | if (client_framer_.version().HasHeaderProtection()) { | 
|  | EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)); | 
|  | } | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  | } | 
|  | ProcessPacket(serialized); | 
|  | EXPECT_EQ(GetParam().version_serialization, header.version_flag); | 
|  | DeleteFrames(&frames_); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, ConsumeDataLargerThanOneStreamFrame) { | 
|  | if (!GetParam().version_serialization) { | 
|  | creator_.StopSendingVersion(); | 
|  | } | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | // A string larger than fits into a frame. | 
|  | QuicFrame frame; | 
|  | size_t payload_length = creator_.max_packet_length(); | 
|  | const std::string too_long_payload(payload_length, 'a'); | 
|  | MakeIOVector(too_long_payload, &iov_); | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( | 
|  | client_framer_.transport_version(), Perspective::IS_CLIENT); | 
|  | ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( | 
|  | stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, true, false, | 
|  | NOT_RETRANSMISSION, &frame)); | 
|  | size_t consumed = frame.stream_frame.data_length; | 
|  | // The entire payload could not be consumed. | 
|  | EXPECT_GT(payload_length, consumed); | 
|  | creator_.FlushCurrentPacket(); | 
|  | DeleteSerializedPacket(); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, AddFrameAndFlush) { | 
|  | if (!GetParam().version_serialization) { | 
|  | creator_.StopSendingVersion(); | 
|  | } | 
|  | const size_t max_plaintext_size = | 
|  | client_framer_.GetMaxPlaintextSize(creator_.max_packet_length()); | 
|  | EXPECT_FALSE(creator_.HasPendingFrames()); | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( | 
|  | client_framer_.transport_version(), Perspective::IS_CLIENT); | 
|  | if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { | 
|  | stream_id = | 
|  | QuicUtils::GetCryptoStreamId(client_framer_.transport_version()); | 
|  | } | 
|  | EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id)); | 
|  | EXPECT_EQ(max_plaintext_size - | 
|  | GetPacketHeaderSize( | 
|  | client_framer_.transport_version(), | 
|  | creator_.GetDestinationConnectionIdLength(), | 
|  | creator_.GetSourceConnectionIdLength(), | 
|  | QuicPacketCreatorPeer::SendVersionInPacket(&creator_), | 
|  | !kIncludeDiversificationNonce, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_), | 
|  | QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), | 
|  | 0, QuicPacketCreatorPeer::GetLengthLength(&creator_)), | 
|  | creator_.BytesFree()); | 
|  | StrictMock<MockDebugDelegate> debug; | 
|  | creator_.set_debug_delegate(&debug); | 
|  |  | 
|  | // Add a variety of frame types and then a padding frame. | 
|  | QuicAckFrame ack_frame(InitAckFrame(10u)); | 
|  | EXPECT_CALL(debug, OnFrameAddedToPacket(_)); | 
|  | EXPECT_TRUE( | 
|  | creator_.AddSavedFrame(QuicFrame(&ack_frame), NOT_RETRANSMISSION)); | 
|  | EXPECT_TRUE(creator_.HasPendingFrames()); | 
|  | EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id)); | 
|  |  | 
|  | QuicFrame frame; | 
|  | MakeIOVector("test", &iov_); | 
|  | EXPECT_CALL(debug, OnFrameAddedToPacket(_)); | 
|  | ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( | 
|  | stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, false, false, | 
|  | NOT_RETRANSMISSION, &frame)); | 
|  | size_t consumed = frame.stream_frame.data_length; | 
|  | EXPECT_EQ(4u, consumed); | 
|  | EXPECT_TRUE(creator_.HasPendingFrames()); | 
|  | EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(stream_id)); | 
|  |  | 
|  | QuicPaddingFrame padding_frame; | 
|  | EXPECT_CALL(debug, OnFrameAddedToPacket(_)); | 
|  | EXPECT_TRUE( | 
|  | creator_.AddSavedFrame(QuicFrame(padding_frame), NOT_RETRANSMISSION)); | 
|  | EXPECT_TRUE(creator_.HasPendingFrames()); | 
|  | EXPECT_EQ(0u, creator_.BytesFree()); | 
|  |  | 
|  | // Packet is full. Creator will flush. | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | EXPECT_FALSE( | 
|  | creator_.AddSavedFrame(QuicFrame(&ack_frame), NOT_RETRANSMISSION)); | 
|  |  | 
|  | // Ensure the packet is successfully created. | 
|  | ASSERT_TRUE(serialized_packet_.encrypted_buffer); | 
|  | ASSERT_FALSE(serialized_packet_.retransmittable_frames.empty()); | 
|  | const QuicFrames& retransmittable = serialized_packet_.retransmittable_frames; | 
|  | ASSERT_EQ(1u, retransmittable.size()); | 
|  | EXPECT_EQ(STREAM_FRAME, retransmittable[0].type); | 
|  | EXPECT_TRUE(serialized_packet_.has_ack); | 
|  | EXPECT_EQ(QuicPacketNumber(10u), serialized_packet_.largest_acked); | 
|  | DeleteSerializedPacket(); | 
|  |  | 
|  | EXPECT_FALSE(creator_.HasPendingFrames()); | 
|  | EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id)); | 
|  | EXPECT_EQ(max_plaintext_size - | 
|  | GetPacketHeaderSize( | 
|  | client_framer_.transport_version(), | 
|  | creator_.GetDestinationConnectionIdLength(), | 
|  | creator_.GetSourceConnectionIdLength(), | 
|  | QuicPacketCreatorPeer::SendVersionInPacket(&creator_), | 
|  | !kIncludeDiversificationNonce, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_), | 
|  | QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), | 
|  | 0, QuicPacketCreatorPeer::GetLengthLength(&creator_)), | 
|  | creator_.BytesFree()); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, SerializeAndSendStreamFrame) { | 
|  | if (!GetParam().version_serialization) { | 
|  | creator_.StopSendingVersion(); | 
|  | } | 
|  | EXPECT_FALSE(creator_.HasPendingFrames()); | 
|  |  | 
|  | MakeIOVector("test", &iov_); | 
|  | producer_.SaveStreamData(GetNthClientInitiatedStreamId(0), &iov_, 1u, 0u, | 
|  | iov_.iov_len); | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | size_t num_bytes_consumed; | 
|  | StrictMock<MockDebugDelegate> debug; | 
|  | creator_.set_debug_delegate(&debug); | 
|  | EXPECT_CALL(debug, OnFrameAddedToPacket(_)); | 
|  | creator_.CreateAndSerializeStreamFrame( | 
|  | GetNthClientInitiatedStreamId(0), iov_.iov_len, 0, 0, true, | 
|  | NOT_RETRANSMISSION, &num_bytes_consumed); | 
|  | EXPECT_EQ(4u, num_bytes_consumed); | 
|  |  | 
|  | // Ensure the packet is successfully created. | 
|  | ASSERT_TRUE(serialized_packet_.encrypted_buffer); | 
|  | ASSERT_FALSE(serialized_packet_.retransmittable_frames.empty()); | 
|  | const QuicFrames& retransmittable = serialized_packet_.retransmittable_frames; | 
|  | ASSERT_EQ(1u, retransmittable.size()); | 
|  | EXPECT_EQ(STREAM_FRAME, retransmittable[0].type); | 
|  | DeleteSerializedPacket(); | 
|  |  | 
|  | EXPECT_FALSE(creator_.HasPendingFrames()); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, SerializeStreamFrameWithPadding) { | 
|  | // Regression test to check that CreateAndSerializeStreamFrame uses a | 
|  | // correctly formatted stream frame header when appending padding. | 
|  |  | 
|  | if (!GetParam().version_serialization) { | 
|  | creator_.StopSendingVersion(); | 
|  | } | 
|  | EXPECT_FALSE(creator_.HasPendingFrames()); | 
|  |  | 
|  | // Send one byte of stream data. | 
|  | MakeIOVector("a", &iov_); | 
|  | producer_.SaveStreamData(GetNthClientInitiatedStreamId(0), &iov_, 1u, 0u, | 
|  | iov_.iov_len); | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | size_t num_bytes_consumed; | 
|  | creator_.CreateAndSerializeStreamFrame( | 
|  | GetNthClientInitiatedStreamId(0), iov_.iov_len, 0, 0, true, | 
|  | NOT_RETRANSMISSION, &num_bytes_consumed); | 
|  | EXPECT_EQ(1u, num_bytes_consumed); | 
|  |  | 
|  | // Check that a packet is created. | 
|  | ASSERT_TRUE(serialized_packet_.encrypted_buffer); | 
|  | ASSERT_FALSE(serialized_packet_.retransmittable_frames.empty()); | 
|  | { | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnStreamFrame(_)); | 
|  | if (client_framer_.version().HasHeaderProtection()) { | 
|  | EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)); | 
|  | } | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  | } | 
|  | ProcessPacket(serialized_packet_); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, AddUnencryptedStreamDataClosesConnection) { | 
|  | // EXPECT_QUIC_BUG tests are expensive so only run one instance of them. | 
|  | if (!IsDefaultTestConfiguration()) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | creator_.set_encryption_level(ENCRYPTION_INITIAL); | 
|  | EXPECT_CALL(delegate_, OnUnrecoverableError(_, _)); | 
|  | QuicStreamFrame stream_frame(GetNthClientInitiatedStreamId(0), | 
|  | /*fin=*/false, 0u, QuicStringPiece()); | 
|  | EXPECT_QUIC_BUG( | 
|  | creator_.AddSavedFrame(QuicFrame(stream_frame), NOT_RETRANSMISSION), | 
|  | "Cannot send stream data with level: ENCRYPTION_INITIAL"); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, SendStreamDataWithEncryptionHandshake) { | 
|  | // EXPECT_QUIC_BUG tests are expensive so only run one instance of them. | 
|  | if (!IsDefaultTestConfiguration()) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | creator_.set_encryption_level(ENCRYPTION_HANDSHAKE); | 
|  | EXPECT_CALL(delegate_, OnUnrecoverableError(_, _)); | 
|  | QuicStreamFrame stream_frame(GetNthClientInitiatedStreamId(0), | 
|  | /*fin=*/false, 0u, QuicStringPiece()); | 
|  | EXPECT_QUIC_BUG( | 
|  | creator_.AddSavedFrame(QuicFrame(stream_frame), NOT_RETRANSMISSION), | 
|  | "Cannot send stream data with level: ENCRYPTION_HANDSHAKE"); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, ChloTooLarge) { | 
|  | // EXPECT_QUIC_BUG tests are expensive so only run one instance of them. | 
|  | if (!IsDefaultTestConfiguration()) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | // This test only matters when the crypto handshake is sent in stream frames. | 
|  | // TODO(b/128596274): Re-enable when this check is supported for CRYPTO | 
|  | // frames. | 
|  | if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | CryptoHandshakeMessage message; | 
|  | message.set_tag(kCHLO); | 
|  | message.set_minimum_size(kMaxOutgoingPacketSize); | 
|  | CryptoFramer framer; | 
|  | std::unique_ptr<QuicData> message_data; | 
|  | message_data = framer.ConstructHandshakeMessage(message); | 
|  |  | 
|  | struct iovec iov; | 
|  | MakeIOVector(QuicStringPiece(message_data->data(), message_data->length()), | 
|  | &iov); | 
|  | QuicFrame frame; | 
|  | EXPECT_CALL(delegate_, OnUnrecoverableError(QUIC_CRYPTO_CHLO_TOO_LARGE, _)); | 
|  | EXPECT_QUIC_BUG( | 
|  | creator_.ConsumeDataToFillCurrentPacket( | 
|  | QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), | 
|  | &iov, 1u, iov.iov_len, 0u, 0u, false, false, NOT_RETRANSMISSION, | 
|  | &frame), | 
|  | "Client hello won't fit in a single packet."); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, PendingPadding) { | 
|  | EXPECT_EQ(0u, creator_.pending_padding_bytes()); | 
|  | creator_.AddPendingPadding(kMaxNumRandomPaddingBytes * 10); | 
|  | EXPECT_EQ(kMaxNumRandomPaddingBytes * 10, creator_.pending_padding_bytes()); | 
|  |  | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillRepeatedly( | 
|  | Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | // Flush all paddings. | 
|  | while (creator_.pending_padding_bytes() > 0) { | 
|  | creator_.FlushCurrentPacket(); | 
|  | { | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  | } | 
|  | // Packet only contains padding. | 
|  | ProcessPacket(serialized_packet_); | 
|  | } | 
|  | EXPECT_EQ(0u, creator_.pending_padding_bytes()); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, FullPaddingDoesNotConsumePendingPadding) { | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | creator_.AddPendingPadding(kMaxNumRandomPaddingBytes); | 
|  | QuicFrame frame; | 
|  | MakeIOVector("test", &iov_); | 
|  | QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( | 
|  | client_framer_.transport_version(), Perspective::IS_CLIENT); | 
|  | ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( | 
|  | stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, false, | 
|  | /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame)); | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | creator_.FlushCurrentPacket(); | 
|  | EXPECT_EQ(kMaxNumRandomPaddingBytes, creator_.pending_padding_bytes()); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, SendPendingPaddingInRetransmission) { | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( | 
|  | client_framer_.transport_version(), Perspective::IS_CLIENT); | 
|  | QuicStreamFrame stream_frame(stream_id, | 
|  | /*fin=*/false, 0u, QuicStringPiece()); | 
|  | QuicFrames frames; | 
|  | frames.push_back(QuicFrame(stream_frame)); | 
|  | char buffer[kMaxOutgoingPacketSize]; | 
|  | QuicPendingRetransmission retransmission(CreateRetransmission( | 
|  | frames, true, /*num_padding_bytes=*/0, ENCRYPTION_FORWARD_SECURE, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_))); | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | creator_.AddPendingPadding(kMaxNumRandomPaddingBytes); | 
|  | creator_.ReserializeAllFrames(retransmission, buffer, kMaxOutgoingPacketSize); | 
|  | EXPECT_EQ(0u, creator_.pending_padding_bytes()); | 
|  | { | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnStreamFrame(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  | } | 
|  | ProcessPacket(serialized_packet_); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, SendPacketAfterFullPaddingRetransmission) { | 
|  | // Making sure needs_full_padding gets reset after a full padding | 
|  | // retransmission. | 
|  | EXPECT_EQ(0u, creator_.pending_padding_bytes()); | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | QuicFrame frame; | 
|  | std::string data = "fake handshake message data"; | 
|  | MakeIOVector(data, &iov_); | 
|  | QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( | 
|  | client_framer_.transport_version(), Perspective::IS_CLIENT); | 
|  | if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { | 
|  | stream_id = | 
|  | QuicUtils::GetCryptoStreamId(client_framer_.transport_version()); | 
|  | } | 
|  | producer_.SaveStreamData(stream_id, &iov_, 1u, 0u, iov_.iov_len); | 
|  | QuicPacketCreatorPeer::CreateStreamFrame(&creator_, stream_id, iov_.iov_len, | 
|  | 0u, false, &frame); | 
|  | QuicFrames frames; | 
|  | frames.push_back(frame); | 
|  | char buffer[kMaxOutgoingPacketSize]; | 
|  | QuicPendingRetransmission retransmission(CreateRetransmission( | 
|  | frames, true, /*num_padding_bytes=*/-1, ENCRYPTION_FORWARD_SECURE, | 
|  | QuicPacketCreatorPeer::GetPacketNumberLength(&creator_))); | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillRepeatedly( | 
|  | Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | creator_.ReserializeAllFrames(retransmission, buffer, kMaxOutgoingPacketSize); | 
|  | EXPECT_EQ(kDefaultMaxPacketSize, serialized_packet_.encrypted_length); | 
|  | { | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnStreamFrame(_)); | 
|  | // Full padding. | 
|  | EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  | } | 
|  | ProcessPacket(serialized_packet_); | 
|  |  | 
|  | creator_.ConsumeDataToFillCurrentPacket(stream_id, &iov_, 1u, iov_.iov_len, | 
|  | 0u, 0u, false, false, | 
|  | NOT_RETRANSMISSION, &frame); | 
|  | creator_.FlushCurrentPacket(); | 
|  | { | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnStreamFrame(_)); | 
|  | // needs_full_padding gets reset. | 
|  | EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)).Times(0); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  | } | 
|  | ProcessPacket(serialized_packet_); | 
|  | DeleteFrames(&frames); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, ConsumeDataAndRandomPadding) { | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | const QuicByteCount kStreamFramePayloadSize = 100u; | 
|  | // Set the packet size be enough for one stream frame with 0 stream offset + | 
|  | // 1. | 
|  | QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( | 
|  | client_framer_.transport_version(), Perspective::IS_CLIENT); | 
|  | size_t length = | 
|  | GetPacketHeaderOverhead(client_framer_.transport_version()) + | 
|  | GetEncryptionOverhead() + | 
|  | QuicFramer::GetMinStreamFrameSize( | 
|  | client_framer_.transport_version(), stream_id, 0, | 
|  | /*last_frame_in_packet=*/false, kStreamFramePayloadSize + 1) + | 
|  | kStreamFramePayloadSize + 1; | 
|  | creator_.SetMaxPacketLength(length); | 
|  | creator_.AddPendingPadding(kMaxNumRandomPaddingBytes); | 
|  | QuicByteCount pending_padding_bytes = creator_.pending_padding_bytes(); | 
|  | QuicFrame frame; | 
|  | char buf[kStreamFramePayloadSize + 1] = {}; | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillRepeatedly( | 
|  | Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | // Send stream frame of size kStreamFramePayloadSize. | 
|  | MakeIOVector(QuicStringPiece(buf, kStreamFramePayloadSize), &iov_); | 
|  | creator_.ConsumeDataToFillCurrentPacket(stream_id, &iov_, 1u, iov_.iov_len, | 
|  | 0u, 0u, false, false, | 
|  | NOT_RETRANSMISSION, &frame); | 
|  | creator_.FlushCurrentPacket(); | 
|  | // 1 byte padding is sent. | 
|  | EXPECT_EQ(pending_padding_bytes - 1, creator_.pending_padding_bytes()); | 
|  | // Send stream frame of size kStreamFramePayloadSize + 1. | 
|  | MakeIOVector(QuicStringPiece(buf, kStreamFramePayloadSize + 1), &iov_); | 
|  | creator_.ConsumeDataToFillCurrentPacket(stream_id, &iov_, 1u, iov_.iov_len, | 
|  | 0u, kStreamFramePayloadSize, false, | 
|  | false, NOT_RETRANSMISSION, &frame); | 
|  | // No padding is sent. | 
|  | creator_.FlushCurrentPacket(); | 
|  | EXPECT_EQ(pending_padding_bytes - 1, creator_.pending_padding_bytes()); | 
|  | // Flush all paddings. | 
|  | while (creator_.pending_padding_bytes() > 0) { | 
|  | creator_.FlushCurrentPacket(); | 
|  | } | 
|  | EXPECT_EQ(0u, creator_.pending_padding_bytes()); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, FlushWithExternalBuffer) { | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | char external_buffer[kMaxOutgoingPacketSize]; | 
|  | char* expected_buffer = external_buffer; | 
|  | EXPECT_CALL(delegate_, GetPacketBuffer()).WillOnce(Return(expected_buffer)); | 
|  |  | 
|  | QuicFrame frame; | 
|  | MakeIOVector("test", &iov_); | 
|  | QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( | 
|  | client_framer_.transport_version(), Perspective::IS_CLIENT); | 
|  | ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket( | 
|  | stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, false, | 
|  | /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame)); | 
|  |  | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillOnce(Invoke([expected_buffer](SerializedPacket* serialized_packet) { | 
|  | EXPECT_EQ(expected_buffer, serialized_packet->encrypted_buffer); | 
|  | ClearSerializedPacket(serialized_packet); | 
|  | })); | 
|  | creator_.FlushCurrentPacket(); | 
|  | } | 
|  |  | 
|  | // Test for error found in | 
|  | // https://bugs.chromium.org/p/chromium/issues/detail?id=859949 where a gap | 
|  | // length that crosses an IETF VarInt length boundary would cause a | 
|  | // failure. While this test is not applicable to versions other than version 99, | 
|  | // it should still work. Hence, it is not made version-specific. | 
|  | TEST_P(QuicPacketCreatorTest, IetfAckGapErrorRegression) { | 
|  | QuicAckFrame ack_frame = | 
|  | InitAckFrame({{QuicPacketNumber(60), QuicPacketNumber(61)}, | 
|  | {QuicPacketNumber(125), QuicPacketNumber(126)}}); | 
|  | frames_.push_back(QuicFrame(&ack_frame)); | 
|  | SerializeAllFrames(frames_); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, AddMessageFrame) { | 
|  | if (!VersionSupportsMessageFrames(client_framer_.transport_version())) { | 
|  | return; | 
|  | } | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .Times(3) | 
|  | .WillRepeatedly( | 
|  | Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacketForTests)); | 
|  | QuicMemSliceStorage storage(nullptr, 0, nullptr, 0); | 
|  | // Verify that there is enough room for the largest message payload. | 
|  | EXPECT_TRUE(creator_.HasRoomForMessageFrame( | 
|  | creator_.GetCurrentLargestMessagePayload())); | 
|  | std::string message(creator_.GetCurrentLargestMessagePayload(), 'a'); | 
|  | QuicMessageFrame* message_frame = | 
|  | new QuicMessageFrame(1, MakeSpan(&allocator_, message, &storage)); | 
|  | EXPECT_TRUE( | 
|  | creator_.AddSavedFrame(QuicFrame(message_frame), NOT_RETRANSMISSION)); | 
|  | EXPECT_TRUE(creator_.HasPendingFrames()); | 
|  | creator_.FlushCurrentPacket(); | 
|  |  | 
|  | QuicMessageFrame* frame2 = | 
|  | new QuicMessageFrame(2, MakeSpan(&allocator_, "message", &storage)); | 
|  | EXPECT_TRUE(creator_.AddSavedFrame(QuicFrame(frame2), NOT_RETRANSMISSION)); | 
|  | EXPECT_TRUE(creator_.HasPendingFrames()); | 
|  | // Verify if a new frame is added, 1 byte message length will be added. | 
|  | EXPECT_EQ(1u, creator_.ExpansionOnNewFrame()); | 
|  | QuicMessageFrame* frame3 = | 
|  | new QuicMessageFrame(3, MakeSpan(&allocator_, "message2", &storage)); | 
|  | EXPECT_TRUE(creator_.AddSavedFrame(QuicFrame(frame3), NOT_RETRANSMISSION)); | 
|  | EXPECT_EQ(1u, creator_.ExpansionOnNewFrame()); | 
|  | creator_.FlushCurrentPacket(); | 
|  |  | 
|  | QuicFrame frame; | 
|  | MakeIOVector("test", &iov_); | 
|  | QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( | 
|  | client_framer_.transport_version(), Perspective::IS_CLIENT); | 
|  | EXPECT_TRUE(creator_.ConsumeDataToFillCurrentPacket( | 
|  | stream_id, &iov_, 1u, iov_.iov_len, 0u, 0u, false, false, | 
|  | NOT_RETRANSMISSION, &frame)); | 
|  | QuicMessageFrame* frame4 = | 
|  | new QuicMessageFrame(4, MakeSpan(&allocator_, "message", &storage)); | 
|  | EXPECT_TRUE(creator_.AddSavedFrame(QuicFrame(frame4), NOT_RETRANSMISSION)); | 
|  | EXPECT_TRUE(creator_.HasPendingFrames()); | 
|  | // Verify there is not enough room for largest payload. | 
|  | EXPECT_FALSE(creator_.HasRoomForMessageFrame( | 
|  | creator_.GetCurrentLargestMessagePayload())); | 
|  | // Add largest message will causes the flush of the stream frame. | 
|  | QuicMessageFrame frame5(5, MakeSpan(&allocator_, message, &storage)); | 
|  | EXPECT_FALSE(creator_.AddSavedFrame(QuicFrame(&frame5), NOT_RETRANSMISSION)); | 
|  | EXPECT_FALSE(creator_.HasPendingFrames()); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, MessageFrameConsumption) { | 
|  | if (!VersionSupportsMessageFrames(client_framer_.transport_version())) { | 
|  | return; | 
|  | } | 
|  | std::string message_data(kDefaultMaxPacketSize, 'a'); | 
|  | QuicStringPiece message_buffer(message_data); | 
|  | QuicMemSliceStorage storage(nullptr, 0, nullptr, 0); | 
|  | // Test all possible encryption levels of message frames. | 
|  | for (EncryptionLevel level : | 
|  | {ENCRYPTION_ZERO_RTT, ENCRYPTION_FORWARD_SECURE}) { | 
|  | creator_.set_encryption_level(level); | 
|  | // Test all possible sizes of message frames. | 
|  | for (size_t message_size = 0; | 
|  | message_size <= creator_.GetCurrentLargestMessagePayload(); | 
|  | ++message_size) { | 
|  | QuicMessageFrame* frame = new QuicMessageFrame( | 
|  | 0, MakeSpan(&allocator_, | 
|  | QuicStringPiece(message_buffer.data(), message_size), | 
|  | &storage)); | 
|  | EXPECT_TRUE(creator_.AddSavedFrame(QuicFrame(frame), NOT_RETRANSMISSION)); | 
|  | EXPECT_TRUE(creator_.HasPendingFrames()); | 
|  |  | 
|  | size_t expansion_bytes = message_size >= 64 ? 2 : 1; | 
|  | EXPECT_EQ(expansion_bytes, creator_.ExpansionOnNewFrame()); | 
|  | // Verify BytesFree returns bytes available for the next frame, which | 
|  | // should subtract the message length. | 
|  | size_t expected_bytes_free = | 
|  | creator_.GetCurrentLargestMessagePayload() - message_size < | 
|  | expansion_bytes | 
|  | ? 0 | 
|  | : creator_.GetCurrentLargestMessagePayload() - expansion_bytes - | 
|  | message_size; | 
|  | EXPECT_EQ(expected_bytes_free, creator_.BytesFree()); | 
|  | EXPECT_LE(creator_.GetGuaranteedLargestMessagePayload(), | 
|  | creator_.GetCurrentLargestMessagePayload()); | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  | creator_.FlushCurrentPacket(); | 
|  | ASSERT_TRUE(serialized_packet_.encrypted_buffer); | 
|  | DeleteSerializedPacket(); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | // Regression test for bugfix of GetPacketHeaderSize. | 
|  | TEST_P(QuicPacketCreatorTest, GetGuaranteedLargestMessagePayload) { | 
|  | QuicTransportVersion version = GetParam().version.transport_version; | 
|  | if (!VersionSupportsMessageFrames(version)) { | 
|  | return; | 
|  | } | 
|  | QuicPacketLength expected_largest_payload = 1319; | 
|  | if (QuicVersionHasLongHeaderLengths(version)) { | 
|  | expected_largest_payload -= 2; | 
|  | } | 
|  | if (GetParam().version.HasLengthPrefixedConnectionIds()) { | 
|  | expected_largest_payload -= 1; | 
|  | } | 
|  | EXPECT_EQ(expected_largest_payload, | 
|  | creator_.GetGuaranteedLargestMessagePayload()); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, PacketTransmissionType) { | 
|  | creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); | 
|  | creator_.set_can_set_transmission_type(true); | 
|  | creator_.SetTransmissionTypeOfNextPackets(NOT_RETRANSMISSION); | 
|  |  | 
|  | QuicAckFrame temp_ack_frame = InitAckFrame(1); | 
|  | QuicFrame ack_frame(&temp_ack_frame); | 
|  | ASSERT_FALSE(QuicUtils::IsRetransmittableFrame(ack_frame.type)); | 
|  |  | 
|  | QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId( | 
|  | client_framer_.transport_version(), Perspective::IS_CLIENT); | 
|  | QuicFrame stream_frame(QuicStreamFrame(stream_id, | 
|  | /*fin=*/false, 0u, QuicStringPiece())); | 
|  | ASSERT_TRUE(QuicUtils::IsRetransmittableFrame(stream_frame.type)); | 
|  |  | 
|  | QuicFrame padding_frame{QuicPaddingFrame()}; | 
|  | ASSERT_FALSE(QuicUtils::IsRetransmittableFrame(padding_frame.type)); | 
|  |  | 
|  | EXPECT_CALL(delegate_, OnSerializedPacket(_)) | 
|  | .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); | 
|  |  | 
|  | EXPECT_TRUE(creator_.AddSavedFrame(ack_frame, LOSS_RETRANSMISSION)); | 
|  | ASSERT_FALSE(serialized_packet_.encrypted_buffer); | 
|  |  | 
|  | EXPECT_TRUE(creator_.AddSavedFrame(stream_frame, RTO_RETRANSMISSION)); | 
|  | ASSERT_FALSE(serialized_packet_.encrypted_buffer); | 
|  |  | 
|  | EXPECT_TRUE(creator_.AddSavedFrame(padding_frame, TLP_RETRANSMISSION)); | 
|  | creator_.FlushCurrentPacket(); | 
|  | ASSERT_TRUE(serialized_packet_.encrypted_buffer); | 
|  |  | 
|  | if (creator_.can_set_transmission_type()) { | 
|  | // The last retransmittable frame on packet is a stream frame, the packet's | 
|  | // transmission type should be the same as the stream frame's. | 
|  | EXPECT_EQ(serialized_packet_.transmission_type, RTO_RETRANSMISSION); | 
|  | } else { | 
|  | EXPECT_EQ(serialized_packet_.transmission_type, NOT_RETRANSMISSION); | 
|  | } | 
|  | DeleteSerializedPacket(); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, RetryToken) { | 
|  | if (!GetParam().version_serialization || | 
|  | !QuicVersionHasLongHeaderLengths(client_framer_.transport_version())) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | char retry_token_bytes[] = {1, 2,  3,  4,  5,  6,  7,  8, | 
|  | 9, 10, 11, 12, 13, 14, 15, 16}; | 
|  |  | 
|  | creator_.SetRetryToken( | 
|  | std::string(retry_token_bytes, sizeof(retry_token_bytes))); | 
|  |  | 
|  | std::string data("a"); | 
|  | if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { | 
|  | QuicStreamFrame stream_frame( | 
|  | QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), | 
|  | /*fin=*/false, 0u, QuicStringPiece()); | 
|  | frames_.push_back(QuicFrame(stream_frame)); | 
|  | } else { | 
|  | producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data); | 
|  | frames_.push_back( | 
|  | QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, 0, data.length()))); | 
|  | } | 
|  | SerializedPacket serialized = SerializeAllFrames(frames_); | 
|  |  | 
|  | QuicPacketHeader header; | 
|  | { | 
|  | InSequence s; | 
|  | EXPECT_CALL(framer_visitor_, OnPacket()); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); | 
|  | EXPECT_CALL(framer_visitor_, OnPacketHeader(_)) | 
|  | .WillOnce(DoAll(SaveArg<0>(&header), Return(true))); | 
|  | if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) { | 
|  | EXPECT_CALL(framer_visitor_, OnCryptoFrame(_)); | 
|  | } else { | 
|  | EXPECT_CALL(framer_visitor_, OnStreamFrame(_)); | 
|  | } | 
|  | if (client_framer_.version().HasHeaderProtection()) { | 
|  | EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)); | 
|  | } | 
|  | EXPECT_CALL(framer_visitor_, OnPacketComplete()); | 
|  | } | 
|  | ProcessPacket(serialized); | 
|  | ASSERT_TRUE(header.version_flag); | 
|  | ASSERT_EQ(header.long_packet_type, INITIAL); | 
|  | ASSERT_EQ(header.retry_token.length(), sizeof(retry_token_bytes)); | 
|  | test::CompareCharArraysWithHexError( | 
|  | "retry token", header.retry_token.data(), header.retry_token.length(), | 
|  | retry_token_bytes, sizeof(retry_token_bytes)); | 
|  | DeleteFrames(&frames_); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, GetConnectionId) { | 
|  | EXPECT_EQ(TestConnectionId(2), creator_.GetDestinationConnectionId()); | 
|  | EXPECT_EQ(EmptyQuicConnectionId(), creator_.GetSourceConnectionId()); | 
|  | } | 
|  |  | 
|  | TEST_P(QuicPacketCreatorTest, ClientConnectionId) { | 
|  | if (!client_framer_.version().SupportsClientConnectionIds()) { | 
|  | return; | 
|  | } | 
|  | EXPECT_EQ(TestConnectionId(2), creator_.GetDestinationConnectionId()); | 
|  | EXPECT_EQ(EmptyQuicConnectionId(), creator_.GetSourceConnectionId()); | 
|  | creator_.SetClientConnectionId(TestConnectionId(0x33)); | 
|  | EXPECT_EQ(TestConnectionId(2), creator_.GetDestinationConnectionId()); | 
|  | EXPECT_EQ(TestConnectionId(0x33), creator_.GetSourceConnectionId()); | 
|  | } | 
|  |  | 
|  | }  // namespace | 
|  | }  // namespace test | 
|  | }  // namespace quic |