diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-03-11 11:32:04 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-03-18 13:40:17 +0000 |
commit | 31ccca0778db85c159634478b4ec7997f6704860 (patch) | |
tree | 3d33fc3afd9d5ec95541e1bbe074a9cf8da12a0e /chromium/net/third_party/quiche/src/quic/test_tools | |
parent | 248b70b82a40964d5594eb04feca0fa36716185d (diff) | |
download | qtwebengine-chromium-31ccca0778db85c159634478b4ec7997f6704860.tar.gz |
BASELINE: Update Chromium to 80.0.3987.136
Change-Id: I98e1649aafae85ba3a83e67af00bb27ef301db7b
Reviewed-by: Jüri Valdmann <juri.valdmann@qt.io>
Diffstat (limited to 'chromium/net/third_party/quiche/src/quic/test_tools')
47 files changed, 1454 insertions, 508 deletions
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.cc b/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.cc index 98d65e8d0fe..6716dec2605 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.cc @@ -209,7 +209,14 @@ class FullChloGenerator { } // namespace +std::unique_ptr<QuicCryptoServerConfig> CryptoServerConfigForTesting() { + return std::make_unique<QuicCryptoServerConfig>( + QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(), + ProofSourceForTesting(), KeyExchangeSource::Default()); +} + int HandshakeWithFakeServer(QuicConfig* server_quic_config, + QuicCryptoServerConfig* crypto_config, MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory, PacketSavingConnection* client_conn, @@ -219,19 +226,19 @@ int HandshakeWithFakeServer(QuicConfig* server_quic_config, helper, alarm_factory, Perspective::IS_SERVER, ParsedVersionOfIndex(client_conn->supported_versions(), 0)); - QuicCryptoServerConfig crypto_config( - QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(), - ProofSourceForTesting(), KeyExchangeSource::Default()); QuicCompressedCertsCache compressed_certs_cache( QuicCompressedCertsCache::kQuicCompressedCertsCacheSize); SetupCryptoServerConfigForTest( - server_conn->clock(), server_conn->random_generator(), &crypto_config); + server_conn->clock(), server_conn->random_generator(), crypto_config); TestQuicSpdyServerSession server_session( server_conn, *server_quic_config, client_conn->supported_versions(), - &crypto_config, &compressed_certs_cache); - server_session.OnSuccessfulVersionNegotiation( - client_conn->supported_versions().front()); + crypto_config, &compressed_certs_cache); + server_session.Initialize(); + if (!GetQuicReloadableFlag(quic_version_negotiated_by_default_at_server)) { + server_session.OnSuccessfulVersionNegotiation( + client_conn->supported_versions().front()); + } EXPECT_CALL(*server_session.helper(), CanAcceptClientHello(testing::_, testing::_, testing::_, testing::_, testing::_)) @@ -346,7 +353,8 @@ void CommunicateHandshakeMessages(PacketSavingConnection* client_conn, MovePackets(client_conn, &client_i, server, server_conn, Perspective::IS_SERVER); - if (client->handshake_confirmed() && server->handshake_confirmed()) { + if (client->handshake_confirmed() && server->handshake_confirmed() && + server_conn->encrypted_packets_.size() == server_i) { break; } ASSERT_GT(server_conn->encrypted_packets_.size(), server_i); @@ -782,7 +790,7 @@ std::string GenerateClientNonceHex(const QuicClock* clock, QuicRandom::GetInstance(), clock, new_config_options); primary_config.set_primary_time(clock->WallNow().ToUNIXSeconds()); std::unique_ptr<CryptoHandshakeMessage> msg = - crypto_config->AddConfig(std::move(primary_config), clock->WallNow()); + crypto_config->AddConfig(primary_config, clock->WallNow()); QuicStringPiece orbit; CHECK(msg->GetStringPiece(kORBT, &orbit)); std::string nonce; diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h b/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h index 6f87e90494c..327eb673523 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h @@ -64,8 +64,13 @@ struct FakeClientOptions { bool only_tls_versions = false; }; +// Returns a QuicCryptoServerConfig that is in a reasonable configuration to +// pass into HandshakeWithFakeServer. +std::unique_ptr<QuicCryptoServerConfig> CryptoServerConfigForTesting(); + // returns: the number of client hellos that the client sent. int HandshakeWithFakeServer(QuicConfig* server_quic_config, + QuicCryptoServerConfig* crypto_config, MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory, PacketSavingConnection* client_conn, diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils_test.cc b/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils_test.cc index 59a3947393e..656549772fa 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils_test.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils_test.cc @@ -128,7 +128,7 @@ TEST_F(CryptoTestUtilsTest, TestGenerateFullCHLO) { QuicRandom::GetInstance(), &clock, new_config_options); primary_config.set_primary_time(clock.WallNow().ToUNIXSeconds()); std::unique_ptr<CryptoHandshakeMessage> msg = - crypto_config.AddConfig(std::move(primary_config), clock.WallNow()); + crypto_config.AddConfig(primary_config, clock.WallNow()); QuicStringPiece orbit; ASSERT_TRUE(msg->GetStringPiece(kORBT, &orbit)); std::string nonce; diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.cc b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.cc new file mode 100644 index 00000000000..2b835ae2e46 --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.cc @@ -0,0 +1,88 @@ +// Copyright (c) 2018 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/test_tools/qpack/qpack_decoder_test_utils.h" + +#include <algorithm> +#include <cstddef> +#include <utility> + +#include "net/third_party/quiche/src/quic/platform/api/quic_test.h" + +namespace quic { +namespace test { + +void NoopEncoderStreamErrorDelegate::OnEncoderStreamError( + QuicStringPiece /*error_message*/) {} + +TestHeadersHandler::TestHeadersHandler() + : decoding_completed_(false), decoding_error_detected_(false) {} + +void TestHeadersHandler::OnHeaderDecoded(QuicStringPiece name, + QuicStringPiece value) { + ASSERT_FALSE(decoding_completed_); + ASSERT_FALSE(decoding_error_detected_); + + header_list_.AppendValueOrAddHeader(name, value); +} + +void TestHeadersHandler::OnDecodingCompleted() { + ASSERT_FALSE(decoding_completed_); + ASSERT_FALSE(decoding_error_detected_); + + decoding_completed_ = true; +} + +void TestHeadersHandler::OnDecodingErrorDetected( + QuicStringPiece error_message) { + ASSERT_FALSE(decoding_completed_); + ASSERT_FALSE(decoding_error_detected_); + + decoding_error_detected_ = true; + error_message_.assign(error_message.data(), error_message.size()); +} + +spdy::SpdyHeaderBlock TestHeadersHandler::ReleaseHeaderList() { + DCHECK(decoding_completed_); + DCHECK(!decoding_error_detected_); + + return std::move(header_list_); +} + +bool TestHeadersHandler::decoding_completed() const { + return decoding_completed_; +} + +bool TestHeadersHandler::decoding_error_detected() const { + return decoding_error_detected_; +} + +const std::string& TestHeadersHandler::error_message() const { + DCHECK(decoding_error_detected_); + return error_message_; +} + +void QpackDecode( + uint64_t maximum_dynamic_table_capacity, + uint64_t maximum_blocked_streams, + QpackDecoder::EncoderStreamErrorDelegate* encoder_stream_error_delegate, + QpackStreamSenderDelegate* decoder_stream_sender_delegate, + QpackProgressiveDecoder::HeadersHandlerInterface* handler, + const FragmentSizeGenerator& fragment_size_generator, + QuicStringPiece data) { + QpackDecoder decoder(maximum_dynamic_table_capacity, maximum_blocked_streams, + encoder_stream_error_delegate); + decoder.set_qpack_stream_sender_delegate(decoder_stream_sender_delegate); + auto progressive_decoder = + decoder.CreateProgressiveDecoder(/* stream_id = */ 1, handler); + while (!data.empty()) { + size_t fragment_size = std::min(fragment_size_generator(), data.size()); + progressive_decoder->Decode(data.substr(0, fragment_size)); + data = data.substr(fragment_size); + } + progressive_decoder->EndHeaderBlock(); +} + +} // namespace test +} // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.h b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.h new file mode 100644 index 00000000000..213aded1ba5 --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.h @@ -0,0 +1,103 @@ +// Copyright (c) 2018 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. + +#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_DECODER_TEST_UTILS_H_ +#define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_DECODER_TEST_UTILS_H_ + +#include <string> + +#include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder.h" +#include "net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.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/qpack/qpack_test_utils.h" +#include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" + +namespace quic { +namespace test { + +// QpackDecoder::EncoderStreamErrorDelegate implementation that does nothing. +class NoopEncoderStreamErrorDelegate + : public QpackDecoder::EncoderStreamErrorDelegate { + public: + ~NoopEncoderStreamErrorDelegate() override = default; + + void OnEncoderStreamError(QuicStringPiece error_message) override; +}; + +// Mock QpackDecoder::EncoderStreamErrorDelegate implementation. +class MockEncoderStreamErrorDelegate + : public QpackDecoder::EncoderStreamErrorDelegate { + public: + ~MockEncoderStreamErrorDelegate() override = default; + + MOCK_METHOD1(OnEncoderStreamError, void(QuicStringPiece error_message)); +}; + +// HeadersHandlerInterface implementation that collects decoded headers +// into a SpdyHeaderBlock. +class TestHeadersHandler + : public QpackProgressiveDecoder::HeadersHandlerInterface { + public: + TestHeadersHandler(); + ~TestHeadersHandler() override = default; + + // HeadersHandlerInterface implementation: + void OnHeaderDecoded(QuicStringPiece name, QuicStringPiece value) override; + void OnDecodingCompleted() override; + void OnDecodingErrorDetected(QuicStringPiece error_message) override; + + // Release decoded header list. Must only be called if decoding is complete + // and no errors have been detected. + spdy::SpdyHeaderBlock ReleaseHeaderList(); + + bool decoding_completed() const; + bool decoding_error_detected() const; + const std::string& error_message() const; + + private: + spdy::SpdyHeaderBlock header_list_; + bool decoding_completed_; + bool decoding_error_detected_; + std::string error_message_; +}; + +class MockHeadersHandler + : public QpackProgressiveDecoder::HeadersHandlerInterface { + public: + MockHeadersHandler() = default; + MockHeadersHandler(const MockHeadersHandler&) = delete; + MockHeadersHandler& operator=(const MockHeadersHandler&) = delete; + ~MockHeadersHandler() override = default; + + MOCK_METHOD2(OnHeaderDecoded, + void(QuicStringPiece name, QuicStringPiece value)); + MOCK_METHOD0(OnDecodingCompleted, void()); + MOCK_METHOD1(OnDecodingErrorDetected, void(QuicStringPiece error_message)); +}; + +class NoOpHeadersHandler + : public QpackProgressiveDecoder::HeadersHandlerInterface { + public: + ~NoOpHeadersHandler() override = default; + + void OnHeaderDecoded(QuicStringPiece /*name*/, + QuicStringPiece /*value*/) override {} + void OnDecodingCompleted() override {} + void OnDecodingErrorDetected(QuicStringPiece /*error_message*/) override {} +}; + +void QpackDecode( + uint64_t maximum_dynamic_table_capacity, + uint64_t maximum_blocked_streams, + QpackDecoder::EncoderStreamErrorDelegate* encoder_stream_error_delegate, + QpackStreamSenderDelegate* decoder_stream_sender_delegate, + QpackProgressiveDecoder::HeadersHandlerInterface* handler, + const FragmentSizeGenerator& fragment_size_generator, + QuicStringPiece data); + +} // namespace test +} // namespace quic + +#endif // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_DECODER_TEST_UTILS_H_ diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack_encoder_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_peer.cc index 9719bdb9b7a..709686a85e8 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack_encoder_peer.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_peer.cc @@ -2,7 +2,7 @@ // 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/test_tools/qpack_encoder_peer.h" +#include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_peer.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder.h" diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack_encoder_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_peer.h index 2edf4274611..a824276bc4c 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack_encoder_peer.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_peer.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_ENCODER_PEER_H_ -#define QUICHE_QUIC_TEST_TOOLS_QPACK_ENCODER_PEER_H_ +#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_ENCODER_PEER_H_ +#define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_ENCODER_PEER_H_ #include <cstdint> @@ -27,4 +27,4 @@ class QpackEncoderPeer { } // namespace quic -#endif // QUICHE_QUIC_TEST_TOOLS_QPACK_ENCODER_PEER_H_ +#endif // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_ENCODER_PEER_H_ diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.cc b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.cc new file mode 100644 index 00000000000..dbdd3690d55 --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.cc @@ -0,0 +1,16 @@ +// Copyright (c) 2018 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/test_tools/qpack/qpack_encoder_test_utils.h" + +#include "net/third_party/quiche/src/spdy/core/hpack/hpack_encoder.h" + +namespace quic { +namespace test { + +void NoopDecoderStreamErrorDelegate::OnDecoderStreamError( + QuicStringPiece /*error_message*/) {} + +} // namespace test +} // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.h b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.h new file mode 100644 index 00000000000..5fa229256b4 --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.h @@ -0,0 +1,40 @@ +// Copyright (c) 2018 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. + +#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_ENCODER_TEST_UTILS_H_ +#define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_ENCODER_TEST_UTILS_H_ + +#include <string> + +#include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder.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/qpack/qpack_test_utils.h" +#include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" + +namespace quic { +namespace test { + +// QpackEncoder::DecoderStreamErrorDelegate implementation that does nothing. +class NoopDecoderStreamErrorDelegate + : public QpackEncoder::DecoderStreamErrorDelegate { + public: + ~NoopDecoderStreamErrorDelegate() override = default; + + void OnDecoderStreamError(QuicStringPiece error_message) override; +}; + +// Mock QpackEncoder::DecoderStreamErrorDelegate implementation. +class MockDecoderStreamErrorDelegate + : public QpackEncoder::DecoderStreamErrorDelegate { + public: + ~MockDecoderStreamErrorDelegate() override = default; + + MOCK_METHOD1(OnDecoderStreamError, void(QuicStringPiece error_message)); +}; + +} // namespace test +} // namespace quic + +#endif // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_ENCODER_TEST_UTILS_H_ diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack_header_table_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_header_table_peer.cc index bb18731dae7..c554a97d1ce 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack_header_table_peer.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_header_table_peer.cc @@ -2,7 +2,7 @@ // 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/test_tools/qpack_header_table_peer.h" +#include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_header_table_peer.h" #include "net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h" diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack_header_table_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_header_table_peer.h index cbf3f448a28..19e8d0d64e3 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/qpack_header_table_peer.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_header_table_peer.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_HEADER_TABLE_PEER_H_ -#define QUICHE_QUIC_TEST_TOOLS_QPACK_HEADER_TABLE_PEER_H_ +#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_HEADER_TABLE_PEER_H_ +#define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_HEADER_TABLE_PEER_H_ #include <cstdint> @@ -26,4 +26,4 @@ class QpackHeaderTablePeer { } // namespace quic -#endif // QUICHE_QUIC_TEST_TOOLS_QPACK_HEADER_TABLE_PEER_H_ +#endif // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_HEADER_TABLE_PEER_H_ diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.cc b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.cc new file mode 100644 index 00000000000..a5a74aa4cb0 --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.cc @@ -0,0 +1,334 @@ +// Copyright (c) 2018 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. + +// Decoder to test QPACK Offline Interop corpus +// +// See https://github.com/quicwg/base-drafts/wiki/QPACK-Offline-Interop for +// description of test data format. +// +// Example usage +// +// cd $TEST_DATA +// git clone https://github.com/qpackers/qifs.git +// TEST_ENCODED_DATA=$TEST_DATA/qifs/encoded/qpack-06 +// TEST_QIF_DATA=$TEST_DATA/qifs/qifs +// $BIN/qpack_offline_decoder \ +// $TEST_ENCODED_DATA/f5/fb-req.qifencoded.4096.100.0 \ +// $TEST_QIF_DATA/fb-req.qif +// $TEST_ENCODED_DATA/h2o/fb-req-hq.out.512.0.1 \ +// $TEST_QIF_DATA/fb-req-hq.qif +// $TEST_ENCODED_DATA/ls-qpack/fb-resp-hq.out.0.0.0 \ +// $TEST_QIF_DATA/fb-resp-hq.qif +// $TEST_ENCODED_DATA/proxygen/netbsd.qif.proxygen.out.4096.0.0 \ +// $TEST_QIF_DATA/netbsd.qif +// + +#include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.h" + +#include <cstdint> +#include <string> +#include <utility> + +#include "net/third_party/quiche/src/quic/core/quic_types.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_file_utils.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h" +#include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" + +namespace quic { + +QpackOfflineDecoder::QpackOfflineDecoder() + : encoder_stream_error_detected_(false) {} + +bool QpackOfflineDecoder::DecodeAndVerifyOfflineData( + QuicStringPiece input_filename, + QuicStringPiece expected_headers_filename) { + if (!ParseInputFilename(input_filename)) { + QUIC_LOG(ERROR) << "Error parsing input filename " << input_filename; + return false; + } + + if (!DecodeHeaderBlocksFromFile(input_filename)) { + QUIC_LOG(ERROR) << "Error decoding header blocks in " << input_filename; + return false; + } + + if (!VerifyDecodedHeaderLists(expected_headers_filename)) { + QUIC_LOG(ERROR) << "Header lists decoded from " << input_filename + << " to not match expected headers parsed from " + << expected_headers_filename; + return false; + } + + return true; +} + +void QpackOfflineDecoder::OnEncoderStreamError(QuicStringPiece error_message) { + QUIC_LOG(ERROR) << "Encoder stream error: " << error_message; + encoder_stream_error_detected_ = true; +} + +bool QpackOfflineDecoder::ParseInputFilename(QuicStringPiece input_filename) { + auto pieces = QuicTextUtils::Split(input_filename, '.'); + + if (pieces.size() < 3) { + QUIC_LOG(ERROR) << "Not enough fields in input filename " << input_filename; + return false; + } + + auto piece_it = pieces.rbegin(); + + // Acknowledgement mode: 1 for immediate, 0 for none. + bool immediate_acknowledgement = false; + if (*piece_it == "0") { + immediate_acknowledgement = false; + } else if (*piece_it == "1") { + immediate_acknowledgement = true; + } else { + QUIC_LOG(ERROR) + << "Header acknowledgement field must be 0 or 1 in input filename " + << input_filename; + return false; + } + + ++piece_it; + + // Maximum allowed number of blocked streams. + uint64_t max_blocked_streams = 0; + if (!QuicTextUtils::StringToUint64(*piece_it, &max_blocked_streams)) { + QUIC_LOG(ERROR) << "Error parsing part of input filename \"" << *piece_it + << "\" as an integer."; + return false; + } + + ++piece_it; + + // Maximum Dynamic Table Capacity in bytes + uint64_t maximum_dynamic_table_capacity = 0; + if (!QuicTextUtils::StringToUint64(*piece_it, + &maximum_dynamic_table_capacity)) { + QUIC_LOG(ERROR) << "Error parsing part of input filename \"" << *piece_it + << "\" as an integer."; + return false; + } + qpack_decoder_ = std::make_unique<QpackDecoder>( + maximum_dynamic_table_capacity, max_blocked_streams, this); + qpack_decoder_->set_qpack_stream_sender_delegate( + &decoder_stream_sender_delegate_); + + // The initial dynamic table capacity is zero according to + // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#eviction. + // However, for historical reasons, offline interop encoders use + // |maximum_dynamic_table_capacity| as initial capacity. + qpack_decoder_->OnSetDynamicTableCapacity(maximum_dynamic_table_capacity); + + return true; +} + +bool QpackOfflineDecoder::DecodeHeaderBlocksFromFile( + QuicStringPiece input_filename) { + // Store data in |input_data_storage|; use a QuicStringPiece to efficiently + // keep track of remaining portion yet to be decoded. + std::string input_data_storage; + ReadFileContents(input_filename, &input_data_storage); + QuicStringPiece input_data(input_data_storage); + + while (!input_data.empty()) { + // Parse stream_id and length. + if (input_data.size() < sizeof(uint64_t) + sizeof(uint32_t)) { + QUIC_LOG(ERROR) << "Unexpected end of input file."; + return false; + } + + uint64_t stream_id = quiche::QuicheEndian::NetToHost64( + *reinterpret_cast<const uint64_t*>(input_data.data())); + input_data = input_data.substr(sizeof(uint64_t)); + + uint32_t length = quiche::QuicheEndian::NetToHost32( + *reinterpret_cast<const uint32_t*>(input_data.data())); + input_data = input_data.substr(sizeof(uint32_t)); + + if (input_data.size() < length) { + QUIC_LOG(ERROR) << "Unexpected end of input file."; + return false; + } + + // Parse data. + QuicStringPiece data = input_data.substr(0, length); + input_data = input_data.substr(length); + + // Process data. + if (stream_id == 0) { + qpack_decoder_->encoder_stream_receiver()->Decode(data); + + if (encoder_stream_error_detected_) { + QUIC_LOG(ERROR) << "Error detected on encoder stream."; + return false; + } + } else { + auto headers_handler = std::make_unique<test::TestHeadersHandler>(); + auto progressive_decoder = qpack_decoder_->CreateProgressiveDecoder( + stream_id, headers_handler.get()); + + progressive_decoder->Decode(data); + progressive_decoder->EndHeaderBlock(); + + if (headers_handler->decoding_error_detected()) { + QUIC_LOG(ERROR) << "Sync decoding error on stream " << stream_id << ": " + << headers_handler->error_message(); + return false; + } + + decoders_.push_back({std::move(headers_handler), + std::move(progressive_decoder), stream_id}); + } + + // Move decoded header lists from TestHeadersHandlers and append them to + // |decoded_header_lists_| while preserving the order in |decoders_|. + while (!decoders_.empty() && + decoders_.front().headers_handler->decoding_completed()) { + Decoder* decoder = &decoders_.front(); + + if (decoder->headers_handler->decoding_error_detected()) { + QUIC_LOG(ERROR) << "Async decoding error on stream " + << decoder->stream_id << ": " + << decoder->headers_handler->error_message(); + return false; + } + + if (!decoder->headers_handler->decoding_completed()) { + QUIC_LOG(ERROR) << "Decoding incomplete after reading entire" + " file, on stream " + << decoder->stream_id; + return false; + } + + decoded_header_lists_.push_back( + decoder->headers_handler->ReleaseHeaderList()); + decoders_.pop_front(); + } + } + + if (!decoders_.empty()) { + DCHECK(!decoders_.front().headers_handler->decoding_completed()); + + QUIC_LOG(ERROR) << "Blocked decoding uncomplete after reading entire" + " file, on stream " + << decoders_.front().stream_id; + return false; + } + + return true; +} + +bool QpackOfflineDecoder::VerifyDecodedHeaderLists( + QuicStringPiece expected_headers_filename) { + // Store data in |expected_headers_data_storage|; use a QuicStringPiece to + // efficiently keep track of remaining portion yet to be decoded. + std::string expected_headers_data_storage; + ReadFileContents(expected_headers_filename, &expected_headers_data_storage); + QuicStringPiece expected_headers_data(expected_headers_data_storage); + + while (!decoded_header_lists_.empty()) { + spdy::SpdyHeaderBlock decoded_header_list = + std::move(decoded_header_lists_.front()); + decoded_header_lists_.pop_front(); + + spdy::SpdyHeaderBlock expected_header_list; + if (!ReadNextExpectedHeaderList(&expected_headers_data, + &expected_header_list)) { + QUIC_LOG(ERROR) + << "Error parsing expected header list to match next decoded " + "header list."; + return false; + } + + if (!CompareHeaderBlocks(std::move(decoded_header_list), + std::move(expected_header_list))) { + QUIC_LOG(ERROR) << "Decoded header does not match expected header."; + return false; + } + } + + if (!expected_headers_data.empty()) { + QUIC_LOG(ERROR) + << "Not enough encoded header lists to match expected ones."; + return false; + } + + return true; +} + +bool QpackOfflineDecoder::ReadNextExpectedHeaderList( + QuicStringPiece* expected_headers_data, + spdy::SpdyHeaderBlock* expected_header_list) { + while (true) { + QuicStringPiece::size_type endline = expected_headers_data->find('\n'); + + // Even last header list must be followed by an empty line. + if (endline == QuicStringPiece::npos) { + QUIC_LOG(ERROR) << "Unexpected end of expected header list file."; + return false; + } + + if (endline == 0) { + // Empty line indicates end of header list. + *expected_headers_data = expected_headers_data->substr(1); + return true; + } + + QuicStringPiece header_field = expected_headers_data->substr(0, endline); + auto pieces = QuicTextUtils::Split(header_field, '\t'); + + if (pieces.size() != 2) { + QUIC_LOG(ERROR) << "Header key and value must be separated by TAB."; + return false; + } + + expected_header_list->AppendValueOrAddHeader(pieces[0], pieces[1]); + + *expected_headers_data = expected_headers_data->substr(endline + 1); + } +} + +bool QpackOfflineDecoder::CompareHeaderBlocks( + spdy::SpdyHeaderBlock decoded_header_list, + spdy::SpdyHeaderBlock expected_header_list) { + if (decoded_header_list == expected_header_list) { + return true; + } + + // The h2o decoder reshuffles the "content-length" header and pseudo-headers, + // see + // https://github.com/qpackers/qifs/blob/master/encoded/qpack-03/h2o/README.md. + // Remove such headers one by one if they match. + const char* kContentLength = "content-length"; + const char* kPseudoHeaderPrefix = ":"; + for (spdy::SpdyHeaderBlock::iterator decoded_it = decoded_header_list.begin(); + decoded_it != decoded_header_list.end();) { + const QuicStringPiece key = decoded_it->first; + if (key != kContentLength && + !QuicTextUtils::StartsWith(key, kPseudoHeaderPrefix)) { + ++decoded_it; + continue; + } + spdy::SpdyHeaderBlock::iterator expected_it = + expected_header_list.find(key); + if (expected_it == expected_header_list.end() || + decoded_it->second != expected_it->second) { + ++decoded_it; + continue; + } + // SpdyHeaderBlock does not support erasing by iterator, only by key. + ++decoded_it; + expected_header_list.erase(key); + // This will invalidate |key|. + decoded_header_list.erase(key); + } + + return decoded_header_list == expected_header_list; +} + +} // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.h b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.h new file mode 100644 index 00000000000..cb7dedd3aaf --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_offline_decoder.h @@ -0,0 +1,86 @@ +// Copyright (c) 2018 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. + +#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_OFFLINE_DECODER_H_ +#define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_OFFLINE_DECODER_H_ + +#include <list> + +#include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h" +#include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_decoder_test_utils.h" +#include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h" +#include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" + +namespace quic { + +// A decoder to read encoded data from a file, decode it, and compare to +// a list of expected header lists read from another file. File format is +// described at +// https://github.com/quicwg/base-drafts/wiki/QPACK-Offline-Interop. +class QpackOfflineDecoder : public QpackDecoder::EncoderStreamErrorDelegate { + public: + QpackOfflineDecoder(); + ~QpackOfflineDecoder() override = default; + + // Read encoded header blocks and encoder stream data from |input_filename| + // and decode them, read expected header lists from + // |expected_headers_filename|, and compare decoded header lists to expected + // ones. Returns true if there is an equal number of them and the + // corresponding ones match, false otherwise. + bool DecodeAndVerifyOfflineData(QuicStringPiece input_filename, + QuicStringPiece expected_headers_filename); + + // QpackDecoder::EncoderStreamErrorDelegate implementation: + void OnEncoderStreamError(QuicStringPiece error_message) override; + + private: + // Data structure to hold TestHeadersHandler and QpackProgressiveDecoder until + // decoding of a header header block (and all preceding header blocks) is + // complete. + struct Decoder { + std::unique_ptr<test::TestHeadersHandler> headers_handler; + std::unique_ptr<QpackProgressiveDecoder> progressive_decoder; + uint64_t stream_id; + }; + + // Parse decoder parameters from |input_filename| and set up |qpack_decoder_| + // accordingly. + bool ParseInputFilename(QuicStringPiece input_filename); + + // Read encoded header blocks and encoder stream data from |input_filename|, + // pass them to |qpack_decoder_| for decoding, and add decoded header lists to + // |decoded_header_lists_|. + bool DecodeHeaderBlocksFromFile(QuicStringPiece input_filename); + + // Read expected header lists from |expected_headers_filename| and verify + // decoded header lists in |decoded_header_lists_| against them. + bool VerifyDecodedHeaderLists(QuicStringPiece expected_headers_filename); + + // Parse next header list from |*expected_headers_data| into + // |*expected_header_list|, removing consumed data from the beginning of + // |*expected_headers_data|. Returns true on success, false if parsing fails. + bool ReadNextExpectedHeaderList(QuicStringPiece* expected_headers_data, + spdy::SpdyHeaderBlock* expected_header_list); + + // Compare two header lists. Allow for different orders of certain headers as + // described at + // https://github.com/qpackers/qifs/blob/master/encoded/qpack-03/h2o/README.md. + bool CompareHeaderBlocks(spdy::SpdyHeaderBlock decoded_header_list, + spdy::SpdyHeaderBlock expected_header_list); + + bool encoder_stream_error_detected_; + test::NoopQpackStreamSenderDelegate decoder_stream_sender_delegate_; + std::unique_ptr<QpackDecoder> qpack_decoder_; + + // Objects necessary for decoding, one list element for each header block. + std::list<Decoder> decoders_; + + // Decoded header lists. + std::list<spdy::SpdyHeaderBlock> decoded_header_lists_; +}; + +} // namespace quic + +#endif // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_OFFLINE_DECODER_H_ diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.cc b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.cc new file mode 100644 index 00000000000..faaddcb2187 --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.cc @@ -0,0 +1,23 @@ +// Copyright (c) 2018 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/test_tools/qpack/qpack_test_utils.h" + +#include <limits> + +namespace quic { +namespace test { + +FragmentSizeGenerator FragmentModeToFragmentSizeGenerator( + FragmentMode fragment_mode) { + switch (fragment_mode) { + case FragmentMode::kSingleChunk: + return []() { return std::numeric_limits<size_t>::max(); }; + case FragmentMode::kOctetByOctet: + return []() { return 1; }; + } +} + +} // namespace test +} // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h new file mode 100644 index 00000000000..08cab4e0b2c --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h @@ -0,0 +1,47 @@ +// Copyright (c) 2018 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. + +#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_TEST_UTILS_H_ +#define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_TEST_UTILS_H_ + +#include <cstddef> +#include <functional> + +#include "net/third_party/quiche/src/quic/core/qpack/qpack_stream_sender_delegate.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_test.h" + +namespace quic { +namespace test { + +// Called repeatedly to determine the size of each fragment when encoding or +// decoding. Must return a positive value. +using FragmentSizeGenerator = std::function<size_t()>; + +enum class FragmentMode { + kSingleChunk, + kOctetByOctet, +}; + +FragmentSizeGenerator FragmentModeToFragmentSizeGenerator( + FragmentMode fragment_mode); + +// Mock QpackUnidirectionalStreamSenderDelegate implementation. +class MockQpackStreamSenderDelegate : public QpackStreamSenderDelegate { + public: + ~MockQpackStreamSenderDelegate() override = default; + + MOCK_METHOD1(WriteStreamData, void(QuicStringPiece data)); +}; + +class NoopQpackStreamSenderDelegate : public QpackStreamSenderDelegate { + public: + ~NoopQpackStreamSenderDelegate() override = default; + + void WriteStreamData(QuicStringPiece /*data*/) override {} +}; + +} // namespace test +} // namespace quic + +#endif // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_TEST_UTILS_H_ diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.cc index 02775caf901..7b9264c31b8 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.cc @@ -9,7 +9,6 @@ #include "net/third_party/quiche/src/quic/core/quic_received_packet_manager.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.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_generator_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h" namespace quic { @@ -37,22 +36,9 @@ void QuicConnectionPeer::PopulateStopWaitingFrame( } // static -QuicConnectionVisitorInterface* QuicConnectionPeer::GetVisitor( - QuicConnection* connection) { - return connection->visitor_; -} - -// static QuicPacketCreator* QuicConnectionPeer::GetPacketCreator( QuicConnection* connection) { - return QuicPacketGeneratorPeer::GetPacketCreator( - &connection->packet_generator_); -} - -// static -QuicPacketGenerator* QuicConnectionPeer::GetPacketGenerator( - QuicConnection* connection) { - return &connection->packet_generator_; + return &connection->packet_creator_; } // static @@ -226,22 +212,7 @@ QuicConnectionStats* QuicConnectionPeer::GetStats(QuicConnection* connection) { // static QuicPacketCount QuicConnectionPeer::GetPacketsBetweenMtuProbes( QuicConnection* connection) { - if (connection->mtu_discovery_v2_) { - return connection->mtu_discoverer_.packets_between_probes(); - } - return connection->packets_between_mtu_probes_; -} - -// static -void QuicConnectionPeer::SetPacketsBetweenMtuProbes(QuicConnection* connection, - QuicPacketCount packets) { - connection->packets_between_mtu_probes_ = packets; -} - -// static -void QuicConnectionPeer::SetNextMtuProbeAt(QuicConnection* connection, - QuicPacketNumber number) { - connection->next_mtu_probe_at_ = number; + return connection->mtu_discoverer_.packets_between_probes(); } // static @@ -308,15 +279,13 @@ void QuicConnectionPeer::SetMaxTrackedPackets( } // static -void QuicConnectionPeer::SetSessionDecidesWhatToWrite( - QuicConnection* connection) { - connection->sent_packet_manager_.SetSessionDecideWhatToWrite(true); - connection->packet_generator_.SetCanSetTransmissionType(true); -} - -// static void QuicConnectionPeer::SetNegotiatedVersion(QuicConnection* connection) { connection->version_negotiated_ = true; + if (connection->perspective() == Perspective::IS_SERVER && + !QuicFramerPeer::infer_packet_header_type_from_version( + &connection->framer_)) { + connection->framer_.InferPacketHeaderTypeFromVersion(); + } } // static @@ -364,5 +333,18 @@ void QuicConnectionPeer::SendConnectionClosePacket(QuicConnection* connection, connection->SendConnectionClosePacket(error, details); } +// static +size_t QuicConnectionPeer::GetNumEncryptionLevels(QuicConnection* connection) { + size_t count = 0; + for (EncryptionLevel level : + {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE, ENCRYPTION_ZERO_RTT, + ENCRYPTION_FORWARD_SECURE}) { + if (connection->framer_.HasEncrypterOfEncryptionLevel(level)) { + ++count; + } + } + return count; +} + } // namespace test } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h index c5c972f9cc0..b7140ded5ed 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h @@ -20,7 +20,6 @@ class QuicConnectionVisitorInterface; class QuicEncryptedPacket; class QuicFramer; class QuicPacketCreator; -class QuicPacketGenerator; class QuicPacketWriter; class QuicSentPacketManager; class SendAlgorithmInterface; @@ -41,12 +40,8 @@ class QuicConnectionPeer { static void PopulateStopWaitingFrame(QuicConnection* connection, QuicStopWaitingFrame* stop_waiting); - static QuicConnectionVisitorInterface* GetVisitor(QuicConnection* connection); - static QuicPacketCreator* GetPacketCreator(QuicConnection* connection); - static QuicPacketGenerator* GetPacketGenerator(QuicConnection* connection); - static QuicSentPacketManager* GetSentPacketManager( QuicConnection* connection); @@ -107,10 +102,6 @@ class QuicConnectionPeer { static QuicPacketCount GetPacketsBetweenMtuProbes(QuicConnection* connection); - static void SetPacketsBetweenMtuProbes(QuicConnection* connection, - QuicPacketCount packets); - static void SetNextMtuProbeAt(QuicConnection* connection, - QuicPacketNumber number); static void ReInitializeMtuDiscoverer( QuicConnection* connection, QuicPacketCount packets_between_probes_base, @@ -127,7 +118,6 @@ class QuicConnectionPeer { bool no_stop_waiting_frames); static void SetMaxTrackedPackets(QuicConnection* connection, QuicPacketCount max_tracked_packets); - static void SetSessionDecidesWhatToWrite(QuicConnection* connection); static void SetNegotiatedVersion(QuicConnection* connection); static void SetMaxConsecutiveNumPacketsWithNoRetransmittableFrames( QuicConnection* connection, @@ -143,6 +133,8 @@ class QuicConnectionPeer { static void SendConnectionClosePacket(QuicConnection* connection, QuicErrorCode error, const std::string& details); + + static size_t GetNumEncryptionLevels(QuicConnection* connection); }; } // namespace test diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.cc index 2590834891c..b460165d906 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.cc @@ -11,6 +11,12 @@ namespace quic { namespace test { // static +QuicTimeWaitListManager* QuicDispatcherPeer::GetTimeWaitListManager( + QuicDispatcher* dispatcher) { + return dispatcher->time_wait_list_manager_.get(); +} + +// static void QuicDispatcherPeer::SetTimeWaitListManager( QuicDispatcher* dispatcher, QuicTimeWaitListManager* time_wait_list_manager) { @@ -77,8 +83,7 @@ const QuicDispatcher::SessionMap& QuicDispatcherPeer::session_map( void QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop( QuicDispatcher* dispatcher, size_t num_session_allowed) { - return dispatcher->set_new_sessions_allowed_per_event_loop( - num_session_allowed); + dispatcher->new_sessions_allowed_per_event_loop_ = num_session_allowed; } // static diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.h index a888b4e0967..7cb4c92c5a9 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.h @@ -17,6 +17,9 @@ class QuicDispatcherPeer { public: QuicDispatcherPeer() = delete; + static QuicTimeWaitListManager* GetTimeWaitListManager( + QuicDispatcher* dispatcher); + static void SetTimeWaitListManager( QuicDispatcher* dispatcher, QuicTimeWaitListManager* time_wait_list_manager); diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h index 661def5493a..d462555a104 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h @@ -187,6 +187,10 @@ class QuicFramerPeer { uint64_t current_received_frame_type) { framer->current_received_frame_type_ = current_received_frame_type; } + + static bool infer_packet_header_type_from_version(QuicFramer* framer) { + return framer->infer_packet_header_type_from_version_; + } }; } // namespace test diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.cc index d4e5598ffa0..7c8db91da7f 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.cc @@ -4,6 +4,7 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.h" +#include "net/third_party/quiche/src/quic/core/frames/quic_frame.h" #include "net/third_party/quiche/src/quic/core/quic_packet_creator.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" @@ -63,6 +64,11 @@ void QuicPacketCreatorPeer::SetPacketNumber(QuicPacketCreator* creator, creator->packet_.packet_number = QuicPacketNumber(s); } +void QuicPacketCreatorPeer::SetPacketNumber(QuicPacketCreator* creator, + QuicPacketNumber num) { + creator->packet_.packet_number = num; +} + // static void QuicPacketCreatorPeer::ClearPacketNumber(QuicPacketCreator* creator) { creator->packet_.packet_number.Clear(); @@ -102,14 +108,13 @@ SerializedPacket QuicPacketCreatorPeer::SerializeAllFrames( DCHECK(creator->queued_frames_.empty()); DCHECK(!frames.empty()); for (const QuicFrame& frame : frames) { - bool success = creator->AddFrame(frame, false, NOT_RETRANSMISSION); + bool success = creator->AddFrame(frame, NOT_RETRANSMISSION); DCHECK(success); } creator->SerializePacket(buffer, buffer_len); - SerializedPacket packet = creator->packet_; + SerializedPacket packet = std::move(creator->packet_); // The caller takes ownership of the QuicEncryptedPacket. creator->packet_.encrypted_buffer = nullptr; - DCHECK(packet.retransmittable_frames.empty()); return packet; } diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.h index e040090f6dd..88587a212b5 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.h @@ -31,6 +31,7 @@ class QuicPacketCreatorPeer { static QuicVariableLengthIntegerLength GetLengthLength( QuicPacketCreator* creator); static void SetPacketNumber(QuicPacketCreator* creator, uint64_t s); + static void SetPacketNumber(QuicPacketCreator* creator, QuicPacketNumber num); static void ClearPacketNumber(QuicPacketCreator* creator); static void FillPacketHeader(QuicPacketCreator* creator, QuicPacketHeader* header); diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_generator_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_generator_peer.cc deleted file mode 100644 index 91a875282c2..00000000000 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_generator_peer.cc +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2014 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/test_tools/quic_packet_generator_peer.h" - -#include "net/third_party/quiche/src/quic/core/quic_packet_creator.h" -#include "net/third_party/quiche/src/quic/core/quic_packet_generator.h" - -namespace quic { -namespace test { - -// static -QuicPacketCreator* QuicPacketGeneratorPeer::GetPacketCreator( - QuicPacketGenerator* generator) { - return &generator->packet_creator_; -} - -} // namespace test -} // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_generator_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_generator_peer.h deleted file mode 100644 index 6941b089d23..00000000000 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_generator_peer.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2014 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. - -#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_PACKET_GENERATOR_PEER_H_ -#define QUICHE_QUIC_TEST_TOOLS_QUIC_PACKET_GENERATOR_PEER_H_ - -#include "net/third_party/quiche/src/quic/core/quic_packets.h" - -namespace quic { - -class QuicPacketCreator; -class QuicPacketGenerator; - -namespace test { - -class QuicPacketGeneratorPeer { - public: - QuicPacketGeneratorPeer() = delete; - - static QuicPacketCreator* GetPacketCreator(QuicPacketGenerator* generator); -}; - -} // namespace test - -} // namespace quic - -#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_PACKET_GENERATOR_PEER_H_ diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.cc index b680f66d815..cd8297a961e 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.cc @@ -86,18 +86,9 @@ bool QuicSentPacketManagerPeer::IsRetransmission( if (!HasRetransmittableFrames(sent_packet_manager, packet_number)) { return false; } - if (sent_packet_manager->session_decides_what_to_write()) { - return sent_packet_manager->unacked_packets_ - .GetTransmissionInfo(QuicPacketNumber(packet_number)) - .transmission_type != NOT_RETRANSMISSION; - } - for (auto transmission_info : sent_packet_manager->unacked_packets_) { - if (transmission_info.retransmission.IsInitialized() && - transmission_info.retransmission == QuicPacketNumber(packet_number)) { - return true; - } - } - return false; + return sent_packet_manager->unacked_packets_ + .GetTransmissionInfo(QuicPacketNumber(packet_number)) + .transmission_type != NOT_RETRANSMISSION; } // static @@ -223,5 +214,12 @@ bool QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled( .use_adaptive_reordering_threshold(); } +// static +bool QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled( + QuicSentPacketManager* sent_packet_manager) { + return sent_packet_manager->uber_loss_algorithm_.general_loss_algorithms_[0] + .use_adaptive_time_threshold(); +} + } // namespace test } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h index 6be8b46308f..3927189ee3f 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h @@ -98,6 +98,9 @@ class QuicSentPacketManagerPeer { static bool AdaptiveReorderingThresholdEnabled( QuicSentPacketManager* sent_packet_manager); + + static bool AdaptiveTimeThresholdEnabled( + QuicSentPacketManager* sent_packet_manager); }; } // namespace test diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.cc index 001f1ca2b87..f9e785d2c98 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.cc @@ -226,15 +226,6 @@ QuicStreamIdManager* QuicSessionPeer::v99_unidirectional_stream_id_manager( } // static -void QuicSessionPeer::SendRstStreamInner(QuicSession* session, - QuicStreamId id, - QuicRstStreamErrorCode error, - QuicStreamOffset bytes_written, - bool close_write_side_only) { - session->SendRstStreamInner(id, error, bytes_written, close_write_side_only); -} - -// static PendingStream* QuicSessionPeer::GetPendingStream(QuicSession* session, QuicStreamId stream_id) { auto it = session->pending_stream_map_.find(stream_id); diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.h index eed3bddcf88..446cd67b176 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.h @@ -79,11 +79,6 @@ class QuicSessionPeer { QuicSession* session); static QuicStreamIdManager* v99_unidirectional_stream_id_manager( QuicSession* session); - static void SendRstStreamInner(QuicSession* session, - QuicStreamId id, - QuicRstStreamErrorCode error, - QuicStreamOffset bytes_written, - bool close_write_side_only); static PendingStream* GetPendingStream(QuicSession* session, QuicStreamId stream_id); static void set_is_configured(QuicSession* session, bool value); diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_peer.cc index d501debb7e3..42961984527 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_peer.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_peer.cc @@ -29,7 +29,7 @@ void QuicStreamPeer::SetStreamBytesWritten( // static bool QuicStreamPeer::read_side_closed(QuicStream* stream) { - return stream->read_side_closed(); + return stream->read_side_closed_; } // static diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.h index f61cb0049a5..3adb173b91d 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.h @@ -20,6 +20,10 @@ class QuicStreamSendBufferPeer { QuicStreamSendBuffer* send_buffer); static QuicByteCount TotalLength(QuicStreamSendBuffer* send_buffer); + + static int32_t write_index(QuicStreamSendBuffer* send_buffer) { + return send_buffer->write_index_; + } }; } // namespace test diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.cc index 36d2b04ee60..b3bf224df4e 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_buffer_peer.cc @@ -7,6 +7,7 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" +#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" typedef quic::QuicStreamSequencerBuffer::BufferBlock BufferBlock; @@ -28,8 +29,8 @@ size_t QuicStreamSequencerBufferPeer::Read(char* dest_buffer, size_t size) { dest.iov_base = dest_buffer, dest.iov_len = size; size_t bytes_read; std::string error_details; - EXPECT_EQ(QUIC_NO_ERROR, - buffer_->Readv(&dest, 1, &bytes_read, &error_details)); + EXPECT_THAT(buffer_->Readv(&dest, 1, &bytes_read, &error_details), + IsQuicNoError()); return bytes_read; } diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.cc index 237d9f66d8f..ca5e95ab0f6 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.cc @@ -382,7 +382,9 @@ ssize_t QuicTestClient::SendRequestAndRstTogether(const std::string& uri) { QuicStreamId stream_id = GetNthClientInitiatedBidirectionalStreamId( session->transport_version(), 0); - session->SendRstStream(stream_id, QUIC_STREAM_CANCELLED, 0); + QuicStream* stream = session->GetOrCreateStream(stream_id); + session->SendRstStream(stream_id, QUIC_STREAM_CANCELLED, + stream->stream_bytes_written()); return ret; } diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_server.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_server.cc index a893830102e..81b54d47260 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_server.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_server.cc @@ -230,12 +230,20 @@ ImmediateGoAwaySession::ImmediateGoAwaySession( quic_simple_server_backend) {} void ImmediateGoAwaySession::OnStreamFrame(const QuicStreamFrame& frame) { - SendGoAway(QUIC_PEER_GOING_AWAY, ""); + if (VersionUsesHttp3(transport_version())) { + SendHttp3GoAway(); + } else { + SendGoAway(QUIC_PEER_GOING_AWAY, ""); + } QuicSimpleServerSession::OnStreamFrame(frame); } void ImmediateGoAwaySession::OnCryptoFrame(const QuicCryptoFrame& frame) { - SendGoAway(QUIC_PEER_GOING_AWAY, ""); + // In IETF QUIC, GOAWAY lives up in HTTP/3 layer. Even if it's a immediate + // goaway session, goaway shouldn't be sent when crypto frame is received. + if (!VersionUsesHttp3(transport_version())) { + SendGoAway(QUIC_PEER_GOING_AWAY, ""); + } QuicSimpleServerSession::OnCryptoFrame(frame); } diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.cc index ff0239213a2..4b10826660b 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.cc @@ -22,12 +22,12 @@ #include "net/third_party/quiche/src/quic/core/quic_packet_creator.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_endian.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" #include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h" using testing::_; @@ -44,14 +44,14 @@ QuicConnectionId TestConnectionId() { QuicConnectionId TestConnectionId(uint64_t connection_number) { const uint64_t connection_id64_net = - QuicEndian::HostToNet64(connection_number); + quiche::QuicheEndian::HostToNet64(connection_number); return QuicConnectionId(reinterpret_cast<const char*>(&connection_id64_net), sizeof(connection_id64_net)); } QuicConnectionId TestConnectionIdNineBytesLong(uint64_t connection_number) { const uint64_t connection_number_net = - QuicEndian::HostToNet64(connection_number); + quiche::QuicheEndian::HostToNet64(connection_number); char connection_id_bytes[9] = {}; static_assert( sizeof(connection_id_bytes) == 1 + sizeof(connection_number_net), @@ -67,7 +67,7 @@ uint64_t TestConnectionIdToUInt64(QuicConnectionId connection_id) { memcpy(&connection_id64_net, connection_id.data(), std::min<size_t>(static_cast<size_t>(connection_id.length()), sizeof(connection_id64_net))); - return QuicEndian::NetToHost64(connection_id64_net); + return quiche::QuicheEndian::NetToHost64(connection_id64_net); } QuicAckFrame InitAckFrame(const std::vector<QuicAckBlock>& ack_blocks) { @@ -531,7 +531,7 @@ void PacketSavingConnection::SendOrQueuePacket(SerializedPacket* packet) { // Transfer ownership of the packet to the SentPacketManager and the // ack notifier to the AckNotifierManager. QuicConnectionPeer::GetSentPacketManager(this)->OnPacketSent( - packet, QuicPacketNumber(), clock_.ApproximateNow(), NOT_RETRANSMISSION, + packet, clock_.ApproximateNow(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); } @@ -576,7 +576,7 @@ QuicConsumedData MockQuicSession::ConsumeData(QuicStream* stream, StreamSendingState state) { if (write_length > 0) { auto buf = std::make_unique<char[]>(write_length); - QuicDataWriter writer(write_length, buf.get(), HOST_BYTE_ORDER); + QuicDataWriter writer(write_length, buf.get(), quiche::HOST_BYTE_ORDER); stream->WriteStreamData(offset, write_length, &writer); } else { DCHECK(state != NO_FIN); @@ -652,7 +652,6 @@ TestQuicSpdyServerSession::TestQuicSpdyServerSession( &helper_, crypto_config, compressed_certs_cache) { - Initialize(); ON_CALL(helper_, CanAcceptClientHello(_, _, _, _, _)) .WillByDefault(testing::Return(true)); } @@ -992,7 +991,7 @@ QuicEncryptedPacket* ConstructMisFramedEncryptedPacket( QuicConnectionIdIncluded destination_connection_id_included, QuicConnectionIdIncluded source_connection_id_included, QuicPacketNumberLength packet_number_length, - ParsedQuicVersionVector* versions, + ParsedQuicVersion version, Perspective perspective) { QuicPacketHeader header; header.destination_connection_id = destination_connection_id; @@ -1004,7 +1003,7 @@ QuicEncryptedPacket* ConstructMisFramedEncryptedPacket( header.reset_flag = reset_flag; header.packet_number_length = packet_number_length; header.packet_number = QuicPacketNumber(packet_number); - if (QuicVersionHasLongHeaderLengths((*versions)[0].transport_version) && + if (QuicVersionHasLongHeaderLengths(version.transport_version) && version_flag) { header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1; header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2; @@ -1012,10 +1011,7 @@ QuicEncryptedPacket* ConstructMisFramedEncryptedPacket( QuicFrame frame(QuicStreamFrame(1, false, 0, QuicStringPiece(data))); QuicFrames frames; frames.push_back(frame); - ParsedQuicVersion version = - (versions != nullptr ? *versions : AllSupportedVersions())[0]; - QuicFramer framer(versions != nullptr ? *versions : AllSupportedVersions(), - QuicTime::Zero(), perspective, + QuicFramer framer({version}, QuicTime::Zero(), perspective, kQuicDefaultConnectionIdLength); framer.SetInitialObfuscators(destination_connection_id); EncryptionLevel level = @@ -1184,6 +1180,7 @@ void CreateServerSessionForTest( *server_session = new TestQuicSpdyServerSession( *server_connection, DefaultQuicConfig(), supported_versions, server_crypto_config, compressed_certs_cache); + (*server_session)->Initialize(); // We advance the clock initially because the default time is zero and the // strike register worries that we've just overflowed a uint32_t time. diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.h index be6e84d7746..7919ef30299 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.h @@ -23,6 +23,7 @@ #include "net/third_party/quiche/src/quic/core/quic_sent_packet_manager.h" #include "net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h" #include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.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/mock_clock.h" @@ -161,7 +162,7 @@ QuicEncryptedPacket* ConstructMisFramedEncryptedPacket( QuicConnectionIdIncluded destination_connection_id_included, QuicConnectionIdIncluded source_connection_id_included, QuicPacketNumberLength packet_number_length, - ParsedQuicVersionVector* versions, + ParsedQuicVersion version, Perspective perspective); void CompareCharArraysWithHexError(const std::string& description, @@ -412,7 +413,8 @@ class MockQuicConnectionVisitor : public QuicConnectionVisitorInterface { MOCK_METHOD1(OnMaxStreamsFrame, bool(const QuicMaxStreamsFrame& frame)); MOCK_METHOD1(OnStreamsBlockedFrame, bool(const QuicStreamsBlockedFrame& frame)); - MOCK_METHOD1(OnStopSendingFrame, bool(const QuicStopSendingFrame& frame)); + MOCK_METHOD1(OnStopSendingFrame, void(const QuicStopSendingFrame& frame)); + MOCK_METHOD1(OnPacketDecrypted, void(EncryptionLevel)); }; class MockQuicConnectionHelper : public QuicConnectionHelperInterface { @@ -533,7 +535,8 @@ class MockQuicConnection : public QuicConnection { MOCK_METHOD2(OnStreamReset, void(QuicStreamId, QuicRstStreamErrorCode)); MOCK_METHOD1(SendControlFrame, bool(const QuicFrame& frame)); - MOCK_METHOD2(SendMessage, MessageStatus(QuicMessageId, QuicMemSliceSpan)); + MOCK_METHOD3(SendMessage, + MessageStatus(QuicMessageId, QuicMemSliceSpan, bool)); MOCK_METHOD3(OnConnectionClosed, void(QuicErrorCode error, const std::string& error_details, @@ -666,6 +669,12 @@ class MockQuicSession : public QuicSession { QuicStreamOffset offset, StreamSendingState state); + void ReallySendRstStream(QuicStreamId id, + QuicRstStreamErrorCode error, + QuicStreamOffset bytes_written) { + QuicSession::SendRstStream(id, error, bytes_written); + } + private: std::unique_ptr<QuicCryptoStream> crypto_stream_; }; @@ -681,6 +690,7 @@ class MockQuicCryptoStream : public QuicCryptoStream { const QuicCryptoNegotiatedParameters& crypto_negotiated_params() const override; CryptoMessageParser* crypto_message_parser() override; + void OnPacketDecrypted(EncryptionLevel /*level*/) override {} private: QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_; @@ -947,7 +957,9 @@ class MockSendAlgorithm : public SendAlgorithmInterface { MOCK_CONST_METHOD0(GetCongestionControlType, CongestionControlType()); MOCK_METHOD3(AdjustNetworkParameters, void(QuicBandwidth, QuicTime::Delta, bool)); + MOCK_METHOD1(AdjustNetworkParameters, void(const NetworkParams&)); MOCK_METHOD1(OnApplicationLimited, void(QuicByteCount)); + MOCK_CONST_METHOD1(PopulateConnectionStats, void(QuicConnectionStats*)); }; class MockLossAlgorithm : public LossDetectionInterface { @@ -966,11 +978,6 @@ class MockLossAlgorithm : public LossDetectionInterface { const AckedPacketVector& packets_acked, LostPacketVector* packets_lost)); MOCK_CONST_METHOD0(GetLossTimeout, QuicTime()); - MOCK_METHOD4(SpuriousRetransmitDetected, - void(const QuicUnackedPacketMap&, - QuicTime, - const RttStats&, - QuicPacketNumber)); MOCK_METHOD5(SpuriousLossDetected, void(const QuicUnackedPacketMap&, const RttStats&, @@ -1014,11 +1021,8 @@ class MockQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor { MOCK_METHOD1(OnFrameAddedToPacket, void(const QuicFrame&)); - MOCK_METHOD4(OnPacketSent, - void(const SerializedPacket&, - QuicPacketNumber, - TransmissionType, - QuicTime)); + MOCK_METHOD3(OnPacketSent, + void(const SerializedPacket&, TransmissionType, QuicTime)); MOCK_METHOD0(OnPingSent, void()); @@ -1195,8 +1199,6 @@ void ExpectApproxEq(T expected, T actual, float relative_margin) { template <typename T> QuicHeaderList AsHeaderList(const T& container) { QuicHeaderList l; - // No need to enforce header list size limits again in this handler. - l.set_max_header_list_size(UINT_MAX); l.OnHeaderBlockStart(); size_t total_size = 0; for (auto p : container) { @@ -1254,6 +1256,46 @@ MATCHER_P2(InRange, min, max, "") { return arg >= min && arg <= max; } +// A GMock matcher that prints expected and actual QuicErrorCode strings +// upon failure. Example usage: +// EXPECT_THAT(stream_->connection_error()), IsError(QUIC_INTERNAL_ERROR)); +MATCHER_P(IsError, + expected, + QuicStrCat(negation ? "isn't equal to " : "is equal to ", + QuicErrorCodeToString(expected))) { + *result_listener << QuicErrorCodeToString(arg); + return arg == expected; +} + +// Shorthand for IsError(QUIC_NO_ERROR). +// Example usage: EXPECT_THAT(stream_->connection_error(), IsQuicNoError()); +MATCHER(IsQuicNoError, + QuicStrCat(negation ? "isn't equal to " : "is equal to ", + QuicErrorCodeToString(QUIC_NO_ERROR))) { + *result_listener << QuicErrorCodeToString(arg); + return arg == QUIC_NO_ERROR; +} + +// A GMock matcher that prints expected and actual QuicRstStreamErrorCode +// strings upon failure. Example usage: +// EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_INTERNAL_ERROR)); +MATCHER_P(IsStreamError, + expected, + QuicStrCat(negation ? "isn't equal to " : "is equal to ", + QuicRstStreamErrorCodeToString(expected))) { + *result_listener << QuicRstStreamErrorCodeToString(arg); + return arg == expected; +} + +// Shorthand for IsStreamError(QUIC_STREAM_NO_ERROR). Example usage: +// EXPECT_THAT(stream_->stream_error(), IsQuicStreamNoError()); +MATCHER(IsQuicStreamNoError, + QuicStrCat(negation ? "isn't equal to " : "is equal to ", + QuicRstStreamErrorCodeToString(QUIC_STREAM_NO_ERROR))) { + *result_listener << QuicRstStreamErrorCodeToString(arg); + return arg == QUIC_STREAM_NO_ERROR; +} + } // namespace test } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_transport_test_tools.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_transport_test_tools.h new file mode 100644 index 00000000000..c6a8b46496e --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_transport_test_tools.h @@ -0,0 +1,36 @@ +// Copyright (c) 2019 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. + +#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TRANSPORT_TEST_TOOLS_H_ +#define QUICHE_QUIC_TEST_TOOLS_QUIC_TRANSPORT_TEST_TOOLS_H_ + +#include "net/third_party/quiche/src/quic/platform/api/quic_test.h" +#include "net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.h" +#include "net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.h" + +namespace quic { +namespace test { + +class MockClientVisitor : public QuicTransportClientSession::ClientVisitor { + public: + MOCK_METHOD0(OnIncomingBidirectionalStreamAvailable, void()); + MOCK_METHOD0(OnIncomingUnidirectionalStreamAvailable, void()); +}; + +class MockServerVisitor : public QuicTransportServerSession::ServerVisitor { + public: + MOCK_METHOD1(CheckOrigin, bool(url::Origin)); +}; + +class MockStreamVisitor : public QuicTransportStream::Visitor { + public: + MOCK_METHOD0(OnCanRead, void()); + MOCK_METHOD0(OnFinRead, void()); + MOCK_METHOD0(OnCanWrite, void()); +}; + +} // namespace test +} // namespace quic + +#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_TRANSPORT_TEST_TOOLS_H_ diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.cc index be03aa1c869..588f3b66d43 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.cc @@ -59,7 +59,9 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface { return true; } - void OnCoalescedPacket(const QuicEncryptedPacket& /*packet*/) override {} + void OnCoalescedPacket(const QuicEncryptedPacket& packet) override { + coalesced_packet_ = packet.Clone(); + } void OnUndecryptablePacket(const QuicEncryptedPacket& /*packet*/, EncryptionLevel /*decryption_level*/, @@ -253,6 +255,9 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface { return version_negotiation_packet_.get(); } EncryptionLevel last_decrypted_level() const { return last_decrypted_level_; } + const QuicEncryptedPacket* coalesced_packet() const { + return coalesced_packet_.get(); + } private: QuicErrorCode error_; @@ -284,6 +289,7 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface { std::vector<std::unique_ptr<std::string>> stream_data_; std::vector<std::unique_ptr<std::string>> crypto_data_; EncryptionLevel last_decrypted_level_; + std::unique_ptr<QuicEncryptedPacket> coalesced_packet_; }; SimpleQuicFramer::SimpleQuicFramer() @@ -404,5 +410,9 @@ const std::vector<QuicPaddingFrame>& SimpleQuicFramer::padding_frames() const { return visitor_->padding_frames(); } +const QuicEncryptedPacket* SimpleQuicFramer::coalesced_packet() const { + return visitor_->coalesced_packet(); +} + } // namespace test } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h b/chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h index a254ce523e9..3e063d07334 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h @@ -50,6 +50,7 @@ class SimpleQuicFramer { const std::vector<QuicPaddingFrame>& padding_frames() const; const QuicVersionNegotiationPacket* version_negotiation_packet() const; EncryptionLevel last_decrypted_level() const; + const QuicEncryptedPacket* coalesced_packet() const; QuicFramer* framer(); diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.cc new file mode 100644 index 00000000000..7787fbeb059 --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.cc @@ -0,0 +1,28 @@ +// Copyright (c) 2019 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/test_tools/simple_session_cache.h" + +namespace quic { +namespace test { + +void SimpleSessionCache::Insert(const QuicServerId& server_id, + std::unique_ptr<QuicResumptionState> state) { + cache_entries_.insert(std::make_pair(server_id, std::move(state))); +} + +std::unique_ptr<QuicResumptionState> SimpleSessionCache::Lookup( + const QuicServerId& server_id, + const SSL_CTX* /*ctx*/) { + auto it = cache_entries_.find(server_id); + if (it == cache_entries_.end()) { + return nullptr; + } + std::unique_ptr<QuicResumptionState> state = std::move(it->second); + cache_entries_.erase(it); + return state; +} + +} // namespace test +} // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.h b/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.h new file mode 100644 index 00000000000..40a6946dfde --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.h @@ -0,0 +1,35 @@ +// Copyright (c) 2019 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. + +#ifndef QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_CACHE_H_ +#define QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_CACHE_H_ + +#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h" + +namespace quic { +namespace test { + +// SimpleSessionCache provides a simple implementation of SessionCache that +// stores only one QuicResumptionState per QuicServerId. No limit is placed on +// the total number of entries in the cache. When Lookup is called, if a cache +// entry exists for the provided QuicServerId, the entry will be removed from +// the cached when it is returned. +class SimpleSessionCache : public SessionCache { + public: + SimpleSessionCache() = default; + ~SimpleSessionCache() override = default; + + void Insert(const QuicServerId& server_id, + std::unique_ptr<QuicResumptionState> state) override; + std::unique_ptr<QuicResumptionState> Lookup(const QuicServerId& server_id, + const SSL_CTX* ctx) override; + + private: + std::map<QuicServerId, std::unique_ptr<QuicResumptionState>> cache_entries_; +}; + +} // namespace test +} // namespace quic + +#endif // QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_CACHE_H_ diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier.cc index 72a23d73178..9e67c899f51 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier.cc @@ -46,7 +46,6 @@ QuicConsumedData SimpleSessionNotifier::WriteOrBufferData( StreamState& stream_state = stream_map_.find(id)->second; const bool had_buffered_data = HasBufferedStreamData() || HasBufferedControlFrames(); - QuicConsumedData total_consumed(0, false); QuicStreamOffset offset = stream_state.bytes_sent; QUIC_DVLOG(1) << "WriteOrBuffer stream_id: " << id << " [" << offset << ", " << offset + data_length << "), fin: " << (state != NO_FIN); @@ -127,8 +126,13 @@ void SimpleSessionNotifier::WriteOrBufferPing() { } void SimpleSessionNotifier::NeuterUnencryptedData() { - // TODO(nharper): Handle CRYPTO frame case. if (QuicVersionUsesCryptoFrames(connection_->transport_version())) { + for (const auto& interval : crypto_bytes_transferred_[ENCRYPTION_INITIAL]) { + QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, interval.min(), + interval.max() - interval.min()); + OnFrameAcked(QuicFrame(&crypto_frame), QuicTime::Delta::Zero(), + QuicTime::Zero()); + } return; } for (const auto& interval : crypto_bytes_transferred_[ENCRYPTION_INITIAL]) { diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier_test.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier_test.cc index 93f11aa387d..4dc48a7c1d5 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier_test.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier_test.cc @@ -42,7 +42,7 @@ class SimpleSessionNotifierTest : public QuicTest { : connection_(&helper_, &alarm_factory_, Perspective::IS_CLIENT), notifier_(&connection_) { connection_.set_visitor(&visitor_); - QuicConnectionPeer::SetSessionDecidesWhatToWrite(&connection_); + connection_.SetSessionNotifier(¬ifier_); EXPECT_FALSE(notifier_.WillingToWrite()); EXPECT_EQ(0u, notifier_.StreamBytesSent()); EXPECT_FALSE(notifier_.HasBufferedStreamData()); @@ -135,6 +135,8 @@ TEST_F(SimpleSessionNotifierTest, WriteOrBufferPing) { TEST_F(SimpleSessionNotifierTest, NeuterUnencryptedData) { if (QuicVersionUsesCryptoFrames(connection_.transport_version())) { + // This test writes crypto data through crypto streams. It won't work when + // crypto frames are used instead. return; } InSequence s; @@ -175,6 +177,8 @@ TEST_F(SimpleSessionNotifierTest, NeuterUnencryptedData) { TEST_F(SimpleSessionNotifierTest, OnCanWrite) { if (QuicVersionUsesCryptoFrames(connection_.transport_version())) { + // This test writes crypto data through crypto streams. It won't work when + // crypto frames are used instead. return; } InSequence s; diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.cc index bd01c43d252..9f504359dbf 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.cc @@ -4,6 +4,7 @@ #include "net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.h" +#include <memory> #include <utility> #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h" @@ -23,89 +24,41 @@ const QuicStreamId kDataStream = 3; const QuicByteCount kWriteChunkSize = 128 * 1024; const char kStreamDataContents = 'Q'; -// Takes a SHA-1 hash of the name and converts it into five 32-bit integers. -static std::vector<uint32_t> HashNameIntoFive32BitIntegers(std::string name) { - const std::string hash = test::Sha1Hash(name); - - std::vector<uint32_t> output; - uint32_t current_number = 0; - for (size_t i = 0; i < hash.size(); i++) { - current_number = (current_number << 8) + hash[i]; - if (i % 4 == 3) { - output.push_back(i); - current_number = 0; - } - } - - return output; -} - -QuicSocketAddress GetAddressFromName(std::string name) { - const std::vector<uint32_t> hash = HashNameIntoFive32BitIntegers(name); - - // Generate a random port between 1025 and 65535. - const uint16_t port = 1025 + hash[0] % (65535 - 1025 + 1); - - // Generate a random 10.x.x.x address, where x is between 1 and 254. - std::string ip_address{"\xa\0\0\0", 4}; - for (size_t i = 1; i < 4; i++) { - ip_address[i] = 1 + hash[i] % 254; - } - QuicIpAddress host; - host.FromPackedString(ip_address.c_str(), ip_address.length()); - return QuicSocketAddress(host, port); -} - QuicEndpoint::QuicEndpoint(Simulator* simulator, std::string name, std::string peer_name, Perspective perspective, QuicConnectionId connection_id) - : Endpoint(simulator, name), - peer_name_(peer_name), - writer_(this), - nic_tx_queue_(simulator, - QuicStringPrintf("%s (TX Queue)", name.c_str()), - kMaxOutgoingPacketSize * kTxQueueSize), - connection_(connection_id, - GetAddressFromName(peer_name), - simulator, - simulator->GetAlarmFactory(), - &writer_, - false, - perspective, - ParsedVersionOfIndex(CurrentSupportedVersions(), 0)), + : QuicEndpointBase(simulator, name, peer_name), bytes_to_transfer_(0), bytes_transferred_(0), - write_blocked_count_(0), wrong_data_received_(false), - drop_next_packet_(false), notifier_(nullptr) { - nic_tx_queue_.set_listener_interface(this); - - connection_.SetSelfAddress(GetAddressFromName(name)); - connection_.set_visitor(this); - connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE, - std::make_unique<NullEncrypter>(perspective)); - connection_.SetEncrypter(ENCRYPTION_INITIAL, nullptr); - if (connection_.version().KnowsWhichDecrypterToUse()) { - connection_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE, - std::make_unique<NullDecrypter>(perspective)); - connection_.RemoveDecrypter(ENCRYPTION_INITIAL); + connection_ = std::make_unique<QuicConnection>( + connection_id, GetAddressFromName(peer_name), simulator, + simulator->GetAlarmFactory(), &writer_, false, perspective, + ParsedVersionOfIndex(CurrentSupportedVersions(), 0)); + connection_->SetSelfAddress(GetAddressFromName(name)); + connection_->set_visitor(this); + connection_->SetEncrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullEncrypter>(perspective)); + connection_->SetEncrypter(ENCRYPTION_INITIAL, nullptr); + if (connection_->version().KnowsWhichDecrypterToUse()) { + connection_->InstallDecrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullDecrypter>(perspective)); + connection_->RemoveDecrypter(ENCRYPTION_INITIAL); } else { - connection_.SetDecrypter(ENCRYPTION_FORWARD_SECURE, - std::make_unique<NullDecrypter>(perspective)); + connection_->SetDecrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullDecrypter>(perspective)); } - connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); + connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); if (perspective == Perspective::IS_SERVER) { // Skip version negotiation. - test::QuicConnectionPeer::SetNegotiatedVersion(&connection_); - } - connection_.SetDataProducer(&producer_); - connection_.SetSessionNotifier(this); - if (connection_.session_decides_what_to_write()) { - notifier_ = std::make_unique<test::SimpleSessionNotifier>(&connection_); + test::QuicConnectionPeer::SetNegotiatedVersion(connection_.get()); } + connection_->SetDataProducer(&producer_); + connection_->SetSessionNotifier(this); + notifier_ = std::make_unique<test::SimpleSessionNotifier>(connection_.get()); // Configure the connection as if it received a handshake. This is important // primarily because @@ -122,19 +75,7 @@ QuicEndpoint::QuicEndpoint(Simulator* simulator, peer_hello, perspective == Perspective::IS_CLIENT ? SERVER : CLIENT, &error); DCHECK_EQ(error_code, QUIC_NO_ERROR) << "Configuration failed: " << error; - connection_.SetFromConfig(config); -} - -QuicEndpoint::~QuicEndpoint() { - if (trace_visitor_ != nullptr) { - const char* perspective_prefix = - connection_.perspective() == Perspective::IS_CLIENT ? "C" : "S"; - - std::string identifier = - QuicStrCat(perspective_prefix, connection_.connection_id().ToString()); - QuicRecordTestOutput(identifier, - trace_visitor_->trace()->SerializeAsString()); - } + connection_->SetFromConfig(config); } QuicByteCount QuicEndpoint::bytes_received() const { @@ -176,48 +117,6 @@ void QuicEndpoint::AddBytesToTransfer(QuicByteCount bytes) { WriteStreamData(); } -void QuicEndpoint::DropNextIncomingPacket() { - drop_next_packet_ = true; -} - -void QuicEndpoint::RecordTrace() { - trace_visitor_ = std::make_unique<QuicTraceVisitor>(&connection_); - connection_.set_debug_visitor(trace_visitor_.get()); -} - -void QuicEndpoint::AcceptPacket(std::unique_ptr<Packet> packet) { - if (packet->destination != name_) { - return; - } - if (drop_next_packet_) { - drop_next_packet_ = false; - return; - } - - QuicReceivedPacket received_packet(packet->contents.data(), - packet->contents.size(), clock_->Now()); - connection_.ProcessUdpPacket(connection_.self_address(), - connection_.peer_address(), received_packet); -} - -UnconstrainedPortInterface* QuicEndpoint::GetRxPort() { - return this; -} - -void QuicEndpoint::SetTxPort(ConstrainedPortInterface* port) { - // Any egress done by the endpoint is actually handled by a queue on an NIC. - nic_tx_queue_.set_tx_port(port); -} - -void QuicEndpoint::OnPacketDequeued() { - if (writer_.IsWriteBlocked() && - (nic_tx_queue_.capacity() - nic_tx_queue_.bytes_queued()) >= - kMaxOutgoingPacketSize) { - writer_.SetWritable(); - connection_.OnCanWrite(); - } -} - void QuicEndpoint::OnStreamFrame(const QuicStreamFrame& frame) { // Verify that the data received always matches the expected. DCHECK(frame.stream_id == kDataStream); @@ -302,73 +201,6 @@ bool QuicEndpoint::HasUnackedStreamData() const { return false; } -QuicEndpoint::Writer::Writer(QuicEndpoint* endpoint) - : endpoint_(endpoint), is_blocked_(false) {} - -QuicEndpoint::Writer::~Writer() {} - -WriteResult QuicEndpoint::Writer::WritePacket( - const char* buffer, - size_t buf_len, - const QuicIpAddress& /*self_address*/, - const QuicSocketAddress& /*peer_address*/, - PerPacketOptions* options) { - DCHECK(!IsWriteBlocked()); - DCHECK(options == nullptr); - DCHECK(buf_len <= kMaxOutgoingPacketSize); - - // Instead of losing a packet, become write-blocked when the egress queue is - // full. - if (endpoint_->nic_tx_queue_.packets_queued() > kTxQueueSize) { - is_blocked_ = true; - endpoint_->write_blocked_count_++; - return WriteResult(WRITE_STATUS_BLOCKED, 0); - } - - auto packet = std::make_unique<Packet>(); - packet->source = endpoint_->name(); - packet->destination = endpoint_->peer_name_; - packet->tx_timestamp = endpoint_->clock_->Now(); - - packet->contents = std::string(buffer, buf_len); - packet->size = buf_len; - - endpoint_->nic_tx_queue_.AcceptPacket(std::move(packet)); - - return WriteResult(WRITE_STATUS_OK, buf_len); -} - -bool QuicEndpoint::Writer::IsWriteBlocked() const { - return is_blocked_; -} - -void QuicEndpoint::Writer::SetWritable() { - is_blocked_ = false; -} - -QuicByteCount QuicEndpoint::Writer::GetMaxPacketSize( - const QuicSocketAddress& /*peer_address*/) const { - return kMaxOutgoingPacketSize; -} - -bool QuicEndpoint::Writer::SupportsReleaseTime() const { - return false; -} - -bool QuicEndpoint::Writer::IsBatchMode() const { - return false; -} - -char* QuicEndpoint::Writer::GetNextWriteLocation( - const QuicIpAddress& /*self_address*/, - const QuicSocketAddress& /*peer_address*/) { - return nullptr; -} - -WriteResult QuicEndpoint::Writer::Flush() { - return WriteResult(WRITE_STATUS_OK, 0); -} - WriteStreamDataResult QuicEndpoint::DataProducer::WriteStreamData( QuicStreamId /*id*/, QuicStreamOffset /*offset*/, @@ -388,14 +220,14 @@ bool QuicEndpoint::DataProducer::WriteCryptoData(EncryptionLevel /*level*/, void QuicEndpoint::WriteStreamData() { // Instantiate a flusher which would normally be here due to QuicSession. - QuicConnection::ScopedPacketFlusher flusher(&connection_); + QuicConnection::ScopedPacketFlusher flusher(connection_.get()); while (bytes_to_transfer_ > 0) { // Transfer data in chunks of size at most |kWriteChunkSize|. const size_t transmission_size = std::min(kWriteChunkSize, bytes_to_transfer_); - QuicConsumedData consumed_data = connection_.SendStreamData( + QuicConsumedData consumed_data = connection_->SendStreamData( kDataStream, transmission_size, bytes_transferred_, NO_FIN); DCHECK(consumed_data.bytes_consumed <= transmission_size); @@ -407,33 +239,5 @@ void QuicEndpoint::WriteStreamData() { } } -QuicEndpointMultiplexer::QuicEndpointMultiplexer( - std::string name, - const std::vector<QuicEndpoint*>& endpoints) - : Endpoint((*endpoints.begin())->simulator(), name) { - for (QuicEndpoint* endpoint : endpoints) { - mapping_.insert(std::make_pair(endpoint->name(), endpoint)); - } -} - -QuicEndpointMultiplexer::~QuicEndpointMultiplexer() {} - -void QuicEndpointMultiplexer::AcceptPacket(std::unique_ptr<Packet> packet) { - auto key_value_pair_it = mapping_.find(packet->destination); - if (key_value_pair_it == mapping_.end()) { - return; - } - - key_value_pair_it->second->GetRxPort()->AcceptPacket(std::move(packet)); -} -UnconstrainedPortInterface* QuicEndpointMultiplexer::GetRxPort() { - return this; -} -void QuicEndpointMultiplexer::SetTxPort(ConstrainedPortInterface* port) { - for (auto& key_value_pair : mapping_) { - key_value_pair.second->SetTxPort(port); - } -} - } // namespace simulator } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.h b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.h index 43fce53bb4c..c2d24ac5404 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.h +++ b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.h @@ -16,26 +16,17 @@ #include "net/third_party/quiche/src/quic/test_tools/simple_session_notifier.h" #include "net/third_party/quiche/src/quic/test_tools/simulator/link.h" #include "net/third_party/quiche/src/quic/test_tools/simulator/queue.h" +#include "net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.h" namespace quic { namespace simulator { -// Size of the TX queue used by the kernel/NIC. 1000 is the Linux -// kernel default. -const QuicByteCount kTxQueueSize = 1000; - -// Generate a random local network host-port tuple based on the name of the -// endpoint. -QuicSocketAddress GetAddressFromName(std::string name); - // A QUIC connection endpoint. Wraps around QuicConnection. In order to // initiate a transfer, the caller has to call AddBytesToTransfer(). The data // transferred is always the same and is always transferred on a single stream. // The endpoint receives all packets addressed to it, and verifies that the data // received is what it's supposed to be. -class QuicEndpoint : public Endpoint, - public UnconstrainedPortInterface, - public Queue::ListenerInterface, +class QuicEndpoint : public QuicEndpointBase, public QuicConnectionVisitorInterface, public SessionNotifierInterface { public: @@ -44,40 +35,16 @@ class QuicEndpoint : public Endpoint, std::string peer_name, Perspective perspective, QuicConnectionId connection_id); - ~QuicEndpoint() override; - inline QuicConnection* connection() { return &connection_; } QuicByteCount bytes_to_transfer() const; QuicByteCount bytes_transferred() const; QuicByteCount bytes_received() const; - inline size_t write_blocked_count() { return write_blocked_count_; } inline bool wrong_data_received() const { return wrong_data_received_; } // Send |bytes| bytes. Initiates the transfer if one is not already in // progress. void AddBytesToTransfer(QuicByteCount bytes); - // Drop the next packet upon receipt. - void DropNextIncomingPacket(); - - // UnconstrainedPortInterface method. Called whenever the endpoint receives a - // packet. - void AcceptPacket(std::unique_ptr<Packet> packet) override; - - // Enables logging of the connection trace at the end of the unit test. - void RecordTrace(); - - // Begin Endpoint implementation. - UnconstrainedPortInterface* GetRxPort() override; - void SetTxPort(ConstrainedPortInterface* port) override; - // End Endpoint implementation. - - // Actor method. - void Act() override {} - - // Queue::ListenerInterface method. - void OnPacketDequeued() override; - // Begin QuicConnectionVisitorInterface implementation. void OnStreamFrame(const QuicStreamFrame& frame) override; void OnCryptoFrame(const QuicCryptoFrame& frame) override; @@ -114,9 +81,8 @@ class QuicEndpoint : public Endpoint, const QuicStreamsBlockedFrame& /*frame*/) override { return true; } - bool OnStopSendingFrame(const QuicStopSendingFrame& /*frame*/) override { - return true; - } + void OnStopSendingFrame(const QuicStopSendingFrame& /*frame*/) override {} + void OnPacketDecrypted(EncryptionLevel /*level*/) override {} // End QuicConnectionVisitorInterface implementation. @@ -134,33 +100,6 @@ class QuicEndpoint : public Endpoint, // End SessionNotifierInterface implementation. private: - // A Writer object that writes into the |nic_tx_queue_|. - class Writer : public QuicPacketWriter { - public: - explicit Writer(QuicEndpoint* endpoint); - ~Writer() override; - - WriteResult WritePacket(const char* buffer, - size_t buf_len, - const QuicIpAddress& self_address, - const QuicSocketAddress& peer_address, - PerPacketOptions* options) override; - bool IsWriteBlocked() const override; - void SetWritable() override; - QuicByteCount GetMaxPacketSize( - const QuicSocketAddress& peer_address) const override; - bool SupportsReleaseTime() const override; - bool IsBatchMode() const override; - char* GetNextWriteLocation(const QuicIpAddress& self_address, - const QuicSocketAddress& peer_address) override; - WriteResult Flush() override; - - private: - QuicEndpoint* endpoint_; - - bool is_blocked_; - }; - // The producer outputs the repetition of the same byte. That sequence is // verified by the receiver. class DataProducer : public QuicStreamFrameDataProducer { @@ -175,60 +114,30 @@ class QuicEndpoint : public Endpoint, QuicDataWriter* writer) override; }; + std::unique_ptr<QuicConnection> CreateConnection( + Simulator* simulator, + std::string name, + std::string peer_name, + Perspective perspective, + QuicConnectionId connection_id); + // Write stream data until |bytes_to_transfer_| is zero or the connection is // write-blocked. void WriteStreamData(); - std::string peer_name_; - - Writer writer_; DataProducer producer_; - // The queue for the outgoing packets. In reality, this might be either on - // the network card, or in the kernel, but for concreteness we assume it's on - // the network card. - Queue nic_tx_queue_; - QuicConnection connection_; QuicByteCount bytes_to_transfer_; QuicByteCount bytes_transferred_; - // Counts the number of times the writer became write-blocked. - size_t write_blocked_count_; - // Set to true if the endpoint receives stream data different from what it // expects. bool wrong_data_received_; - // If true, drop the next packet when receiving it. - bool drop_next_packet_; - // Record of received offsets in the data stream. QuicIntervalSet<QuicStreamOffset> offsets_received_; std::unique_ptr<test::SimpleSessionNotifier> notifier_; - std::unique_ptr<QuicTraceVisitor> trace_visitor_; -}; - -// Multiplexes multiple connections at the same host on the network. -class QuicEndpointMultiplexer : public Endpoint, - public UnconstrainedPortInterface { - public: - QuicEndpointMultiplexer(std::string name, - const std::vector<QuicEndpoint*>& endpoints); - ~QuicEndpointMultiplexer() override; - - // Receives a packet and passes it to the specified endpoint if that endpoint - // is one of the endpoints being multiplexed, otherwise ignores the packet. - void AcceptPacket(std::unique_ptr<Packet> packet) override; - UnconstrainedPortInterface* GetRxPort() override; - - // Sets the egress port for all the endpoints being multiplexed. - void SetTxPort(ConstrainedPortInterface* port) override; - - void Act() override {} - - private: - QuicUnorderedMap<std::string, QuicEndpoint*> mapping_; }; } // namespace simulator diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.cc new file mode 100644 index 00000000000..537a94737b4 --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.cc @@ -0,0 +1,222 @@ +// 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/test_tools/simulator/quic_endpoint_base.h" + +#include <memory> +#include <utility> + +#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h" +#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" +#include "net/third_party/quiche/src/quic/core/quic_connection.h" +#include "net/third_party/quiche/src/quic/core/quic_data_writer.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_test_output.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h" +#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h" +#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" +#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h" + +namespace quic { +namespace simulator { + +// Takes a SHA-1 hash of the name and converts it into five 32-bit integers. +static std::vector<uint32_t> HashNameIntoFive32BitIntegers(std::string name) { + const std::string hash = test::Sha1Hash(name); + + std::vector<uint32_t> output; + uint32_t current_number = 0; + for (size_t i = 0; i < hash.size(); i++) { + current_number = (current_number << 8) + hash[i]; + if (i % 4 == 3) { + output.push_back(i); + current_number = 0; + } + } + + return output; +} + +QuicSocketAddress GetAddressFromName(std::string name) { + const std::vector<uint32_t> hash = HashNameIntoFive32BitIntegers(name); + + // Generate a random port between 1025 and 65535. + const uint16_t port = 1025 + hash[0] % (65535 - 1025 + 1); + + // Generate a random 10.x.x.x address, where x is between 1 and 254. + std::string ip_address{"\xa\0\0\0", 4}; + for (size_t i = 1; i < 4; i++) { + ip_address[i] = 1 + hash[i] % 254; + } + QuicIpAddress host; + host.FromPackedString(ip_address.c_str(), ip_address.length()); + return QuicSocketAddress(host, port); +} + +QuicEndpointBase::QuicEndpointBase(Simulator* simulator, + std::string name, + std::string peer_name) + : Endpoint(simulator, name), + peer_name_(peer_name), + writer_(this), + nic_tx_queue_(simulator, + QuicStringPrintf("%s (TX Queue)", name.c_str()), + kMaxOutgoingPacketSize * kTxQueueSize), + connection_(nullptr), + write_blocked_count_(0), + drop_next_packet_(false) { + nic_tx_queue_.set_listener_interface(this); +} + +QuicEndpointBase::~QuicEndpointBase() { + if (trace_visitor_ != nullptr) { + const char* perspective_prefix = + connection_->perspective() == Perspective::IS_CLIENT ? "C" : "S"; + + std::string identifier = + QuicStrCat(perspective_prefix, connection_->connection_id().ToString()); + QuicRecordTestOutput(identifier, + trace_visitor_->trace()->SerializeAsString()); + } +} + +void QuicEndpointBase::DropNextIncomingPacket() { + drop_next_packet_ = true; +} + +void QuicEndpointBase::RecordTrace() { + trace_visitor_ = std::make_unique<QuicTraceVisitor>(connection_.get()); + connection_->set_debug_visitor(trace_visitor_.get()); +} + +void QuicEndpointBase::AcceptPacket(std::unique_ptr<Packet> packet) { + if (packet->destination != name_) { + return; + } + if (drop_next_packet_) { + drop_next_packet_ = false; + return; + } + + QuicReceivedPacket received_packet(packet->contents.data(), + packet->contents.size(), clock_->Now()); + connection_->ProcessUdpPacket(connection_->self_address(), + connection_->peer_address(), received_packet); +} + +UnconstrainedPortInterface* QuicEndpointBase::GetRxPort() { + return this; +} + +void QuicEndpointBase::SetTxPort(ConstrainedPortInterface* port) { + // Any egress done by the endpoint is actually handled by a queue on an NIC. + nic_tx_queue_.set_tx_port(port); +} + +void QuicEndpointBase::OnPacketDequeued() { + if (writer_.IsWriteBlocked() && + (nic_tx_queue_.capacity() - nic_tx_queue_.bytes_queued()) >= + kMaxOutgoingPacketSize) { + writer_.SetWritable(); + connection_->OnCanWrite(); + } +} + +QuicEndpointBase::Writer::Writer(QuicEndpointBase* endpoint) + : endpoint_(endpoint), is_blocked_(false) {} + +QuicEndpointBase::Writer::~Writer() {} + +WriteResult QuicEndpointBase::Writer::WritePacket( + const char* buffer, + size_t buf_len, + const QuicIpAddress& /*self_address*/, + const QuicSocketAddress& /*peer_address*/, + PerPacketOptions* options) { + DCHECK(!IsWriteBlocked()); + DCHECK(options == nullptr); + DCHECK(buf_len <= kMaxOutgoingPacketSize); + + // Instead of losing a packet, become write-blocked when the egress queue is + // full. + if (endpoint_->nic_tx_queue_.packets_queued() > kTxQueueSize) { + is_blocked_ = true; + endpoint_->write_blocked_count_++; + return WriteResult(WRITE_STATUS_BLOCKED, 0); + } + + auto packet = std::make_unique<Packet>(); + packet->source = endpoint_->name(); + packet->destination = endpoint_->peer_name_; + packet->tx_timestamp = endpoint_->clock_->Now(); + + packet->contents = std::string(buffer, buf_len); + packet->size = buf_len; + + endpoint_->nic_tx_queue_.AcceptPacket(std::move(packet)); + + return WriteResult(WRITE_STATUS_OK, buf_len); +} + +bool QuicEndpointBase::Writer::IsWriteBlocked() const { + return is_blocked_; +} + +void QuicEndpointBase::Writer::SetWritable() { + is_blocked_ = false; +} + +QuicByteCount QuicEndpointBase::Writer::GetMaxPacketSize( + const QuicSocketAddress& /*peer_address*/) const { + return kMaxOutgoingPacketSize; +} + +bool QuicEndpointBase::Writer::SupportsReleaseTime() const { + return false; +} + +bool QuicEndpointBase::Writer::IsBatchMode() const { + return false; +} + +char* QuicEndpointBase::Writer::GetNextWriteLocation( + const QuicIpAddress& /*self_address*/, + const QuicSocketAddress& /*peer_address*/) { + return nullptr; +} + +WriteResult QuicEndpointBase::Writer::Flush() { + return WriteResult(WRITE_STATUS_OK, 0); +} + +QuicEndpointMultiplexer::QuicEndpointMultiplexer( + std::string name, + const std::vector<QuicEndpointBase*>& endpoints) + : Endpoint((*endpoints.begin())->simulator(), name) { + for (QuicEndpointBase* endpoint : endpoints) { + mapping_.insert(std::make_pair(endpoint->name(), endpoint)); + } +} + +QuicEndpointMultiplexer::~QuicEndpointMultiplexer() {} + +void QuicEndpointMultiplexer::AcceptPacket(std::unique_ptr<Packet> packet) { + auto key_value_pair_it = mapping_.find(packet->destination); + if (key_value_pair_it == mapping_.end()) { + return; + } + + key_value_pair_it->second->GetRxPort()->AcceptPacket(std::move(packet)); +} +UnconstrainedPortInterface* QuicEndpointMultiplexer::GetRxPort() { + return this; +} +void QuicEndpointMultiplexer::SetTxPort(ConstrainedPortInterface* port) { + for (auto& key_value_pair : mapping_) { + key_value_pair.second->SetTxPort(port); + } +} + +} // namespace simulator +} // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.h b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.h new file mode 100644 index 00000000000..ae9f69b95fc --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.h @@ -0,0 +1,158 @@ +// 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. + +#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_BASE_H_ +#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_BASE_H_ + +#include <memory> + +#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/quic_connection.h" +#include "net/third_party/quiche/src/quic/core/quic_default_packet_writer.h" +#include "net/third_party/quiche/src/quic/core/quic_packets.h" +#include "net/third_party/quiche/src/quic/core/quic_stream_frame_data_producer.h" +#include "net/third_party/quiche/src/quic/core/quic_trace_visitor.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" +#include "net/third_party/quiche/src/quic/test_tools/simple_session_notifier.h" +#include "net/third_party/quiche/src/quic/test_tools/simulator/link.h" +#include "net/third_party/quiche/src/quic/test_tools/simulator/queue.h" + +namespace quic { +namespace simulator { + +// Size of the TX queue used by the kernel/NIC. 1000 is the Linux +// kernel default. +const QuicByteCount kTxQueueSize = 1000; + +// Generate a random local network host-port tuple based on the name of the +// endpoint. +QuicSocketAddress GetAddressFromName(std::string name); + +// A QUIC connection endpoint. If the specific data transmitted does not matter +// (e.g. for congestion control purposes), QuicEndpoint is the subclass that +// transmits dummy data. If the actual semantics of the connection matter, +// subclassing QuicEndpointBase is required. +class QuicEndpointBase : public Endpoint, + public UnconstrainedPortInterface, + public Queue::ListenerInterface { + public: + // Does not create the connection; the subclass has to create connection by + // itself. + QuicEndpointBase(Simulator* simulator, + std::string name, + std::string peer_name); + ~QuicEndpointBase() override; + + inline QuicConnection* connection() { return connection_.get(); } + inline size_t write_blocked_count() { return write_blocked_count_; } + + // Drop the next packet upon receipt. + void DropNextIncomingPacket(); + + // UnconstrainedPortInterface method. Called whenever the endpoint receives a + // packet. + void AcceptPacket(std::unique_ptr<Packet> packet) override; + + // Enables logging of the connection trace at the end of the unit test. + void RecordTrace(); + + // Begin Endpoint implementation. + UnconstrainedPortInterface* GetRxPort() override; + void SetTxPort(ConstrainedPortInterface* port) override; + // End Endpoint implementation. + + // Actor method. + void Act() override {} + + // Queue::ListenerInterface method. + void OnPacketDequeued() override; + + protected: + // A Writer object that writes into the |nic_tx_queue_|. + class Writer : public QuicPacketWriter { + public: + explicit Writer(QuicEndpointBase* endpoint); + ~Writer() override; + + WriteResult WritePacket(const char* buffer, + size_t buf_len, + const QuicIpAddress& self_address, + const QuicSocketAddress& peer_address, + PerPacketOptions* options) override; + bool IsWriteBlocked() const override; + void SetWritable() override; + QuicByteCount GetMaxPacketSize( + const QuicSocketAddress& peer_address) const override; + bool SupportsReleaseTime() const override; + bool IsBatchMode() const override; + char* GetNextWriteLocation(const QuicIpAddress& self_address, + const QuicSocketAddress& peer_address) override; + WriteResult Flush() override; + + private: + QuicEndpointBase* endpoint_; + + bool is_blocked_; + }; + + // The producer outputs the repetition of the same byte. That sequence is + // verified by the receiver. + class DataProducer : public QuicStreamFrameDataProducer { + public: + WriteStreamDataResult WriteStreamData(QuicStreamId id, + QuicStreamOffset offset, + QuicByteCount data_length, + QuicDataWriter* writer) override; + bool WriteCryptoData(EncryptionLevel level, + QuicStreamOffset offset, + QuicByteCount data_length, + QuicDataWriter* writer) override; + }; + + std::string peer_name_; + + Writer writer_; + // The queue for the outgoing packets. In reality, this might be either on + // the network card, or in the kernel, but for concreteness we assume it's on + // the network card. + Queue nic_tx_queue_; + // Created by the subclass. + std::unique_ptr<QuicConnection> connection_; + + // Counts the number of times the writer became write-blocked. + size_t write_blocked_count_; + + // If true, drop the next packet when receiving it. + bool drop_next_packet_; + + std::unique_ptr<QuicTraceVisitor> trace_visitor_; +}; + +// Multiplexes multiple connections at the same host on the network. +class QuicEndpointMultiplexer : public Endpoint, + public UnconstrainedPortInterface { + public: + QuicEndpointMultiplexer(std::string name, + const std::vector<QuicEndpointBase*>& endpoints); + ~QuicEndpointMultiplexer() override; + + // Receives a packet and passes it to the specified endpoint if that endpoint + // is one of the endpoints being multiplexed, otherwise ignores the packet. + void AcceptPacket(std::unique_ptr<Packet> packet) override; + UnconstrainedPortInterface* GetRxPort() override; + + // Sets the egress port for all the endpoints being multiplexed. + void SetTxPort(ConstrainedPortInterface* port) override; + + void Act() override {} + + private: + QuicUnorderedMap<std::string, QuicEndpointBase*> mapping_; +}; + +} // namespace simulator +} // namespace quic + +#endif // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_BASE_H_ diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_test.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_test.cc index 772cd2e4ffd..0989a3bc0f7 100644 --- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_test.cc +++ b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_test.cc @@ -104,8 +104,8 @@ TEST_F(QuicEndpointTest, WriteBlocked) { EXPECT_CALL(*sender, BandwidthEstimate()) .WillRepeatedly(Return(10 * kDefaultBandwidth)); EXPECT_CALL(*sender, GetCongestionWindow()) - .WillRepeatedly( - Return(kMaxOutgoingPacketSize * kDefaultMaxCongestionWindowPackets)); + .WillRepeatedly(Return(kMaxOutgoingPacketSize * + GetQuicFlag(FLAGS_quic_max_congestion_window))); test::QuicConnectionPeer::SetSendAlgorithm(endpoint_a.connection(), sender); // First transmit a small, packet-size chunk of data. |