diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-04-05 17:15:33 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-04-11 07:47:18 +0000 |
commit | 7324afb043a0b1e623d8e8eb906cdc53bdeb4685 (patch) | |
tree | a3fe2d74ea9c9e142c390dac4ca0e219382ace46 /chromium/net/quic | |
parent | 6a4cabb866f66d4128a97cdc6d9d08ce074f1247 (diff) | |
download | qtwebengine-chromium-7324afb043a0b1e623d8e8eb906cdc53bdeb4685.tar.gz |
BASELINE: Update Chromium to 58.0.3029.54
Change-Id: I67f57065a7afdc8e4614adb5c0230281428df4d1
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
Diffstat (limited to 'chromium/net/quic')
254 files changed, 4019 insertions, 6262 deletions
diff --git a/chromium/net/quic/OWNERS b/chromium/net/quic/OWNERS new file mode 100644 index 00000000000..4612afd797b --- /dev/null +++ b/chromium/net/quic/OWNERS @@ -0,0 +1 @@ +# COMPONENT: Internals>Network>QUIC diff --git a/chromium/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc b/chromium/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc index c6a4efd797a..8c6b80085a9 100644 --- a/chromium/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc +++ b/chromium/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc @@ -352,7 +352,7 @@ class BidirectionalStreamQuicImplTest }; BidirectionalStreamQuicImplTest() - : crypto_config_(CryptoTestUtils::ProofVerifierForTesting()), + : crypto_config_(crypto_test_utils::ProofVerifierForTesting()), read_buffer_(new IOBufferWithSize(4096)), connection_id_(2), stream_id_(kClientDataStreamId1), @@ -435,7 +435,7 @@ class BidirectionalStreamQuicImplTest base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)), QuicServerId(kDefaultServerHostName, kDefaultServerPort, PRIVACY_MODE_DISABLED), - kQuicYieldAfterPacketsRead, + /*require_confirmation=*/false, kQuicYieldAfterPacketsRead, QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds), /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN", dns_start, dns_end, &push_promise_index_, nullptr, @@ -443,8 +443,7 @@ class BidirectionalStreamQuicImplTest /*socket_performance_watcher=*/nullptr, net_log().bound().net_log())); session_->Initialize(); TestCompletionCallback callback; - session_->CryptoConnect(/*require_confirmation=*/false, - callback.callback()); + session_->CryptoConnect(callback.callback()); EXPECT_TRUE(session_->IsEncryptionEstablished()); } diff --git a/chromium/net/quic/chromium/crypto/proof_source_chromium.cc b/chromium/net/quic/chromium/crypto/proof_source_chromium.cc index dd8ce1f8881..fb14ba027bd 100644 --- a/chromium/net/quic/chromium/crypto/proof_source_chromium.cc +++ b/chromium/net/quic/chromium/crypto/proof_source_chromium.cc @@ -76,7 +76,7 @@ bool ProofSourceChromium::Initialize(const base::FilePath& cert_path, return true; } -bool ProofSourceChromium::GetProof( +bool ProofSourceChromium::GetProofInner( const QuicSocketAddress& server_addr, const string& hostname, const string& server_config, @@ -146,8 +146,10 @@ void ProofSourceChromium::GetProof(const QuicSocketAddress& server_addr, string signature; string leaf_cert_sct; QuicCryptoProof out_proof; - const bool ok = GetProof(server_addr, hostname, server_config, quic_version, - chlo_hash, connection_options, &chain, &out_proof); + + const bool ok = + GetProofInner(server_addr, hostname, server_config, quic_version, + chlo_hash, connection_options, &chain, &out_proof); callback->Run(ok, chain, out_proof, nullptr /* details */); } diff --git a/chromium/net/quic/chromium/crypto/proof_source_chromium.h b/chromium/net/quic/chromium/crypto/proof_source_chromium.h index 95b892d61f9..f0a8c308f82 100644 --- a/chromium/net/quic/chromium/crypto/proof_source_chromium.h +++ b/chromium/net/quic/chromium/crypto/proof_source_chromium.h @@ -33,15 +33,6 @@ class NET_EXPORT_PRIVATE ProofSourceChromium : public ProofSource { const base::FilePath& sct_path); // ProofSource interface - bool GetProof(const QuicSocketAddress& server_ip, - const std::string& hostname, - const std::string& server_config, - QuicVersion quic_version, - base::StringPiece chlo_hash, - const QuicTagVector& connection_options, - QuicReferenceCountedPointer<ProofSource::Chain>* out_chain, - QuicCryptoProof* proof) override; - void GetProof(const QuicSocketAddress& server_ip, const std::string& hostname, const std::string& server_config, @@ -51,6 +42,15 @@ class NET_EXPORT_PRIVATE ProofSourceChromium : public ProofSource { std::unique_ptr<Callback> callback) override; private: + bool GetProofInner(const QuicSocketAddress& server_ip, + const std::string& hostname, + const std::string& server_config, + QuicVersion quic_version, + base::StringPiece chlo_hash, + const QuicTagVector& connection_options, + QuicReferenceCountedPointer<ProofSource::Chain>* out_chain, + QuicCryptoProof* proof); + std::unique_ptr<crypto::RSAPrivateKey> private_key_; QuicReferenceCountedPointer<ProofSource::Chain> chain_; std::string signed_certificate_timestamp_; diff --git a/chromium/net/quic/chromium/crypto/proof_test_chromium.cc b/chromium/net/quic/chromium/crypto/proof_test_chromium.cc index 023a4332511..eb4a61b298f 100644 --- a/chromium/net/quic/chromium/crypto/proof_test_chromium.cc +++ b/chromium/net/quic/chromium/crypto/proof_test_chromium.cc @@ -65,7 +65,7 @@ void RunVerification(ProofVerifier* verifier, bool ok; string error_details; std::unique_ptr<ProofVerifyContext> verify_context( - CryptoTestUtils::ProofVerifyContextForTesting()); + crypto_test_utils::ProofVerifyContextForTesting()); std::unique_ptr<TestProofVerifierCallback> callback( new TestProofVerifierCallback(&comp_callback, &ok, &error_details)); @@ -124,9 +124,10 @@ INSTANTIATE_TEST_CASE_P(QuicVersion, // TODO(rtenneti): Enable testing of ProofVerifier. See http://crbug.com/514468. TEST_P(ProofTest, DISABLED_Verify) { - std::unique_ptr<ProofSource> source(CryptoTestUtils::ProofSourceForTesting()); + std::unique_ptr<ProofSource> source( + crypto_test_utils::ProofSourceForTesting()); std::unique_ptr<ProofVerifier> verifier( - CryptoTestUtils::ProofVerifierForTesting()); + crypto_test_utils::ProofVerifierForTesting()); const string server_config = "server config bytes"; const string hostname = "test.example.com"; @@ -135,18 +136,30 @@ TEST_P(ProofTest, DISABLED_Verify) { const string second_chlo_hash = "first chlo hash bytes"; const QuicVersion quic_version = GetParam(); + bool called = false; + bool first_called = false; + bool ok, first_ok; QuicReferenceCountedPointer<ProofSource::Chain> chain; QuicReferenceCountedPointer<ProofSource::Chain> first_chain; string error_details; QuicCryptoProof proof, first_proof; QuicSocketAddress server_addr; - ASSERT_TRUE(source->GetProof(server_addr, hostname, server_config, - quic_version, first_chlo_hash, QuicTagVector(), - &first_chain, &first_proof)); - ASSERT_TRUE(source->GetProof(server_addr, hostname, server_config, - quic_version, second_chlo_hash, QuicTagVector(), - &chain, &proof)); + std::unique_ptr<ProofSource::Callback> cb( + new TestCallback(&called, &ok, &chain, &proof)); + std::unique_ptr<ProofSource::Callback> first_cb( + new TestCallback(&first_called, &first_ok, &first_chain, &first_proof)); + + // GetProof here expects the async method to invoke the callback + // synchronously. + source->GetProof(server_addr, hostname, server_config, quic_version, + first_chlo_hash, QuicTagVector(), std::move(first_cb)); + source->GetProof(server_addr, hostname, server_config, quic_version, + second_chlo_hash, QuicTagVector(), std::move(cb)); + ASSERT_TRUE(called); + ASSERT_TRUE(first_called); + ASSERT_TRUE(ok); + ASSERT_TRUE(first_ok); // Check that the proof source is caching correctly: ASSERT_EQ(first_chain->certs, chain->certs); @@ -176,53 +189,28 @@ TEST_P(ProofTest, DISABLED_Verify) { first_chlo_hash, wrong_certs, corrupt_signature, false); } -TEST_P(ProofTest, VerifySourceAsync) { - std::unique_ptr<ProofSource> source(CryptoTestUtils::ProofSourceForTesting()); +TEST_P(ProofTest, UseAfterFree) { + std::unique_ptr<ProofSource> source( + crypto_test_utils::ProofSourceForTesting()); const string server_config = "server config bytes"; const string hostname = "test.example.com"; - const string first_chlo_hash = "first chlo hash bytes"; - const string second_chlo_hash = "first chlo hash bytes"; - const QuicVersion quic_version = GetParam(); - QuicSocketAddress server_addr; - - // Call synchronous version - QuicReferenceCountedPointer<ProofSource::Chain> expected_chain; - QuicCryptoProof expected_proof; - ASSERT_TRUE(source->GetProof(server_addr, hostname, server_config, - quic_version, first_chlo_hash, QuicTagVector(), - &expected_chain, &expected_proof)); - - // Call asynchronous version and compare results + const string chlo_hash = "proof nonce bytes"; bool called = false; bool ok; QuicReferenceCountedPointer<ProofSource::Chain> chain; + string error_details; QuicCryptoProof proof; + QuicSocketAddress server_addr; std::unique_ptr<ProofSource::Callback> cb( new TestCallback(&called, &ok, &chain, &proof)); - source->GetProof(server_addr, hostname, server_config, quic_version, - first_chlo_hash, QuicTagVector(), std::move(cb)); - // TODO(gredner): whan GetProof really invokes the callback asynchronously, - // figure out what to do here. + + // GetProof here expects the async method to invoke the callback + // synchronously. + source->GetProof(server_addr, hostname, server_config, GetParam(), chlo_hash, + QuicTagVector(), std::move(cb)); ASSERT_TRUE(called); ASSERT_TRUE(ok); - EXPECT_THAT(chain->certs, ::testing::ContainerEq(expected_chain->certs)); - EXPECT_EQ(proof.leaf_cert_scts, expected_proof.leaf_cert_scts); -} - -TEST_P(ProofTest, UseAfterFree) { - std::unique_ptr<ProofSource> source(CryptoTestUtils::ProofSourceForTesting()); - - const string server_config = "server config bytes"; - const string hostname = "test.example.com"; - const string chlo_hash = "proof nonce bytes"; - QuicReferenceCountedPointer<ProofSource::Chain> chain; - string error_details; - QuicCryptoProof proof; - QuicSocketAddress server_addr; - - ASSERT_TRUE(source->GetProof(server_addr, hostname, server_config, GetParam(), - chlo_hash, QuicTagVector(), &chain, &proof)); // Make sure we can safely access results after deleting where they came from. EXPECT_FALSE(chain->HasOneRef()); diff --git a/chromium/net/quic/chromium/crypto/proof_verifier_chromium.cc b/chromium/net/quic/chromium/crypto/proof_verifier_chromium.cc index 35503e60776..eed307d6c8f 100644 --- a/chromium/net/quic/chromium/crypto/proof_verifier_chromium.cc +++ b/chromium/net/quic/chromium/crypto/proof_verifier_chromium.cc @@ -225,14 +225,12 @@ QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof( if (!GetX509Certificate(certs, error_details, verify_details)) return QUIC_FAILURE; - if (!cert_sct.empty()) { - // Note that this is a completely synchronous operation: The CT Log Verifier - // gets all the data it needs for SCT verification and does not do any - // external communication. - cert_transparency_verifier_->Verify(cert_.get(), std::string(), cert_sct, - &verify_details_->ct_verify_result.scts, - net_log_); - } + // Note that this is a completely synchronous operation: The CT Log Verifier + // gets all the data it needs for SCT verification and does not do any + // external communication. + cert_transparency_verifier_->Verify(cert_.get(), std::string(), cert_sct, + &verify_details_->ct_verify_result.scts, + net_log_); // We call VerifySignature first to avoid copying of server_config and // signature. diff --git a/chromium/net/quic/chromium/crypto_test_utils_chromium.cc b/chromium/net/quic/chromium/crypto_test_utils_chromium.cc index a7b8df41020..691cb18ea01 100644 --- a/chromium/net/quic/chromium/crypto_test_utils_chromium.cc +++ b/chromium/net/quic/chromium/crypto_test_utils_chromium.cc @@ -79,8 +79,9 @@ class TestProofVerifierChromium : public ProofVerifierChromium { } // namespace -// static -std::unique_ptr<ProofSource> CryptoTestUtils::ProofSourceForTesting() { +namespace crypto_test_utils { + +std::unique_ptr<ProofSource> ProofSourceForTesting() { std::unique_ptr<ProofSourceChromium> source(new ProofSourceChromium()); base::FilePath certs_dir = GetTestCertsDirectory(); CHECK(source->Initialize( @@ -90,8 +91,7 @@ std::unique_ptr<ProofSource> CryptoTestUtils::ProofSourceForTesting() { return std::move(source); } -// static -std::unique_ptr<ProofVerifier> CryptoTestUtils::ProofVerifierForTesting() { +std::unique_ptr<ProofVerifier> ProofVerifierForTesting() { // TODO(rch): use a real cert verifier? std::unique_ptr<MockCertVerifier> cert_verifier(new MockCertVerifier()); net::CertVerifyResult verify_result; @@ -109,12 +109,13 @@ std::unique_ptr<ProofVerifier> CryptoTestUtils::ProofVerifierForTesting() { base::WrapUnique(new CTPolicyEnforcer), "quic_root.crt"); } -// static -ProofVerifyContext* CryptoTestUtils::ProofVerifyContextForTesting() { +ProofVerifyContext* ProofVerifyContextForTesting() { return new ProofVerifyContextChromium(/*cert_verify_flags=*/0, NetLogWithSource()); } +} // namespace crypto_test_utils + } // namespace test } // namespace net diff --git a/chromium/net/quic/chromium/mock_crypto_client_stream_factory.cc b/chromium/net/quic/chromium/mock_crypto_client_stream_factory.cc index 51f5c811379..7619bfd13bc 100644 --- a/chromium/net/quic/chromium/mock_crypto_client_stream_factory.cc +++ b/chromium/net/quic/chromium/mock_crypto_client_stream_factory.cc @@ -29,6 +29,11 @@ MockCryptoClientStreamFactory::CreateQuicCryptoClientStream( QuicChromiumClientSession* session, std::unique_ptr<ProofVerifyContext> /*proof_verify_context*/, QuicCryptoClientConfig* crypto_config) { + if (handshake_mode_ == MockCryptoClientStream::USE_DEFAULT_CRYPTO_STREAM) { + return new QuicCryptoClientStream(server_id, session, nullptr, + crypto_config, session); + } + const ProofVerifyDetailsChromium* proof_verify_details = nullptr; if (!proof_verify_details_queue_.empty()) { proof_verify_details = proof_verify_details_queue_.front(); diff --git a/chromium/net/quic/chromium/mock_network_change_notifier.cc b/chromium/net/quic/chromium/mock_network_change_notifier.cc index e72ba2501cf..86326e2107d 100644 --- a/chromium/net/quic/chromium/mock_network_change_notifier.cc +++ b/chromium/net/quic/chromium/mock_network_change_notifier.cc @@ -10,12 +10,13 @@ namespace net { namespace test { MockNetworkChangeNotifier::MockNetworkChangeNotifier() - : force_network_handles_supported_(false) {} + : force_network_handles_supported_(false), + connection_type_(CONNECTION_UNKNOWN) {} MockNetworkChangeNotifier::~MockNetworkChangeNotifier() {} MockNetworkChangeNotifier::ConnectionType MockNetworkChangeNotifier::GetCurrentConnectionType() const { - return CONNECTION_UNKNOWN; + return connection_type_; } void MockNetworkChangeNotifier::ForceNetworkHandlesSupported() { diff --git a/chromium/net/quic/chromium/mock_network_change_notifier.h b/chromium/net/quic/chromium/mock_network_change_notifier.h index d81b4efa905..7a4511c92ab 100644 --- a/chromium/net/quic/chromium/mock_network_change_notifier.h +++ b/chromium/net/quic/chromium/mock_network_change_notifier.h @@ -21,6 +21,10 @@ class MockNetworkChangeNotifier : public NetworkChangeNotifier { bool AreNetworkHandlesCurrentlySupported() const override; + void SetConnectionType(ConnectionType connection_type) { + connection_type_ = connection_type; + } + void SetConnectedNetworksList(const NetworkList& network_list); void GetCurrentConnectedNetworks(NetworkList* network_list) const override; @@ -44,6 +48,7 @@ class MockNetworkChangeNotifier : public NetworkChangeNotifier { private: bool force_network_handles_supported_; + ConnectionType connection_type_; NetworkChangeNotifier::NetworkList connected_networks_; }; diff --git a/chromium/net/quic/chromium/network_connection.cc b/chromium/net/quic/chromium/network_connection.cc index 6bfed05df54..63e0a5271a7 100644 --- a/chromium/net/quic/chromium/network_connection.cc +++ b/chromium/net/quic/chromium/network_connection.cc @@ -10,66 +10,62 @@ namespace net { NetworkConnection::NetworkConnection() : connection_type_(NetworkChangeNotifier::CONNECTION_UNKNOWN), - connection_description_(nullptr) {} - -const char* NetworkConnection::GetDescription() { - NetworkChangeNotifier::ConnectionType type = - NetworkChangeNotifier::GetConnectionType(); - if (connection_description_ != nullptr && type == connection_type_) - return connection_description_; - - DVLOG(1) << "Updating NetworkConnection's Cached Data"; - - connection_description_ = NetworkChangeNotifier::ConnectionTypeToString(type); - connection_type_ = type; - if (connection_type_ == NetworkChangeNotifier::CONNECTION_UNKNOWN || - connection_type_ == NetworkChangeNotifier::CONNECTION_WIFI) { - // This function only seems usefully defined on Windows currently. - WifiPHYLayerProtocol wifi_type = GetWifiPHYLayerProtocol(); - switch (wifi_type) { - case WIFI_PHY_LAYER_PROTOCOL_NONE: - // No wifi support or no associated AP. - break; - case WIFI_PHY_LAYER_PROTOCOL_ANCIENT: - // An obsolete modes introduced by the original 802.11, e.g. IR, FHSS. - connection_description_ = "CONNECTION_WIFI_ANCIENT"; - break; - case WIFI_PHY_LAYER_PROTOCOL_A: - // 802.11a, OFDM-based rates. - connection_description_ = "CONNECTION_WIFI_802.11a"; - break; - case WIFI_PHY_LAYER_PROTOCOL_B: - // 802.11b, DSSS or HR DSSS. - connection_description_ = "CONNECTION_WIFI_802.11b"; - break; - case WIFI_PHY_LAYER_PROTOCOL_G: - // 802.11g, same rates as 802.11a but compatible with 802.11b. - connection_description_ = "CONNECTION_WIFI_802.11g"; - break; - case WIFI_PHY_LAYER_PROTOCOL_N: - // 802.11n, HT rates. - connection_description_ = "CONNECTION_WIFI_802.11n"; - break; - case WIFI_PHY_LAYER_PROTOCOL_UNKNOWN: - // Unclassified mode or failure to identify. - break; - } - } - return connection_description_; + connection_description_(nullptr) { + NetworkChangeNotifier::AddIPAddressObserver(this); + NetworkChangeNotifier::AddConnectionTypeObserver(this); + OnIPAddressChanged(); } -void NetworkConnection::Clear() { - connection_type_ = NetworkChangeNotifier::CONNECTION_UNKNOWN; - connection_description_ = nullptr; +NetworkConnection::~NetworkConnection() { + NetworkChangeNotifier::RemoveConnectionTypeObserver(this); + NetworkChangeNotifier::RemoveIPAddressObserver(this); } void NetworkConnection::OnIPAddressChanged() { - Clear(); + OnConnectionTypeChanged(NetworkChangeNotifier::GetConnectionType()); } void NetworkConnection::OnConnectionTypeChanged( NetworkChangeNotifier::ConnectionType type) { - Clear(); + DVLOG(1) << "Updating NetworkConnection's Cached Data"; + + connection_type_ = type; + connection_description_ = NetworkChangeNotifier::ConnectionTypeToString(type); + if (connection_type_ != NetworkChangeNotifier::CONNECTION_UNKNOWN && + connection_type_ != NetworkChangeNotifier::CONNECTION_WIFI) { + return; + } + + // This function only seems usefully defined on Windows currently. + WifiPHYLayerProtocol wifi_type = GetWifiPHYLayerProtocol(); + switch (wifi_type) { + case WIFI_PHY_LAYER_PROTOCOL_NONE: + // No wifi support or no associated AP. + break; + case WIFI_PHY_LAYER_PROTOCOL_ANCIENT: + // An obsolete modes introduced by the original 802.11, e.g. IR, FHSS. + connection_description_ = "CONNECTION_WIFI_ANCIENT"; + break; + case WIFI_PHY_LAYER_PROTOCOL_A: + // 802.11a, OFDM-based rates. + connection_description_ = "CONNECTION_WIFI_802.11a"; + break; + case WIFI_PHY_LAYER_PROTOCOL_B: + // 802.11b, DSSS or HR DSSS. + connection_description_ = "CONNECTION_WIFI_802.11b"; + break; + case WIFI_PHY_LAYER_PROTOCOL_G: + // 802.11g, same rates as 802.11a but compatible with 802.11b. + connection_description_ = "CONNECTION_WIFI_802.11g"; + break; + case WIFI_PHY_LAYER_PROTOCOL_N: + // 802.11n, HT rates. + connection_description_ = "CONNECTION_WIFI_802.11n"; + break; + case WIFI_PHY_LAYER_PROTOCOL_UNKNOWN: + // Unclassified mode or failure to identify. + break; + } } } // namespace net diff --git a/chromium/net/quic/chromium/network_connection.h b/chromium/net/quic/chromium/network_connection.h index e9c64d2649a..f1407d8d3e7 100644 --- a/chromium/net/quic/chromium/network_connection.h +++ b/chromium/net/quic/chromium/network_connection.h @@ -11,18 +11,19 @@ namespace net { -namespace test { -class NetworkConnectionPeer; -} // namespace test - -// This class returns the current network's connection description. It also -// cache's the connection description to fix crbug.com/422516. +// This class stores information about the current network type and +// provides a textual description of it. class NET_EXPORT NetworkConnection : public NetworkChangeNotifier::IPAddressObserver, public NetworkChangeNotifier::ConnectionTypeObserver { public: NetworkConnection(); - ~NetworkConnection() override {} + ~NetworkConnection() override; + + // Returns the underlying connection type. + NetworkChangeNotifier::ConnectionType connection_type() { + return connection_type_; + } // Return a string equivalent of current connection type. Callers don't need // to make a copy of the returned C-string value. If the connection type is @@ -33,10 +34,7 @@ class NET_EXPORT NetworkConnection // don't distinguish Wifi vs Etherenet, and call everything CONNECTION_UNKNOWN // :-(. Fo non CONNECTIION_WIFI, this returns the C-string returned by // NetworkChangeNotifier::ConnectionTypeToString. - const char* GetDescription(); - - // It clears the cached connection_type_ and connection_description_. - void Clear(); + const char* connection_description() { return connection_description_; } // NetworkChangeNotifier::IPAddressObserver methods: void OnIPAddressChanged() override; @@ -46,11 +44,11 @@ class NET_EXPORT NetworkConnection NetworkChangeNotifier::ConnectionType type) override; private: - friend class test::NetworkConnectionPeer; - - // Cache the connection_type and the connection description string to avoid - // calling expensive GetWifiPHYLayerProtocol() function. + // Cache the connection type to avoid calling the potentially expensive + // NetworkChangeNotifier::GetConnectionType() function. NetworkChangeNotifier::ConnectionType connection_type_; + // Cache the connection description string to avoid calling the expensive + // GetWifiPHYLayerProtocol() function. const char* connection_description_; DISALLOW_COPY_AND_ASSIGN(NetworkConnection); diff --git a/chromium/net/quic/chromium/network_connection_unittest.cc b/chromium/net/quic/chromium/network_connection_unittest.cc index 6b0ec3a81e4..f9372a18f0a 100644 --- a/chromium/net/quic/chromium/network_connection_unittest.cc +++ b/chromium/net/quic/chromium/network_connection_unittest.cc @@ -4,76 +4,98 @@ #include "net/quic/chromium/network_connection.h" +#include "base/run_loop.h" +#include "net/quic/chromium/mock_network_change_notifier.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { namespace test { -class NetworkConnectionPeer { - public: - static NetworkChangeNotifier::ConnectionType connection_type( - const NetworkConnection& network_connection) { - return network_connection.connection_type_; - } - static void set_connection_type(NetworkConnection* network_connection, - NetworkChangeNotifier::ConnectionType type) { - network_connection->connection_type_ = type; - } - - static const char* connection_description( - const NetworkConnection& network_connection) { - return network_connection.connection_description_; - } - static void set_connection_description(NetworkConnection* network_connection, - const char* description) { - network_connection->connection_description_ = description; - } -}; +constexpr auto CONNECTION_3G = NetworkChangeNotifier::CONNECTION_3G; +constexpr auto CONNECTION_2G = NetworkChangeNotifier::CONNECTION_2G; +constexpr auto CONNECTION_ETHERNET = NetworkChangeNotifier::CONNECTION_ETHERNET; +constexpr auto CONNECTION_WIFI = NetworkChangeNotifier::CONNECTION_WIFI; -// Test NetworkConnection(). class NetworkConnectionTest : public testing::Test { protected: - void CheckNetworkConnectionDescription() { - NetworkChangeNotifier::ConnectionType type = - NetworkChangeNotifier::GetConnectionType(); - const char* description = network_connection_.GetDescription(); - // Verify GetDescription() updated the cached data. - EXPECT_EQ(NetworkConnectionPeer::connection_type(network_connection_), - type); - EXPECT_EQ( - NetworkConnectionPeer::connection_description(network_connection_), - description); - - if (type != NetworkChangeNotifier::CONNECTION_WIFI) - EXPECT_EQ(description, - NetworkChangeNotifier::ConnectionTypeToString(type)); - else - EXPECT_NE(nullptr, network_connection_.GetDescription()); - } - - NetworkConnection network_connection_; + NetworkConnectionTest() + : notifier_(scoped_notifier_.mock_network_change_notifier()) {} + + ScopedMockNetworkChangeNotifier scoped_notifier_; + MockNetworkChangeNotifier* notifier_; }; -TEST_F(NetworkConnectionTest, GetDescription) { - const char* description = network_connection_.GetDescription(); +TEST_F(NetworkConnectionTest, Connection2G) { + notifier_->SetConnectionType(CONNECTION_2G); - // Set connection description to nullptr. - NetworkConnectionPeer::set_connection_description(&network_connection_, - nullptr); - CheckNetworkConnectionDescription(); + NetworkConnection network_connection; + EXPECT_EQ(CONNECTION_2G, network_connection.connection_type()); + const char* description = network_connection.connection_description(); + EXPECT_EQ(NetworkChangeNotifier::ConnectionTypeToString(CONNECTION_2G), + description); +} - // Set connection type to a junk value. - NetworkConnectionPeer::set_connection_type( - &network_connection_, NetworkChangeNotifier::CONNECTION_LAST); - CheckNetworkConnectionDescription(); +TEST_F(NetworkConnectionTest, Connection3G) { + notifier_->SetConnectionType(CONNECTION_3G); - EXPECT_EQ(description, network_connection_.GetDescription()); + NetworkConnection network_connection; + EXPECT_EQ(CONNECTION_3G, network_connection.connection_type()); + const char* description = network_connection.connection_description(); + EXPECT_EQ(NetworkChangeNotifier::ConnectionTypeToString(CONNECTION_3G), + description); } -TEST_F(NetworkConnectionTest, Clear) { - CheckNetworkConnectionDescription(); - network_connection_.Clear(); - CheckNetworkConnectionDescription(); +TEST_F(NetworkConnectionTest, ConnectionEthnernet) { + notifier_->SetConnectionType(CONNECTION_ETHERNET); + + NetworkConnection network_connection; + EXPECT_EQ(CONNECTION_ETHERNET, network_connection.connection_type()); + const char* description = network_connection.connection_description(); + EXPECT_EQ(NetworkChangeNotifier::ConnectionTypeToString(CONNECTION_ETHERNET), + description); +} + +TEST_F(NetworkConnectionTest, ConnectionWifi) { + notifier_->SetConnectionType(CONNECTION_WIFI); + + NetworkConnection network_connection; + EXPECT_EQ(CONNECTION_WIFI, network_connection.connection_type()); + const char* description = network_connection.connection_description(); + // On some platforms, the description for wifi will be more detailed + // than what is returned by NetworkChangeNotifier::ConnectionTypeToString. + EXPECT_NE(nullptr, description); +} + +TEST_F(NetworkConnectionTest, ConnectionChange) { + notifier_->SetConnectionType(CONNECTION_2G); + + NetworkConnection network_connection; + const char* description_2g = network_connection.connection_description(); + + notifier_->SetConnectionType(CONNECTION_3G); + NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); + // Spin the message loop so the notification is delivered. + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(CONNECTION_3G, network_connection.connection_type()); + const char* description_3g = network_connection.connection_description(); + + NetworkChangeNotifier::NotifyObserversOfConnectionTypeChangeForTests( + CONNECTION_ETHERNET); + // Spin the message loop so the notification is delivered. + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(CONNECTION_ETHERNET, network_connection.connection_type()); + const char* description_ethernet = + network_connection.connection_description(); + + NetworkChangeNotifier::NotifyObserversOfConnectionTypeChangeForTests( + CONNECTION_WIFI); + EXPECT_NE(nullptr, network_connection.connection_description()); + EXPECT_EQ(NetworkChangeNotifier::ConnectionTypeToString(CONNECTION_2G), + description_2g); + EXPECT_EQ(NetworkChangeNotifier::ConnectionTypeToString(CONNECTION_3G), + description_3g); + EXPECT_EQ(NetworkChangeNotifier::ConnectionTypeToString(CONNECTION_ETHERNET), + description_ethernet); } } // namespace test diff --git a/chromium/net/quic/chromium/properties_based_quic_server_info.cc b/chromium/net/quic/chromium/properties_based_quic_server_info.cc index 38814545bb1..efe6f84672f 100644 --- a/chromium/net/quic/chromium/properties_based_quic_server_info.cc +++ b/chromium/net/quic/chromium/properties_based_quic_server_info.cc @@ -5,6 +5,7 @@ #include "net/quic/chromium/properties_based_quic_server_info.h" #include "base/base64.h" +#include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" #include "net/base/net_errors.h" #include "net/http/http_server_properties.h" @@ -99,9 +100,11 @@ PropertiesBasedQuicServerInfoFactory::PropertiesBasedQuicServerInfoFactory( PropertiesBasedQuicServerInfoFactory::~PropertiesBasedQuicServerInfoFactory() {} -QuicServerInfo* PropertiesBasedQuicServerInfoFactory::GetForServer( +std::unique_ptr<QuicServerInfo> +PropertiesBasedQuicServerInfoFactory::GetForServer( const QuicServerId& server_id) { - return new PropertiesBasedQuicServerInfo(server_id, http_server_properties_); + return base::MakeUnique<PropertiesBasedQuicServerInfo>( + server_id, http_server_properties_); } } // namespace net diff --git a/chromium/net/quic/chromium/properties_based_quic_server_info.h b/chromium/net/quic/chromium/properties_based_quic_server_info.h index 6fe9f78da6c..c9b0075a355 100644 --- a/chromium/net/quic/chromium/properties_based_quic_server_info.h +++ b/chromium/net/quic/chromium/properties_based_quic_server_info.h @@ -5,6 +5,7 @@ #ifndef NET_QUIC_CHROMIUM_PROPERTIES_BASED_QUIC_SERVER_INFO_H_ #define NET_QUIC_CHROMIUM_PROPERTIES_BASED_QUIC_SERVER_INFO_H_ +#include <memory> #include <string> #include <vector> @@ -51,7 +52,8 @@ class QUIC_EXPORT_PRIVATE PropertiesBasedQuicServerInfoFactory HttpServerProperties* http_server_properties); ~PropertiesBasedQuicServerInfoFactory() override; - QuicServerInfo* GetForServer(const QuicServerId& server_id) override; + std::unique_ptr<QuicServerInfo> GetForServer( + const QuicServerId& server_id) override; private: HttpServerProperties* http_server_properties_; diff --git a/chromium/net/quic/chromium/quic_chromium_client_session.cc b/chromium/net/quic/chromium/quic_chromium_client_session.cc index 96a8eea48f3..816094abb9f 100644 --- a/chromium/net/quic/chromium/quic_chromium_client_session.cc +++ b/chromium/net/quic/chromium/quic_chromium_client_session.cc @@ -15,6 +15,7 @@ #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/threading/thread_task_runner_handle.h" +#include "base/trace_event/memory_usage_estimator.h" #include "base/values.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" @@ -176,7 +177,7 @@ class QuicServerPushHelper : public ServerPushDelegate::ServerPushHelper { } } - const GURL& GetURL() override { return request_url_; } + const GURL& GetURL() const override { return request_url_; } private: base::WeakPtr<QuicChromiumClientSession> session_; @@ -234,6 +235,7 @@ QuicChromiumClientSession::QuicChromiumClientSession( TransportSecurityState* transport_security_state, std::unique_ptr<QuicServerInfo> server_info, const QuicServerId& server_id, + bool require_confirmation, int yield_after_packets, QuicTime::Delta yield_after_duration, int cert_verify_flags, @@ -249,7 +251,7 @@ QuicChromiumClientSession::QuicChromiumClientSession( NetLog* net_log) : QuicClientSessionBase(connection, push_promise_index, config), server_id_(server_id), - require_confirmation_(false), + require_confirmation_(require_confirmation), stream_factory_(stream_factory), transport_security_state_(transport_security_state), server_info_(std::move(server_info)), @@ -662,14 +664,17 @@ Error QuicChromiumClientSession::GetTokenBindingSignature( } int QuicChromiumClientSession::CryptoConnect( - bool require_confirmation, const CompletionCallback& callback) { - require_confirmation_ = require_confirmation; connect_timing_.connect_start = base::TimeTicks::Now(); RecordHandshakeState(STATE_STARTED); DCHECK(flow_controller()); crypto_stream_->CryptoConnect(); + // Check if the connection is still open, issues during CryptoConnect like + // packet write error could cause the connection to be torn down. + if (!connection()->connected()) + return ERR_QUIC_HANDSHAKE_FAILED; + if (IsCryptoHandshakeConfirmed()) { connect_timing_.connect_end = base::TimeTicks::Now(); return OK; @@ -1317,7 +1322,6 @@ std::unique_ptr<base::Value> QuicChromiumClientSession::GetInfoAsValue( dict->SetInteger("packets_received", stats.packets_received); dict->SetInteger("packets_lost", stats.packets_lost); SSLInfo ssl_info; - dict->SetBoolean("secure", GetSSLInfo(&ssl_info) && ssl_info.cert.get()); std::unique_ptr<base::ListValue> alias_list(new base::ListValue()); for (std::set<HostPortPair>::const_iterator it = aliases.begin(); @@ -1466,7 +1470,8 @@ bool QuicChromiumClientSession::HandlePromised(QuicStreamId id, GURL pushed_url = GetUrlFromHeaderBlock(headers); if (push_delegate_) { push_delegate_->OnPush(base::MakeUnique<QuicServerPushHelper>( - weak_factory_.GetWeakPtr(), pushed_url)); + weak_factory_.GetWeakPtr(), pushed_url), + net_log_); } } net_log_.AddEvent(NetLogEventType::QUIC_SESSION_PUSH_PROMISE_RECEIVED, @@ -1519,4 +1524,11 @@ QuicVersion QuicChromiumClientSession::GetQuicVersion() const { return connection()->version(); } +size_t QuicChromiumClientSession::EstimateMemoryUsage() const { + // TODO(xunjieli): Estimate |crypto_stream_|, QuicSpdySession's + // QuicHeaderList, QuicSession's QuiCWriteBlockedList, open streams and + // unacked packet map. + return base::trace_event::EstimateMemoryUsage(packet_readers_); +} + } // namespace net diff --git a/chromium/net/quic/chromium/quic_chromium_client_session.h b/chromium/net/quic/chromium/quic_chromium_client_session.h index 1276e55a273..7d9a87bb1e7 100644 --- a/chromium/net/quic/chromium/quic_chromium_client_session.h +++ b/chromium/net/quic/chromium/quic_chromium_client_session.h @@ -126,6 +126,7 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession TransportSecurityState* transport_security_state, std::unique_ptr<QuicServerInfo> server_info, const QuicServerId& server_id, + bool require_confirmation, int yield_after_packets, QuicTime::Delta yield_after_duration, int cert_verify_flags, @@ -213,8 +214,7 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession std::vector<uint8_t>* out) override; // Performs a crypto handshake with the server. - int CryptoConnect(bool require_confirmation, - const CompletionCallback& callback); + int CryptoConnect(const CompletionCallback& callback); // Resumes a crypto handshake with the server after a timeout. int ResumeCryptoConnect(const CompletionCallback& callback); @@ -317,6 +317,11 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession QuicVersion GetQuicVersion() const; + // Returns the estimate of dynamically allocated memory in bytes. + // See base/trace_event/memory_usage_estimator.h. + // TODO(xunjieli): It only tracks |packet_readers_|. Write a better estimate. + size_t EstimateMemoryUsage() const; + protected: // QuicSession methods: bool ShouldCreateIncomingDynamicStream(QuicStreamId id) override; diff --git a/chromium/net/quic/chromium/quic_chromium_client_session_test.cc b/chromium/net/quic/chromium/quic_chromium_client_session_test.cc index 77f6400ebb3..8d75a510fbe 100644 --- a/chromium/net/quic/chromium/quic_chromium_client_session_test.cc +++ b/chromium/net/quic/chromium/quic_chromium_client_session_test.cc @@ -82,7 +82,7 @@ class QuicChromiumClientSessionTest : public ::testing::TestWithParam<QuicVersion> { protected: QuicChromiumClientSessionTest() - : crypto_config_(CryptoTestUtils::ProofVerifierForTesting()), + : crypto_config_(crypto_test_utils::ProofVerifierForTesting()), default_read_(new MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)), socket_data_( new SequencedSocketData(default_read_.get(), 1, nullptr, 0)), @@ -121,7 +121,7 @@ class QuicChromiumClientSessionTest &transport_security_state_, base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)), QuicServerId(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED), - kQuicYieldAfterPacketsRead, + /*require_confirmation=*/false, kQuicYieldAfterPacketsRead, QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds), /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN", base::TimeTicks::Now(), base::TimeTicks::Now(), @@ -143,7 +143,7 @@ class QuicChromiumClientSessionTest } void CompleteCryptoHandshake() { - ASSERT_THAT(session_->CryptoConnect(false, callback_.callback()), IsOk()); + ASSERT_THAT(session_->CryptoConnect(callback_.callback()), IsOk()); } QuicChromiumPacketWriter* CreateQuicChromiumPacketWriter( diff --git a/chromium/net/quic/chromium/quic_chromium_client_stream.cc b/chromium/net/quic/chromium/quic_chromium_client_stream.cc index 0bf3d2146ff..de95b4930e5 100644 --- a/chromium/net/quic/chromium/quic_chromium_client_stream.cc +++ b/chromium/net/quic/chromium/quic_chromium_client_stream.cc @@ -185,14 +185,15 @@ void QuicChromiumClientStream::SetDelegate( QuicChromiumClientStream::Delegate* delegate) { DCHECK(!(delegate_ && delegate)); delegate_ = delegate; + if (delegate == nullptr) { + DCHECK(delegate_tasks_.empty()); + return; + } while (!delegate_tasks_.empty()) { base::Closure closure = delegate_tasks_.front(); delegate_tasks_.pop_front(); closure.Run(); } - if (delegate == nullptr && sequencer()->IsClosed()) { - OnFinRead(); - } } void QuicChromiumClientStream::OnError(int error) { diff --git a/chromium/net/quic/chromium/quic_chromium_client_stream.h b/chromium/net/quic/chromium/quic_chromium_client_stream.h index 01afae71e1e..9facd0cd0e7 100644 --- a/chromium/net/quic/chromium/quic_chromium_client_stream.h +++ b/chromium/net/quic/chromium/quic_chromium_client_stream.h @@ -125,6 +125,7 @@ class NET_EXPORT_PRIVATE QuicChromiumClientStream : public QuicSpdyStream { bool IsFirstStream(); using QuicSpdyStream::HasBufferedData; + using QuicStream::sequencer; private: void NotifyDelegateOfHeadersCompleteLater(SpdyHeaderBlock headers, diff --git a/chromium/net/quic/chromium/quic_chromium_client_stream_test.cc b/chromium/net/quic/chromium/quic_chromium_client_stream_test.cc index 03be8e877c9..9dc3210005d 100644 --- a/chromium/net/quic/chromium/quic_chromium_client_stream_test.cc +++ b/chromium/net/quic/chromium/quic_chromium_client_stream_test.cc @@ -168,7 +168,7 @@ class QuicChromiumClientStreamTest : public ::testing::TestWithParam<QuicVersion> { public: QuicChromiumClientStreamTest() - : crypto_config_(CryptoTestUtils::ProofVerifierForTesting()), + : crypto_config_(crypto_test_utils::ProofVerifierForTesting()), session_(new MockQuicConnection(&helper_, &alarm_factory_, Perspective::IS_CLIENT, diff --git a/chromium/net/quic/chromium/quic_chromium_packet_reader.cc b/chromium/net/quic/chromium/quic_chromium_packet_reader.cc index 20645fc0788..c151a0eb1d2 100644 --- a/chromium/net/quic/chromium/quic_chromium_packet_reader.cc +++ b/chromium/net/quic/chromium/quic_chromium_packet_reader.cc @@ -66,6 +66,11 @@ void QuicChromiumPacketReader::StartReading() { } } +size_t QuicChromiumPacketReader::EstimateMemoryUsage() const { + // Return the size of |read_buffer_|. + return kMaxPacketSize; +} + void QuicChromiumPacketReader::OnReadComplete(int result) { read_pending_ = false; if (result == 0) diff --git a/chromium/net/quic/chromium/quic_chromium_packet_reader.h b/chromium/net/quic/chromium/quic_chromium_packet_reader.h index a58c623ba9a..14dca1a1160 100644 --- a/chromium/net/quic/chromium/quic_chromium_packet_reader.h +++ b/chromium/net/quic/chromium/quic_chromium_packet_reader.h @@ -49,6 +49,9 @@ class NET_EXPORT_PRIVATE QuicChromiumPacketReader { // and passing the data along to the QuicConnection. void StartReading(); + // Returns the estimate of dynamically allocated memory in bytes. + size_t EstimateMemoryUsage() const; + private: // A completion callback invoked when a read completes. void OnReadComplete(int result); diff --git a/chromium/net/quic/chromium/quic_connection_logger.cc b/chromium/net/quic/chromium/quic_connection_logger.cc index 2bfd9eb0fd7..27128a3a0a0 100644 --- a/chromium/net/quic/chromium/quic_connection_logger.cc +++ b/chromium/net/quic/chromium/quic_connection_logger.cc @@ -411,7 +411,6 @@ void QuicConnectionLogger::OnFrameAddedToPacket(const QuicFrame& frame) { void QuicConnectionLogger::OnPacketSent( const SerializedPacket& serialized_packet, - QuicPathId /* original_path_id */, QuicPacketNumber original_packet_number, TransmissionType transmission_type, QuicTime sent_time) { diff --git a/chromium/net/quic/chromium/quic_connection_logger.h b/chromium/net/quic/chromium/quic_connection_logger.h index 8d71147d530..3b18d252e51 100644 --- a/chromium/net/quic/chromium/quic_connection_logger.h +++ b/chromium/net/quic/chromium/quic_connection_logger.h @@ -46,7 +46,6 @@ class NET_EXPORT_PRIVATE QuicConnectionLogger // QuicConnectionDebugVisitorInterface void OnPacketSent(const SerializedPacket& serialized_packet, - QuicPathId original_path_id, QuicPacketNumber original_packet_number, TransmissionType transmission_type, QuicTime sent_time) override; diff --git a/chromium/net/quic/chromium/quic_end_to_end_unittest.cc b/chromium/net/quic/chromium/quic_end_to_end_unittest.cc index 0df6b3cd8d1..30e89f18ee5 100644 --- a/chromium/net/quic/chromium/quic_end_to_end_unittest.cc +++ b/chromium/net/quic/chromium/quic_end_to_end_unittest.cc @@ -9,9 +9,10 @@ #include "base/compiler_specific.h" #include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" -#include "base/threading/thread_task_runner_handle.h" +#include "base/test/scoped_task_scheduler.h" #include "net/base/elements_upload_data_stream.h" #include "net/base/ip_address.h" #include "net/base/test_completion_callback.h" @@ -126,8 +127,7 @@ class QuicEndToEndTest : public ::testing::TestWithParam<TestParams> { params_.http_auth_handler_factory = auth_handler_factory_.get(); params_.http_server_properties = &http_server_properties_; channel_id_service_.reset( - new ChannelIDService(new DefaultChannelIDStore(nullptr), - base::ThreadTaskRunnerHandle::Get())); + new ChannelIDService(new DefaultChannelIDStore(nullptr))); params_.channel_id_service = channel_id_service_.get(); CertVerifyResult verify_result; @@ -179,7 +179,7 @@ class QuicEndToEndTest : public ::testing::TestWithParam<TestParams> { kInitialSessionFlowControlWindowForTest); server_config_options_.token_binding_params = QuicTagVector{kTB10, kP256}; server_.reset(new QuicSimpleServer( - CryptoTestUtils::ProofSourceForTesting(), server_config_, + crypto_test_utils::ProofSourceForTesting(), server_config_, server_config_options_, AllSupportedVersions(), &response_cache_)); server_->Listen(server_address_); server_address_ = server_->server_address(); @@ -278,6 +278,10 @@ TEST_P(QuicEndToEndTest, LargeGetWithNoPacketLoss) { } TEST_P(QuicEndToEndTest, TokenBinding) { + // Required by ChannelIDService. + base::test::ScopedTaskScheduler scoped_task_scheduler( + base::MessageLoop::current()); + // Enable token binding and re-initialize the TestTransactionFactory. params_.enable_token_binding = true; transaction_factory_.reset(new TestTransactionFactory(params_)); diff --git a/chromium/net/quic/chromium/quic_http_stream.cc b/chromium/net/quic/chromium/quic_http_stream.cc index ef48ef66a90..f824b464414 100644 --- a/chromium/net/quic/chromium/quic_http_stream.cc +++ b/chromium/net/quic/chromium/quic_http_stream.cc @@ -19,6 +19,7 @@ #include "net/log/net_log_source.h" #include "net/quic/chromium/quic_http_utils.h" #include "net/quic/core/quic_client_promised_info.h" +#include "net/quic/core/quic_stream_sequencer.h" #include "net/quic/core/quic_utils.h" #include "net/quic/core/spdy_utils.h" #include "net/spdy/spdy_frame_builder.h" @@ -142,6 +143,8 @@ HttpResponseInfo::ConnectionInfo QuicHttpStream::ConnectionInfoFromQuicVersion( return HttpResponseInfo::CONNECTION_INFO_QUIC_36; case QUIC_VERSION_37: return HttpResponseInfo::CONNECTION_INFO_QUIC_37; + case QUIC_VERSION_38: + return HttpResponseInfo::CONNECTION_INFO_QUIC_38; } NOTREACHED(); return HttpResponseInfo::CONNECTION_INFO_QUIC_UNKNOWN_VERSION; @@ -374,7 +377,10 @@ int64_t QuicHttpStream::GetTotalReceivedBytes() const { // bytes. Change this to include QUIC overhead as well. int64_t total_received_bytes = headers_bytes_received_; if (stream_) { - total_received_bytes += stream_->stream_bytes_read(); + DCHECK_LE(stream_->sequencer()->NumBytesConsumed(), + stream_->stream_bytes_read()); + // Only count the uniquely received bytes. + total_received_bytes += stream_->sequencer()->NumBytesConsumed(); } else { total_received_bytes += closed_stream_received_bytes_; } @@ -810,7 +816,10 @@ void QuicHttpStream::ResetStream() { } if (!stream_) return; - closed_stream_received_bytes_ = stream_->stream_bytes_read(); + DCHECK_LE(stream_->sequencer()->NumBytesConsumed(), + stream_->stream_bytes_read()); + // Only count the uniquely received bytes. + closed_stream_received_bytes_ = stream_->sequencer()->NumBytesConsumed(); closed_stream_sent_bytes_ = stream_->stream_bytes_written(); closed_is_first_stream_ = stream_->IsFirstStream(); stream_ = nullptr; diff --git a/chromium/net/quic/chromium/quic_http_stream.h b/chromium/net/quic/chromium/quic_http_stream.h index 29365a47bb1..3dd49821917 100644 --- a/chromium/net/quic/chromium/quic_http_stream.h +++ b/chromium/net/quic/chromium/quic_http_stream.h @@ -170,9 +170,6 @@ class NET_EXPORT_PRIVATE QuicHttpStream bool response_headers_received_; - // Serialized HTTP request. - std::string request_; - // Number of bytes received by the headers stream on behalf of this stream. int64_t headers_bytes_received_; // Number of bytes sent by the headers stream on behalf of this stream. diff --git a/chromium/net/quic/chromium/quic_http_stream_test.cc b/chromium/net/quic/chromium/quic_http_stream_test.cc index 6f4e4ec25bc..ee849314890 100644 --- a/chromium/net/quic/chromium/quic_http_stream_test.cc +++ b/chromium/net/quic/chromium/quic_http_stream_test.cc @@ -202,7 +202,7 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> { QuicHttpStreamTest() : use_closing_stream_(false), - crypto_config_(CryptoTestUtils::ProofVerifierForTesting()), + crypto_config_(crypto_test_utils::ProofVerifierForTesting()), read_buffer_(new IOBufferWithSize(4096)), promise_id_(kServerDataStreamId1), stream_id_(kClientDataStreamId1), @@ -317,7 +317,7 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> { base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)), QuicServerId(kDefaultServerHostName, kDefaultServerPort, PRIVACY_MODE_DISABLED), - kQuicYieldAfterPacketsRead, + /*require_confirmation=*/false, kQuicYieldAfterPacketsRead, QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds), /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN", dns_start, dns_end, &push_promise_index_, nullptr, @@ -325,8 +325,7 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> { /*socket_performance_watcher=*/nullptr, net_log_.bound().net_log())); session_->Initialize(); TestCompletionCallback callback; - session_->CryptoConnect(/*require_confirmation=*/false, - callback.callback()); + session_->CryptoConnect(callback.callback()); EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed()); stream_.reset(use_closing_stream_ ? new AutoClosingStream(session_->GetWeakPtr()) diff --git a/chromium/net/quic/chromium/quic_network_transaction_unittest.cc b/chromium/net/quic/chromium/quic_network_transaction_unittest.cc index fe8e2bc8aae..3dae6738334 100644 --- a/chromium/net/quic/chromium/quic_network_transaction_unittest.cc +++ b/chromium/net/quic/chromium/quic_network_transaction_unittest.cc @@ -507,6 +507,7 @@ class QuicNetworkTransactionTest params_.http_auth_handler_factory = auth_handler_factory_.get(); params_.http_server_properties = &http_server_properties_; params_.quic_supported_versions = SupportedVersions(version_); + params_.net_log = net_log_.bound().net_log(); for (const char* host : {kDefaultServerHostName, "www.example.org", "news.example.org", "bar.example.org", "foo.example.org", "invalid.example.org", @@ -990,9 +991,8 @@ TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) { ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem")); ASSERT_TRUE(cert.get()); // This certificate is valid for the proxy, but not for the origin. - bool common_name_fallback_used; - EXPECT_TRUE(cert->VerifyNameMatch(proxy_host, &common_name_fallback_used)); - EXPECT_FALSE(cert->VerifyNameMatch(origin_host, &common_name_fallback_used)); + EXPECT_TRUE(cert->VerifyNameMatch(proxy_host, false)); + EXPECT_FALSE(cert->VerifyNameMatch(origin_host, false)); ProofVerifyDetailsChromium verify_details; verify_details.cert_verify_result.verified_cert = cert; crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); @@ -1017,10 +1017,9 @@ TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) { ASSERT_TRUE(cert.get()); // TODO(rch): the connection should be "to" the origin, so if the cert is // valid for the origin but not the alternative, that should work too. - bool common_name_fallback_used; - EXPECT_TRUE(cert->VerifyNameMatch(origin.host(), &common_name_fallback_used)); + EXPECT_TRUE(cert->VerifyNameMatch(origin.host(), false)); EXPECT_TRUE( - cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used)); + cert->VerifyNameMatch(alternative.host(), false)); ProofVerifyDetailsChromium verify_details; verify_details.cert_verify_result.verified_cert = cert; crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); @@ -2190,7 +2189,7 @@ TEST_P(QuicNetworkTransactionTest, ConstructServerRstPacket(1, false, 99, QUIC_STREAM_LAST_ERROR)); std::string quic_error_details = "Data for nonexistent stream"; mock_quic_data.AddWrite(ConstructClientAckAndConnectionClosePacket( - 3, QuicTime::Delta::Infinite(), 0, 1, QUIC_INVALID_STREAM_ID, + 3, QuicTime::Delta::Zero(), 1, 1, QUIC_INVALID_STREAM_ID, quic_error_details)); mock_quic_data.AddSocketDataToFactory(&socket_factory_); @@ -2498,8 +2497,7 @@ TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) { TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) { // Alternate-protocol job will fail before creating a QUIC session. StaticSocketDataProvider quic_data(nullptr, 0, nullptr, 0); - quic_data.set_connect_data( - MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED)); + quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED)); socket_factory_.AddSocketDataProvider(&quic_data); // Main job which will succeed even though the alternate job fails. @@ -2664,7 +2662,10 @@ TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) { test_socket_performance_watcher_factory_.rtt_notification_received()); } -TEST_P(QuicNetworkTransactionTest, QuicUploadToAlternativeProxyServer) { +// TODO(zhongyi): disabled this broken test as it was not testing the correct +// code path. Need a fix to re-enable this test, tracking at crbug.com/704596. +TEST_P(QuicNetworkTransactionTest, + DISABLED_QuicUploadToAlternativeProxyServer) { base::HistogramTester histogram_tester; proxy_service_ = ProxyService::CreateFixedFromPacResult("HTTPS mail.example.org:443"); @@ -2869,7 +2870,7 @@ TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) { GetRequestHeaders("POST", "https", "/"), &offset)); std::unique_ptr<QuicEncryptedPacket> packet; - if (version_ > QUIC_VERSION_35) { + if (version_ == QUIC_VERSION_36) { packet = ConstructClientForceHolDataPacket(3, kClientDataStreamId1, true, true, &offset, "1"); } else { @@ -3326,9 +3327,8 @@ TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) { scoped_refptr<X509Certificate> cert( ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem")); - bool unused; - ASSERT_FALSE(cert->VerifyNameMatch(origin1_, &unused)); - ASSERT_TRUE(cert->VerifyNameMatch(origin2_, &unused)); + ASSERT_FALSE(cert->VerifyNameMatch(origin1_, false)); + ASSERT_TRUE(cert->VerifyNameMatch(origin2_, false)); ProofVerifyDetailsChromium verify_details; verify_details.cert_verify_result.verified_cert = cert; @@ -3366,10 +3366,9 @@ TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) { scoped_refptr<X509Certificate> cert( ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem")); - bool unused; - ASSERT_TRUE(cert->VerifyNameMatch(origin1_, &unused)); - ASSERT_TRUE(cert->VerifyNameMatch(origin2_, &unused)); - ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname, &unused)); + ASSERT_TRUE(cert->VerifyNameMatch(origin1_, false)); + ASSERT_TRUE(cert->VerifyNameMatch(origin2_, false)); + ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname, false)); ProofVerifyDetailsChromium verify_details; verify_details.cert_verify_result.verified_cert = cert; @@ -3436,15 +3435,14 @@ TEST_P(QuicNetworkTransactionWithDestinationTest, scoped_refptr<X509Certificate> cert1( ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem")); - bool unused; - ASSERT_TRUE(cert1->VerifyNameMatch(origin1_, &unused)); - ASSERT_FALSE(cert1->VerifyNameMatch(origin2_, &unused)); - ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname, &unused)); + ASSERT_TRUE(cert1->VerifyNameMatch(origin1_, false)); + ASSERT_FALSE(cert1->VerifyNameMatch(origin2_, false)); + ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname, false)); scoped_refptr<X509Certificate> cert2( ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem")); - ASSERT_TRUE(cert2->VerifyNameMatch(origin2_, &unused)); - ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname, &unused)); + ASSERT_TRUE(cert2->VerifyNameMatch(origin2_, false)); + ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname, false)); ProofVerifyDetailsChromium verify_details1; verify_details1.cert_verify_result.verified_cert = cert1; diff --git a/chromium/net/quic/chromium/quic_server_info.cc b/chromium/net/quic/chromium/quic_server_info.cc index 7259dbac10b..23f4cf8ab24 100644 --- a/chromium/net/quic/chromium/quic_server_info.cc +++ b/chromium/net/quic/chromium/quic_server_info.cc @@ -7,6 +7,7 @@ #include <limits> #include "base/pickle.h" +#include "base/stl_util.h" using std::string; @@ -23,12 +24,12 @@ QuicServerInfo::State::State() {} QuicServerInfo::State::~State() {} void QuicServerInfo::State::Clear() { - server_config.clear(); - source_address_token.clear(); - cert_sct.clear(); - chlo_hash.clear(); - server_config_sig.clear(); - certs.clear(); + base::STLClearObject(&server_config); + base::STLClearObject(&source_address_token); + base::STLClearObject(&cert_sct); + base::STLClearObject(&chlo_hash); + base::STLClearObject(&server_config_sig); + base::STLClearObject(&certs); } QuicServerInfo::QuicServerInfo(const QuicServerId& server_id) diff --git a/chromium/net/quic/chromium/quic_server_info.h b/chromium/net/quic/chromium/quic_server_info.h index 34c6f1e876c..77fb0fc1d75 100644 --- a/chromium/net/quic/chromium/quic_server_info.h +++ b/chromium/net/quic/chromium/quic_server_info.h @@ -5,6 +5,7 @@ #ifndef NET_QUIC_CHROMIUM_QUIC_SERVER_INFO_H_ #define NET_QUIC_CHROMIUM_QUIC_SERVER_INFO_H_ +#include <memory> #include <string> #include <vector> @@ -167,7 +168,8 @@ class QUIC_EXPORT_PRIVATE QuicServerInfoFactory { // GetForServer returns a fresh, allocated QuicServerInfo for the given // |server_id| or NULL on failure. - virtual QuicServerInfo* GetForServer(const QuicServerId& server_id) = 0; + virtual std::unique_ptr<QuicServerInfo> GetForServer( + const QuicServerId& server_id) = 0; private: DISALLOW_COPY_AND_ASSIGN(QuicServerInfoFactory); diff --git a/chromium/net/quic/chromium/quic_stream_factory.cc b/chromium/net/quic/chromium/quic_stream_factory.cc index 48cc2a61b2a..24ff534754f 100644 --- a/chromium/net/quic/chromium/quic_stream_factory.cc +++ b/chromium/net/quic/chromium/quic_stream_factory.cc @@ -19,6 +19,9 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_task_runner_handle.h" +#include "base/trace_event/memory_allocator_dump.h" +#include "base/trace_event/memory_usage_estimator.h" +#include "base/trace_event/process_memory_dump.h" #include "base/trace_event/trace_event.h" #include "base/values.h" #include "crypto/openssl_util.h" @@ -73,6 +76,14 @@ enum CreateSessionFailure { CREATION_ERROR_MAX }; +enum InitialRttEstimateSource { + INITIAL_RTT_DEFAULT, + INITIAL_RTT_CACHED, + INITIAL_RTT_2G, + INITIAL_RTT_3G, + INITIAL_RTT_SOURCE_MAX, +}; + // The maximum receive window sizes for QUIC sessions and streams. const int32_t kQuicSessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB const int32_t kQuicStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB @@ -152,6 +163,15 @@ void HistogramMigrationStatus(enum QuicConnectionMigrationStatus status) { MIGRATION_STATUS_MAX); } +void SetInitialRttEstimate(base::TimeDelta estimate, + enum InitialRttEstimateSource source, + QuicConfig* config) { + UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.InitialRttEsitmateSource", source, + INITIAL_RTT_SOURCE_MAX); + if (estimate != base::TimeDelta()) + config->SetInitialRoundTripTimeUsToSend(estimate.InMicroseconds()); +} + QuicConfig InitializeQuicConfig(const QuicTagVector& connection_options, int idle_connection_timeout_seconds) { DCHECK_GT(idle_connection_timeout_seconds, 0); @@ -185,6 +205,11 @@ class ServerIdOriginFilter : public QuicCryptoClientConfig::ServerIdFilter { const base::Callback<bool(const GURL&)> origin_filter_; }; +// Returns the estimate of dynamically allocated memory of |server_id|. +size_t EstimateServerIdMemoryUsage(const QuicServerId& server_id) { + return base::trace_event::EstimateMemoryUsage(server_id.host_port_pair()); +} + } // namespace // Responsible for verifying the certificates saved in @@ -282,7 +307,7 @@ class QuicStreamFactory::Job { const QuicSessionKey& key, bool was_alternative_service_recently_broken, int cert_verify_flags, - QuicServerInfo* server_info, + std::unique_ptr<QuicServerInfo> server_info, const NetLogWithSource& net_log); // Creates a new job to handle the resumption of for connecting an @@ -354,7 +379,7 @@ QuicStreamFactory::Job::Job(QuicStreamFactory* factory, const QuicSessionKey& key, bool was_alternative_service_recently_broken, int cert_verify_flags, - QuicServerInfo* server_info, + std::unique_ptr<QuicServerInfo> server_info, const NetLogWithSource& net_log) : io_state_(STATE_RESOLVE_HOST), factory_(factory), @@ -363,7 +388,7 @@ QuicStreamFactory::Job::Job(QuicStreamFactory* factory, cert_verify_flags_(cert_verify_flags), was_alternative_service_recently_broken_( was_alternative_service_recently_broken), - server_info_(server_info), + server_info_(std::move(server_info)), started_another_job_(false), net_log_(net_log), num_sent_client_hellos_(0), @@ -563,10 +588,13 @@ int QuicStreamFactory::Job::DoLoadServerInfoComplete(int rv) { int QuicStreamFactory::Job::DoConnect() { io_state_ = STATE_CONNECT_COMPLETE; - int rv = - factory_->CreateSession(key_, cert_verify_flags_, std::move(server_info_), - address_list_, dns_resolution_start_time_, - dns_resolution_end_time_, net_log_, &session_); + bool require_confirmation = factory_->require_confirmation() || + was_alternative_service_recently_broken_; + + int rv = factory_->CreateSession( + key_, cert_verify_flags_, std::move(server_info_), require_confirmation, + address_list_, dns_resolution_start_time_, dns_resolution_end_time_, + net_log_, &session_); if (rv != OK) { DCHECK(rv != ERR_IO_PENDING); DCHECK(!session_); @@ -579,11 +607,8 @@ int QuicStreamFactory::Job::DoConnect() { session_->StartReading(); if (!session_->connection()->connected()) return ERR_QUIC_PROTOCOL_ERROR; - bool require_confirmation = factory_->require_confirmation() || - was_alternative_service_recently_broken_; rv = session_->CryptoConnect( - require_confirmation, base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); if (!session_->connection()->connected() && @@ -738,7 +763,8 @@ QuicStreamFactory::QuicStreamFactory( bool allow_server_migration, bool force_hol_blocking, bool race_cert_verification, - bool quic_do_not_fragment, + bool do_not_fragment, + bool estimate_initial_rtt, const QuicTagVector& connection_options, bool enable_token_binding) : require_confirmation_(true), @@ -794,7 +820,8 @@ QuicStreamFactory::QuicStreamFactory( allow_server_migration_(allow_server_migration), force_hol_blocking_(force_hol_blocking), race_cert_verification_(race_cert_verification), - quic_do_not_fragment_(quic_do_not_fragment), + do_not_fragment_(do_not_fragment), + estimate_initial_rtt(estimate_initial_rtt), check_persisted_supports_quic_(true), has_initialized_data_(false), num_push_streams_created_(0), @@ -897,6 +924,24 @@ void QuicStreamFactory::set_quic_server_info_factory( quic_server_info_factory_.reset(quic_server_info_factory); } +void QuicStreamFactory::DumpMemoryStats( + base::trace_event::ProcessMemoryDump* pmd, + const std::string& parent_absolute_name) const { + if (all_sessions_.empty()) + return; + base::trace_event::MemoryAllocatorDump* factory_dump = + pmd->CreateAllocatorDump(parent_absolute_name + "/quic_stream_factory"); + size_t memory_estimate = + base::trace_event::EstimateMemoryUsage(all_sessions_); + factory_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + memory_estimate); + factory_dump->AddScalar( + base::trace_event::MemoryAllocatorDump::kNameObjectCount, + base::trace_event::MemoryAllocatorDump::kUnitsObjects, + all_sessions_.size()); +} + bool QuicStreamFactory::CanUseExistingSession(const QuicServerId& server_id, const HostPortPair& destination) { // TODO(zhongyi): delete active_sessions_.empty() checks once the @@ -987,7 +1032,7 @@ int QuicStreamFactory::Create(const QuicServerId& server_id, if (!task_runner_) task_runner_ = base::ThreadTaskRunnerHandle::Get().get(); - QuicServerInfo* quic_server_info = nullptr; + std::unique_ptr<QuicServerInfo> quic_server_info; if (quic_server_info_factory_.get()) { bool load_from_disk_cache = !disable_disk_cache_; MaybeInitialize(); @@ -1005,7 +1050,7 @@ int QuicStreamFactory::Create(const QuicServerId& server_id, QuicSessionKey key(destination, server_id); std::unique_ptr<Job> job = base::MakeUnique<Job>( this, host_resolver_, key, WasQuicRecentlyBroken(server_id), - cert_verify_flags, quic_server_info, net_log); + cert_verify_flags, std::move(quic_server_info), net_log); int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, base::Unretained(this), job.get())); if (rv == ERR_IO_PENDING) { @@ -1047,6 +1092,11 @@ bool QuicStreamFactory::QuicSessionKey::operator==( server_id_ == other.server_id_; } +size_t QuicStreamFactory::QuicSessionKey::EstimateMemoryUsage() const { + return base::trace_event::EstimateMemoryUsage(destination_) + + EstimateServerIdMemoryUsage(server_id_); +} + void QuicStreamFactory::CreateAuxilaryJob(const QuicSessionKey& key, int cert_verify_flags, const NetLogWithSource& net_log) { @@ -1508,7 +1558,7 @@ void QuicStreamFactory::OnSSLConfigChanged() { CloseAllSessions(ERR_CERT_DATABASE_CHANGED, QUIC_CONNECTION_CANCELLED); } -void QuicStreamFactory::OnCertDBChanged(const X509Certificate* cert) { +void QuicStreamFactory::OnCertDBChanged() { // We should flush the sessions if we removed trust from a // cert, because a previously trusted server may have become // untrusted. @@ -1565,7 +1615,7 @@ int QuicStreamFactory::ConfigureSocket(DatagramClientSocket* socket, return rv; } - if (quic_do_not_fragment_) { + if (do_not_fragment_) { rv = socket->SetDoNotFragment(); // SetDoNotFragment is not implemented on all platforms, so ignore errors. if (rv != OK && rv != ERR_NOT_IMPLEMENTED) { @@ -1600,6 +1650,7 @@ int QuicStreamFactory::CreateSession( const QuicSessionKey& key, int cert_verify_flags, std::unique_ptr<QuicServerInfo> server_info, + bool require_confirmation, const AddressList& address_list, base::TimeTicks dns_resolution_start_time, base::TimeTicks dns_resolution_end_time, @@ -1654,10 +1705,8 @@ int QuicStreamFactory::CreateSession( config.SetInitialSessionFlowControlWindowToSend( kQuicSessionMaxRecvWindowSize); config.SetInitialStreamFlowControlWindowToSend(kQuicStreamMaxRecvWindowSize); - int64_t srtt = GetServerNetworkStatsSmoothedRttInMicroseconds(server_id); - if (srtt > 0) - config.SetInitialRoundTripTimeUsToSend(static_cast<uint32_t>(srtt)); config.SetBytesForConnectionIdToSend(0); + ConfigureInitialRttEstimate(server_id, &config); if (force_hol_blocking_) config.SetForceHolBlocking(); @@ -1666,7 +1715,7 @@ int QuicStreamFactory::CreateSession( // Start the disk cache loading so that we can persist the newer QUIC server // information and/or inform the disk cache that we have reused // |server_info|. - server_info.reset(quic_server_info_factory_->GetForServer(server_id)); + server_info = quic_server_info_factory_->GetForServer(server_id); server_info->Start(); } @@ -1682,11 +1731,11 @@ int QuicStreamFactory::CreateSession( *session = new QuicChromiumClientSession( connection, std::move(socket), this, quic_crypto_client_stream_factory_, clock_.get(), transport_security_state_, std::move(server_info), - server_id, yield_after_packets_, yield_after_duration_, cert_verify_flags, - config, &crypto_config_, network_connection_.GetDescription(), - dns_resolution_start_time, dns_resolution_end_time, &push_promise_index_, - push_delegate_, task_runner_, std::move(socket_performance_watcher), - net_log.net_log()); + server_id, require_confirmation, yield_after_packets_, + yield_after_duration_, cert_verify_flags, config, &crypto_config_, + network_connection_.connection_description(), dns_resolution_start_time, + dns_resolution_end_time, &push_promise_index_, push_delegate_, + task_runner_, std::move(socket_performance_watcher), net_log.net_log()); all_sessions_[*session] = key; // owning pointer writer->set_delegate(*session); @@ -1719,15 +1768,47 @@ void QuicStreamFactory::ActivateSession(const QuicSessionKey& key, session_peer_ip_[session] = peer_address; } -int64_t QuicStreamFactory::GetServerNetworkStatsSmoothedRttInMicroseconds( +void QuicStreamFactory::ConfigureInitialRttEstimate( + const QuicServerId& server_id, + QuicConfig* config) { + const base::TimeDelta* srtt = GetServerNetworkStatsSmoothedRtt(server_id); + if (srtt != nullptr) { + SetInitialRttEstimate(*srtt, INITIAL_RTT_CACHED, config); + return; + } + + NetworkChangeNotifier::ConnectionType type = + network_connection_.connection_type(); + if (type == NetworkChangeNotifier::CONNECTION_2G) { + SetInitialRttEstimate(base::TimeDelta::FromMilliseconds(1200), + INITIAL_RTT_CACHED, config); + return; + } + + if (type == NetworkChangeNotifier::CONNECTION_3G) { + SetInitialRttEstimate(base::TimeDelta::FromMilliseconds(400), + INITIAL_RTT_CACHED, config); + return; + } + + SetInitialRttEstimate(base::TimeDelta(), INITIAL_RTT_DEFAULT, config); +} + +const base::TimeDelta* QuicStreamFactory::GetServerNetworkStatsSmoothedRtt( const QuicServerId& server_id) const { url::SchemeHostPort server("https", server_id.host_port_pair().host(), server_id.host_port_pair().port()); const ServerNetworkStats* stats = http_server_properties_->GetServerNetworkStats(server); if (stats == nullptr) - return 0; - return stats->srtt.InMicroseconds(); + return nullptr; + return &(stats->srtt); +} + +int64_t QuicStreamFactory::GetServerNetworkStatsSmoothedRttInMicroseconds( + const QuicServerId& server_id) const { + const base::TimeDelta* srtt = GetServerNetworkStatsSmoothedRtt(server_id); + return srtt == nullptr ? 0 : srtt->InMicroseconds(); } bool QuicStreamFactory::WasQuicRecentlyBroken( @@ -1848,7 +1929,7 @@ void QuicStreamFactory::MaybeInitialize() { server_list.push_back(key_value.first); for (auto it = server_list.rbegin(); it != server_list.rend(); ++it) { const QuicServerId& server_id = *it; - server_info.reset(quic_server_info_factory_->GetForServer(server_id)); + server_info = quic_server_info_factory_->GetForServer(server_id); if (server_info->WaitForDataReady(callback) == OK) { DVLOG(1) << "Initialized server config for: " << server_id.ToString(); InitializeCachedStateInCryptoConfig(server_id, server_info, nullptr); diff --git a/chromium/net/quic/chromium/quic_stream_factory.h b/chromium/net/quic/chromium/quic_stream_factory.h index 212cdf77964..966f3b278e3 100644 --- a/chromium/net/quic/chromium/quic_stream_factory.h +++ b/chromium/net/quic/chromium/quic_stream_factory.h @@ -43,6 +43,9 @@ namespace base { class Value; +namespace trace_event { +class ProcessMemoryDump; +} } namespace net { @@ -175,6 +178,9 @@ class NET_EXPORT_PRIVATE QuicStreamFactory const HostPortPair& destination() const { return destination_; } const QuicServerId& server_id() const { return server_id_; } + // Returns the estimate of dynamically allocated memory in bytes. + size_t EstimateMemoryUsage() const; + private: HostPortPair destination_; QuicServerId server_id_; @@ -219,7 +225,8 @@ class NET_EXPORT_PRIVATE QuicStreamFactory bool allow_server_migration, bool force_hol_blocking, bool race_cert_verification, - bool quic_do_not_fragment, + bool do_not_fragment, + bool estimate_initial_rtt, const QuicTagVector& connection_options, bool enable_token_binding); ~QuicStreamFactory() override; @@ -353,7 +360,7 @@ class NET_EXPORT_PRIVATE QuicStreamFactory // CertDatabase::Observer methods: // We close all sessions when certificate database is changed. - void OnCertDBChanged(const X509Certificate* cert) override; + void OnCertDBChanged() override; bool require_confirmation() const { return require_confirmation_; } @@ -368,10 +375,14 @@ class NET_EXPORT_PRIVATE QuicStreamFactory QuicChromiumAlarmFactory* alarm_factory() { return alarm_factory_.get(); } - bool has_quic_server_info_factory() { + bool has_quic_server_info_factory() const { return quic_server_info_factory_.get() != nullptr; } + QuicServerInfoFactory* quic_server_info_factory() const { + return quic_server_info_factory_.get(); + } + void set_quic_server_info_factory( QuicServerInfoFactory* quic_server_info_factory); @@ -392,6 +403,11 @@ class NET_EXPORT_PRIVATE QuicStreamFactory return migrate_sessions_on_network_change_; } + // Dumps memory allocation stats. |parent_dump_absolute_name| is the name + // used by the parent MemoryAllocatorDump in the memory dump hierarchy. + void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd, + const std::string& parent_absolute_name) const; + private: class Job; class CertVerifierJob; @@ -437,6 +453,7 @@ class NET_EXPORT_PRIVATE QuicStreamFactory int CreateSession(const QuicSessionKey& key, int cert_verify_flags, std::unique_ptr<QuicServerInfo> quic_server_info, + bool require_confirmation, const AddressList& address_list, base::TimeTicks dns_resolution_start_time, base::TimeTicks dns_resolution_end_time, @@ -445,12 +462,21 @@ class NET_EXPORT_PRIVATE QuicStreamFactory void ActivateSession(const QuicSessionKey& key, QuicChromiumClientSession* session); + void ConfigureInitialRttEstimate(const QuicServerId& server_id, + QuicConfig* config); + // Returns |srtt| in micro seconds from ServerNetworkStats. Returns 0 if there // is no |http_server_properties_| or if |http_server_properties_| doesn't // have ServerNetworkStats for the given |server_id|. int64_t GetServerNetworkStatsSmoothedRttInMicroseconds( const QuicServerId& server_id) const; + // Returns |srtt| from ServerNetworkStats. Returns null if there + // is no |http_server_properties_| or if |http_server_properties_| doesn't + // have ServerNetworkStats for the given |server_id|. + const base::TimeDelta* GetServerNetworkStatsSmoothedRtt( + const QuicServerId& server_id) const; + // Helper methods. bool WasQuicRecentlyBroken(const QuicServerId& server_id) const; @@ -624,7 +650,10 @@ class NET_EXPORT_PRIVATE QuicStreamFactory bool race_cert_verification_; // If set, configure QUIC sockets to not fragment packets. - bool quic_do_not_fragment_; + bool do_not_fragment_; + + // If true, estimate the initial RTT based on network type. + bool estimate_initial_rtt; // Local address of socket that was created in CreateSession. IPEndPoint local_address_; diff --git a/chromium/net/quic/chromium/quic_stream_factory_test.cc b/chromium/net/quic/chromium/quic_stream_factory_test.cc index 68fb84499f9..92f93ee28d2 100644 --- a/chromium/net/quic/chromium/quic_stream_factory_test.cc +++ b/chromium/net/quic/chromium/quic_stream_factory_test.cc @@ -13,7 +13,6 @@ #include "base/memory/ptr_util.h" #include "base/run_loop.h" #include "base/strings/string_util.h" -#include "base/threading/thread_task_runner_handle.h" #include "net/base/test_proxy_delegate.h" #include "net/cert/cert_verifier.h" #include "net/cert/ct_policy_enforcer.h" @@ -203,8 +202,9 @@ class MockQuicServerInfoFactory : public QuicServerInfoFactory { MockQuicServerInfoFactory() {} ~MockQuicServerInfoFactory() override {} - QuicServerInfo* GetForServer(const QuicServerId& server_id) override { - return new MockQuicServerInfo(server_id); + std::unique_ptr<QuicServerInfo> GetForServer( + const QuicServerId& server_id) override { + return base::MakeUnique<MockQuicServerInfo>(server_id); } }; @@ -228,8 +228,7 @@ class QuicStreamFactoryTestBase { Perspective::IS_SERVER), cert_verifier_(CertVerifier::CreateDefault()), channel_id_service_( - new ChannelIDService(new DefaultChannelIDStore(nullptr), - base::ThreadTaskRunnerHandle::Get())), + new ChannelIDService(new DefaultChannelIDStore(nullptr))), cert_transparency_verifier_(new MultiLogCTVerifier()), scoped_mock_network_change_notifier_(nullptr), factory_(nullptr), @@ -258,7 +257,8 @@ class QuicStreamFactoryTestBase { migrate_sessions_early_(false), allow_server_migration_(false), force_hol_blocking_(false), - race_cert_verification_(false) { + race_cert_verification_(false), + estimate_initial_rtt_(false) { clock_->AdvanceTime(QuicTime::Delta::FromSeconds(1)); } @@ -290,7 +290,7 @@ class QuicStreamFactoryTestBase { packet_reader_yield_after_duration_milliseconds_, migrate_sessions_on_network_change_, migrate_sessions_early_, allow_server_migration_, force_hol_blocking_, race_cert_verification_, - /*do_not_fragment*/ true, QuicTagVector(), + /*do_not_fragment*/ true, estimate_initial_rtt_, QuicTagVector(), /*enable_token_binding*/ false)); factory_->set_require_confirmation(false); EXPECT_FALSE(factory_->has_quic_server_info_factory()); @@ -316,6 +316,12 @@ class QuicStreamFactoryTestBase { return QuicStreamFactoryPeer::HasActiveSession(factory_.get(), server_id); } + bool HasActiveJob(const HostPortPair& host_port_pair, + const PrivacyMode privacy_mode) { + QuicServerId server_id(host_port_pair, privacy_mode); + return QuicStreamFactoryPeer::HasActiveJob(factory_.get(), server_id); + } + bool HasActiveCertVerifierJob(const QuicServerId& server_id) { return QuicStreamFactoryPeer::HasActiveCertVerifierJob(factory_.get(), server_id); @@ -792,6 +798,7 @@ class QuicStreamFactoryTestBase { bool allow_server_migration_; bool force_hol_blocking_; bool race_cert_verification_; + bool estimate_initial_rtt_; }; class QuicStreamFactoryTest : public QuicStreamFactoryTestBase, @@ -897,6 +904,133 @@ TEST_P(QuicStreamFactoryTest, CreateZeroRttPost) { EXPECT_TRUE(socket_data.AllWriteDataConsumed()); } +TEST_P(QuicStreamFactoryTest, DefaultInitialRtt) { + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + MockQuicData socket_data; + socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + socket_data.AddWrite( + ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, + kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddSocketDataToFactory(&socket_factory_); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request(host_port_pair_, privacy_mode_, + /*cert_verify_flags=*/0, url_, "GET", net_log_, + callback_.callback())); + + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + std::unique_ptr<QuicHttpStream> stream = request.CreateStream(); + EXPECT_TRUE(stream.get()); + + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); + EXPECT_EQ(100000u, session->connection()->GetStats().srtt_us); + ASSERT_FALSE(session->config()->HasInitialRoundTripTimeUsToSend()); +} + +TEST_P(QuicStreamFactoryTest, CachedInitialRtt) { + ServerNetworkStats stats; + stats.srtt = base::TimeDelta::FromMilliseconds(10); + http_server_properties_.SetServerNetworkStats(url::SchemeHostPort(url_), + stats); + estimate_initial_rtt_ = true; + + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + MockQuicData socket_data; + socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + socket_data.AddWrite( + ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, + kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddSocketDataToFactory(&socket_factory_); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request(host_port_pair_, privacy_mode_, + /*cert_verify_flags=*/0, url_, "GET", net_log_, + callback_.callback())); + + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + std::unique_ptr<QuicHttpStream> stream = request.CreateStream(); + EXPECT_TRUE(stream.get()); + + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); + EXPECT_EQ(10000u, session->connection()->GetStats().srtt_us); + ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend()); + EXPECT_EQ(10000u, session->config()->GetInitialRoundTripTimeUsToSend()); +} + +TEST_P(QuicStreamFactoryTest, 2gInitialRtt) { + ScopedMockNetworkChangeNotifier notifier; + notifier.mock_network_change_notifier()->SetConnectionType( + NetworkChangeNotifier::CONNECTION_2G); + estimate_initial_rtt_ = true; + + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + MockQuicData socket_data; + socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + socket_data.AddWrite( + ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, + kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddSocketDataToFactory(&socket_factory_); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request(host_port_pair_, privacy_mode_, + /*cert_verify_flags=*/0, url_, "GET", net_log_, + callback_.callback())); + + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + std::unique_ptr<QuicHttpStream> stream = request.CreateStream(); + EXPECT_TRUE(stream.get()); + + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); + EXPECT_EQ(1200000u, session->connection()->GetStats().srtt_us); + ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend()); + EXPECT_EQ(1200000u, session->config()->GetInitialRoundTripTimeUsToSend()); +} + +TEST_P(QuicStreamFactoryTest, 3gInitialRtt) { + ScopedMockNetworkChangeNotifier notifier; + notifier.mock_network_change_notifier()->SetConnectionType( + NetworkChangeNotifier::CONNECTION_3G); + estimate_initial_rtt_ = true; + + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + MockQuicData socket_data; + socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + socket_data.AddWrite( + ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, + kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddSocketDataToFactory(&socket_factory_); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request(host_port_pair_, privacy_mode_, + /*cert_verify_flags=*/0, url_, "GET", net_log_, + callback_.callback())); + + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + std::unique_ptr<QuicHttpStream> stream = request.CreateStream(); + EXPECT_TRUE(stream.get()); + + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); + EXPECT_EQ(400000u, session->connection()->GetStats().srtt_us); + ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend()); + EXPECT_EQ(400000u, session->config()->GetInitialRoundTripTimeUsToSend()); +} + TEST_P(QuicStreamFactoryTest, GoAway) { Initialize(); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -1675,6 +1809,134 @@ TEST_P(QuicStreamFactoryTest, CloseAllSessions) { EXPECT_TRUE(socket_data2.AllWriteDataConsumed()); } +// Regression test for crbug.com/700617. Test a write error during the +// crypto handshake will not hang QuicStreamFactory::Job and should +// report QUIC_HANDSHAKE_FAILED to upper layers. Subsequent +// QuicStreamRequest should succeed without hanging. +TEST_P(QuicStreamFactoryTest, + WriteErrorInCryptoConnectWithAsyncHostResolution) { + Initialize(); + // Use unmocked crypto stream to do crypto connect. + crypto_client_stream_factory_.set_handshake_mode( + MockCryptoClientStream::USE_DEFAULT_CRYPTO_STREAM); + + MockQuicData socket_data; + socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect. + socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); + socket_data.AddSocketDataToFactory(&socket_factory_); + + // Create request, should fail after the write of the CHLO fails. + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request(host_port_pair_, privacy_mode_, + /*cert_verify_flags=*/0, url_, "GET", net_log_, + callback_.callback())); + EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult()); + EXPECT_FALSE(HasActiveSession(host_port_pair_)); + EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_)); + + // Verify new requests can be sent normally without hanging. + crypto_client_stream_factory_.set_handshake_mode( + MockCryptoClientStream::COLD_START); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + MockQuicData socket_data2; + socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + socket_data2.AddWrite( + ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, + kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddSocketDataToFactory(&socket_factory_); + + QuicStreamRequest request2(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request2.Request(host_port_pair_, privacy_mode_, + /*cert_verify_flags=*/0, url_, "GET", net_log_, + callback_.callback())); + EXPECT_FALSE(HasActiveSession(host_port_pair_)); + EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_)); + // Run the message loop to complete host resolution. + base::RunLoop().RunUntilIdle(); + + // Complete handshake. QuicStreamFactory::Job should complete and succeed. + crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( + QuicSession::HANDSHAKE_CONFIRMED); + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + EXPECT_TRUE(HasActiveSession(host_port_pair_)); + EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_)); + + // Create QuicHttpStream. + std::unique_ptr<QuicHttpStream> stream = request2.CreateStream(); + EXPECT_TRUE(stream.get()); + stream.reset(); + EXPECT_TRUE(socket_data.AllReadDataConsumed()); + EXPECT_TRUE(socket_data.AllWriteDataConsumed()); + EXPECT_TRUE(socket_data2.AllReadDataConsumed()); + EXPECT_TRUE(socket_data2.AllWriteDataConsumed()); +} + +TEST_P(QuicStreamFactoryTest, WriteErrorInCryptoConnectWithSyncHostResolution) { + Initialize(); + // Use unmocked crypto stream to do crypto connect. + crypto_client_stream_factory_.set_handshake_mode( + MockCryptoClientStream::USE_DEFAULT_CRYPTO_STREAM); + host_resolver_.set_synchronous_mode(true); + host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), + "192.168.0.1", ""); + + MockQuicData socket_data; + socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect. + socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); + socket_data.AddSocketDataToFactory(&socket_factory_); + + // Create request, should fail immediately. + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, + request.Request(host_port_pair_, privacy_mode_, + /*cert_verify_flags=*/0, url_, "GET", net_log_, + callback_.callback())); + // Check no active session, or active jobs left for this server. + EXPECT_FALSE(HasActiveSession(host_port_pair_)); + EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_)); + + // Verify new requests can be sent normally without hanging. + crypto_client_stream_factory_.set_handshake_mode( + MockCryptoClientStream::COLD_START); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + MockQuicData socket_data2; + socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + socket_data2.AddWrite( + ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, + kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddSocketDataToFactory(&socket_factory_); + + QuicStreamRequest request2(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request2.Request(host_port_pair_, privacy_mode_, + /*cert_verify_flags=*/0, url_, "GET", net_log_, + callback_.callback())); + EXPECT_FALSE(HasActiveSession(host_port_pair_)); + EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_)); + + // Complete handshake. + crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( + QuicSession::HANDSHAKE_CONFIRMED); + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + EXPECT_TRUE(HasActiveSession(host_port_pair_)); + EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_)); + + // Create QuicHttpStream. + std::unique_ptr<QuicHttpStream> stream = request2.CreateStream(); + EXPECT_TRUE(stream.get()); + stream.reset(); + EXPECT_TRUE(socket_data.AllReadDataConsumed()); + EXPECT_TRUE(socket_data.AllWriteDataConsumed()); + EXPECT_TRUE(socket_data2.AllReadDataConsumed()); + EXPECT_TRUE(socket_data2.AllWriteDataConsumed()); +} + TEST_P(QuicStreamFactoryTest, OnIPAddressChanged) { close_sessions_on_ip_change_ = true; Initialize(); @@ -4232,7 +4494,7 @@ TEST_P(QuicStreamFactoryTest, OnCertDBChanged) { net_log_, CompletionCallback())); // Change the CA cert and verify that stream saw the event. - factory_->OnCertDBChanged(nullptr); + factory_->OnCertDBChanged(); EXPECT_EQ(ERR_CERT_DATABASE_CHANGED, stream->ReadResponseHeaders(callback_.callback())); EXPECT_FALSE(factory_->require_confirmation()); @@ -5184,7 +5446,7 @@ TEST_P(QuicStreamFactoryTest, ForceHolBlockingEnabled) { EXPECT_EQ(OK, callback_.WaitForResult()); QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); - if (session->connection()->version() > QUIC_VERSION_35) { + if (session->connection()->version() == QUIC_VERSION_36) { EXPECT_TRUE(session->force_hol_blocking()); } else { EXPECT_FALSE(session->force_hol_blocking()); @@ -5263,9 +5525,8 @@ TEST_P(QuicStreamFactoryWithDestinationTest, InvalidCertificate) { scoped_refptr<X509Certificate> cert( ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem")); - bool unused; - ASSERT_FALSE(cert->VerifyNameMatch(origin1_.host(), &unused)); - ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host(), &unused)); + ASSERT_FALSE(cert->VerifyNameMatch(origin1_.host(), false)); + ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host(), false)); ProofVerifyDetailsChromium verify_details; verify_details.cert_verify_result.verified_cert = cert; @@ -5297,10 +5558,9 @@ TEST_P(QuicStreamFactoryWithDestinationTest, SharedCertificate) { scoped_refptr<X509Certificate> cert( ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem")); - bool unused; - ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host(), &unused)); - ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host(), &unused)); - ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname, &unused)); + ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host(), false)); + ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host(), false)); + ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname, false)); ProofVerifyDetailsChromium verify_details; verify_details.cert_verify_result.verified_cert = cert; @@ -5363,10 +5623,9 @@ TEST_P(QuicStreamFactoryWithDestinationTest, DifferentPrivacyMode) { scoped_refptr<X509Certificate> cert( ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem")); - bool unused; - ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host(), &unused)); - ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host(), &unused)); - ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname, &unused)); + ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host(), false)); + ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host(), false)); + ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname, false)); ProofVerifyDetailsChromium verify_details1; verify_details1.cert_verify_result.verified_cert = cert; @@ -5444,10 +5703,9 @@ TEST_P(QuicStreamFactoryWithDestinationTest, DisjointCertificate) { scoped_refptr<X509Certificate> cert1( ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem")); - bool unused; - ASSERT_TRUE(cert1->VerifyNameMatch(origin1_.host(), &unused)); - ASSERT_FALSE(cert1->VerifyNameMatch(origin2_.host(), &unused)); - ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname, &unused)); + ASSERT_TRUE(cert1->VerifyNameMatch(origin1_.host(), false)); + ASSERT_FALSE(cert1->VerifyNameMatch(origin2_.host(), false)); + ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname, false)); ProofVerifyDetailsChromium verify_details1; verify_details1.cert_verify_result.verified_cert = cert1; @@ -5456,8 +5714,8 @@ TEST_P(QuicStreamFactoryWithDestinationTest, DisjointCertificate) { scoped_refptr<X509Certificate> cert2( ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem")); - ASSERT_TRUE(cert2->VerifyNameMatch(origin2_.host(), &unused)); - ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname, &unused)); + ASSERT_TRUE(cert2->VerifyNameMatch(origin2_.host(), false)); + ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname, false)); ProofVerifyDetailsChromium verify_details2; verify_details2.cert_verify_result.verified_cert = cert2; diff --git a/chromium/net/quic/chromium/quic_test_packet_maker.cc b/chromium/net/quic/chromium/quic_test_packet_maker.cc index 43a99dbbb8a..d80ecda11e2 100644 --- a/chromium/net/quic/chromium/quic_test_packet_maker.cc +++ b/chromium/net/quic/chromium/quic_test_packet_maker.cc @@ -118,9 +118,8 @@ std::unique_ptr<QuicReceivedPacket> QuicTestPacketMaker::MakeAckAndRstPacket( std::unique_ptr<QuicPacket> packet( BuildUnsizedDataPacket(&framer, header, frames)); char buffer[kMaxPacketSize]; - size_t encrypted_size = framer.EncryptPayload(ENCRYPTION_NONE, /*path_id=*/0u, - header.packet_number, *packet, - buffer, kMaxPacketSize); + size_t encrypted_size = framer.EncryptPayload( + ENCRYPTION_NONE, header.packet_number, *packet, buffer, kMaxPacketSize); EXPECT_NE(0u, encrypted_size); QuicReceivedPacket encrypted(buffer, encrypted_size, QuicTime::Zero(), false); return std::unique_ptr<QuicReceivedPacket>(encrypted.Clone()); @@ -170,9 +169,8 @@ QuicTestPacketMaker::MakeAckAndConnectionClosePacket( std::unique_ptr<QuicPacket> packet( BuildUnsizedDataPacket(&framer, header, frames)); char buffer[kMaxPacketSize]; - size_t encrypted_size = framer.EncryptPayload(ENCRYPTION_NONE, /*path_id=*/0u, - header.packet_number, *packet, - buffer, kMaxPacketSize); + size_t encrypted_size = framer.EncryptPayload( + ENCRYPTION_NONE, header.packet_number, *packet, buffer, kMaxPacketSize); EXPECT_NE(0u, encrypted_size); QuicReceivedPacket encrypted(buffer, encrypted_size, clock_->Now(), false); return std::unique_ptr<QuicReceivedPacket>(encrypted.Clone()); @@ -259,9 +257,8 @@ std::unique_ptr<QuicReceivedPacket> QuicTestPacketMaker::MakeAckPacket( std::unique_ptr<QuicPacket> packet( BuildUnsizedDataPacket(&framer, header, frames)); char buffer[kMaxPacketSize]; - size_t encrypted_size = framer.EncryptPayload(ENCRYPTION_NONE, /*path_id=*/0u, - header.packet_number, *packet, - buffer, kMaxPacketSize); + size_t encrypted_size = framer.EncryptPayload( + ENCRYPTION_NONE, header.packet_number, *packet, buffer, kMaxPacketSize); EXPECT_NE(0u, encrypted_size); QuicReceivedPacket encrypted(buffer, encrypted_size, clock_->Now(), false); return std::unique_ptr<QuicReceivedPacket>(encrypted.Clone()); @@ -617,9 +614,8 @@ QuicTestPacketMaker::MakeMultipleFramesPacket(const QuicPacketHeader& header, std::unique_ptr<QuicPacket> packet( BuildUnsizedDataPacket(&framer, header, frames)); char buffer[kMaxPacketSize]; - size_t encrypted_size = framer.EncryptPayload(ENCRYPTION_NONE, /*path_id=*/0u, - header.packet_number, *packet, - buffer, kMaxPacketSize); + size_t encrypted_size = framer.EncryptPayload( + ENCRYPTION_NONE, header.packet_number, *packet, buffer, kMaxPacketSize); EXPECT_NE(0u, encrypted_size); QuicReceivedPacket encrypted(buffer, encrypted_size, clock_->Now(), false); return std::unique_ptr<QuicReceivedPacket>(encrypted.Clone()); diff --git a/chromium/net/quic/core/congestion_control/bandwidth_sampler.h b/chromium/net/quic/core/congestion_control/bandwidth_sampler.h index 7283506ae2a..0bedd6cae72 100644 --- a/chromium/net/quic/core/congestion_control/bandwidth_sampler.h +++ b/chromium/net/quic/core/congestion_control/bandwidth_sampler.h @@ -5,10 +5,10 @@ #ifndef NET_QUIC_CORE_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_ #define NET_QUIC_CORE_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_ -#include "net/base/linked_hash_map.h" #include "net/quic/core/quic_bandwidth.h" #include "net/quic/core/quic_packets.h" #include "net/quic/core/quic_time.h" +#include "net/quic/platform/api/quic_containers.h" #include "net/quic/platform/api/quic_export.h" namespace net { @@ -149,6 +149,9 @@ class QUIC_EXPORT_PRIVATE BandwidthSampler { QuicByteCount total_bytes_acked() const { return total_bytes_acked_; } bool is_app_limited() const { return is_app_limited_; } + QuicPacketNumber end_of_app_limited_phase() const { + return end_of_app_limited_phase_; + } private: friend class test::BandwidthSamplerPeer; @@ -205,7 +208,7 @@ class QUIC_EXPORT_PRIVATE BandwidthSampler { is_app_limited(sampler.is_app_limited_) {} }; - typedef linked_hash_map<QuicPacketNumber, ConnectionStateOnSentPacket> + typedef QuicLinkedHashMap<QuicPacketNumber, ConnectionStateOnSentPacket> ConnectionStateMap; // The total number of congestion controlled bytes sent during the connection. diff --git a/chromium/net/quic/core/congestion_control/bbr_sender.cc b/chromium/net/quic/core/congestion_control/bbr_sender.cc index 33fdfe216f3..438a553af67 100644 --- a/chromium/net/quic/core/congestion_control/bbr_sender.cc +++ b/chromium/net/quic/core/congestion_control/bbr_sender.cc @@ -7,7 +7,6 @@ #include <algorithm> #include <sstream> -#include "base/stl_util.h" #include "net/quic/core/congestion_control/rtt_stats.h" #include "net/quic/core/quic_flags.h" #include "net/quic/platform/api/quic_bug_tracker.h" @@ -26,8 +25,6 @@ const QuicByteCount kMinimumCongestionWindow = 4 * kMaxSegmentSize; const float kHighGain = 2.885f; // The gain used to drain the queue after the slow start. const float kDrainGain = 1.f / kHighGain; -// The gain used to set the congestion window during most of the modes. -const float kCongestionWindowGain = 2; // The cycle of gains used during the PROBE_BW stage. const float kPacingGain[] = {1.25, 0.75, 1, 1, 1, 1, 1, 1}; @@ -61,7 +58,8 @@ BbrSender::DebugState::DebugState(const BbrSender& sender) min_rtt_timestamp(sender.min_rtt_timestamp_), recovery_state(sender.recovery_state_), recovery_window(sender.recovery_window_), - last_sample_is_app_limited(sender.last_sample_is_app_limited_) {} + last_sample_is_app_limited(sender.last_sample_is_app_limited_), + end_of_app_limited_phase(sender.sampler_.end_of_app_limited_phase()) {} BbrSender::DebugState::DebugState(const DebugState& state) = default; @@ -88,6 +86,10 @@ BbrSender::BbrSender(const RttStats* rtt_stats, pacing_rate_(QuicBandwidth::Zero()), pacing_gain_(1), congestion_window_gain_(1), + congestion_window_gain_constant_( + static_cast<float>(base::GetFlag(FLAGS_quic_bbr_cwnd_gain))), + rtt_variance_weight_(static_cast<float>( + base::GetFlag(FLAGS_quic_bbr_rtt_variation_weight))), cycle_current_offset_(0), last_cycle_start_(QuicTime::Zero()), is_at_full_bandwidth_(false), @@ -99,9 +101,7 @@ BbrSender::BbrSender(const RttStats* rtt_stats, last_sample_is_app_limited_(false), recovery_state_(NOT_IN_RECOVERY), end_recovery_at_(0), - recovery_window_(max_congestion_window_), - enforce_startup_pacing_rate_increase_( - FLAGS_quic_reloadable_flag_quic_bbr_faster_startup) { + recovery_window_(max_congestion_window_) { EnterStartupMode(); } @@ -244,7 +244,7 @@ void BbrSender::EnterStartupMode() { void BbrSender::EnterProbeBandwidthMode(QuicTime now) { mode_ = PROBE_BW; - congestion_window_gain_ = kCongestionWindowGain; + congestion_window_gain_ = congestion_window_gain_constant_; // Pick a random offset for the gain cycle out of {0, 2..7} range. 1 is // excluded because in that case increased gain and decreased gain would not @@ -457,23 +457,21 @@ void BbrSender::CalculatePacingRate() { } QuicBandwidth target_rate = pacing_gain_ * BandwidthEstimate(); + if (is_at_full_bandwidth_) { + pacing_rate_ = target_rate; + return; + } - // Ensure that the pacing rate does not drop too low during the startup. - if (!is_at_full_bandwidth_ && enforce_startup_pacing_rate_increase_) { - // Pace at the rate of initial_window / RTT as soon as RTT measurements are - // available. - if (pacing_rate_.IsZero() && !rtt_stats_->min_rtt().IsZero()) { - pacing_rate_ = QuicBandwidth::FromBytesAndTimeDelta( - initial_congestion_window_, rtt_stats_->min_rtt()); - return; - } - - // Do not decrease the pacing rate during the startup. - pacing_rate_ = std::max(pacing_rate_, target_rate); + // Pace at the rate of initial_window / RTT as soon as RTT measurements are + // available. + if (pacing_rate_.IsZero() && !rtt_stats_->min_rtt().IsZero()) { + pacing_rate_ = QuicBandwidth::FromBytesAndTimeDelta( + initial_congestion_window_, rtt_stats_->min_rtt()); return; } - pacing_rate_ = target_rate; + // Do not decrease the pacing rate during the startup. + pacing_rate_ = std::max(pacing_rate_, target_rate); } void BbrSender::CalculateCongestionWindow(QuicByteCount bytes_acked) { @@ -484,6 +482,11 @@ void BbrSender::CalculateCongestionWindow(QuicByteCount bytes_acked) { QuicByteCount target_window = GetTargetCongestionWindow(congestion_window_gain_); + if (rtt_variance_weight_ > 0.f && !BandwidthEstimate().IsZero()) { + target_window += rtt_variance_weight_ * rtt_stats_->mean_deviation() * + BandwidthEstimate(); + } + // Instead of immediately setting the target CWND as the new one, BBR grows // the CWND towards |target_window| by only increasing it |bytes_acked| at a // time. diff --git a/chromium/net/quic/core/congestion_control/bbr_sender.h b/chromium/net/quic/core/congestion_control/bbr_sender.h index 04b71a2790a..21d71150e0d 100644 --- a/chromium/net/quic/core/congestion_control/bbr_sender.h +++ b/chromium/net/quic/core/congestion_control/bbr_sender.h @@ -87,6 +87,7 @@ class QUIC_EXPORT_PRIVATE BbrSender : public SendAlgorithmInterface { QuicByteCount recovery_window; bool last_sample_is_app_limited; + QuicPacketNumber end_of_app_limited_phase; }; BbrSender(const RttStats* rtt_stats, @@ -235,6 +236,13 @@ class QUIC_EXPORT_PRIVATE BbrSender : public SendAlgorithmInterface { // The gain currently applied to the congestion window. float congestion_window_gain_; + // The gain used for the congestion window during PROBE_BW. Latched from + // quic_bbr_cwnd_gain flag. + const float congestion_window_gain_constant_; + // The coefficient by which mean RTT variance is added to the congestion + // window. Latched from quic_bbr_rtt_variation_weight flag. + const float rtt_variance_weight_; + // Number of round-trips in PROBE_BW mode, used for determining the current // pacing gain cycle. int cycle_current_offset_; @@ -270,10 +278,6 @@ class QUIC_EXPORT_PRIVATE BbrSender : public SendAlgorithmInterface { // A window used to limit the number of bytes in flight during loss recovery. QuicByteCount recovery_window_; - // Indicates whether to always only increase the pacing rate during startup. - // Latches |FLAGS_quic_reloadable_flag_quic_bbr_faster_startup|. - bool enforce_startup_pacing_rate_increase_; - DISALLOW_COPY_AND_ASSIGN(BbrSender); }; diff --git a/chromium/net/quic/core/congestion_control/bbr_sender_test.cc b/chromium/net/quic/core/congestion_control/bbr_sender_test.cc index c903c751671..1497689bbfd 100644 --- a/chromium/net/quic/core/congestion_control/bbr_sender_test.cc +++ b/chromium/net/quic/core/congestion_control/bbr_sender_test.cc @@ -78,8 +78,6 @@ class BbrSenderTest : public ::testing::Test { "BBR sender", Perspective::IS_SERVER, 42) { - FLAGS_quic_reloadable_flag_quic_bbr_faster_startup = true; - rtt_stats_ = bbr_sender_.connection()->sent_packet_manager().GetRttStats(); sender_ = new BbrSender( rtt_stats_, diff --git a/chromium/net/quic/core/congestion_control/cubic_bytes_test.cc b/chromium/net/quic/core/congestion_control/cubic_bytes_test.cc index e64865bf7c5..cd703bcf19d 100644 --- a/chromium/net/quic/core/congestion_control/cubic_bytes_test.cc +++ b/chromium/net/quic/core/congestion_control/cubic_bytes_test.cc @@ -7,11 +7,15 @@ #include <cstdint> #include "net/quic/core/quic_flags.h" +#include "net/quic/platform/api/quic_str_cat.h" #include "net/quic/test_tools/mock_clock.h" #include "testing/gtest/include/gtest/gtest.h" +using std::string; + namespace net { namespace test { +namespace { const float kBeta = 0.7f; // Default Cubic backoff factor. const float kBetaLastMax = 0.85f; // Default Cubic backoff factor. @@ -22,17 +26,70 @@ const float kNConnectionBetaLastMax = const float kNConnectionAlpha = 3 * kNumConnections * kNumConnections * (1 - kNConnectionBeta) / (1 + kNConnectionBeta); -class CubicBytesTest : public ::testing::Test { +struct TestParams { + TestParams(bool fix_convex_mode, + bool fix_cubic_quantization, + bool fix_beta_last_max) + : fix_convex_mode(fix_convex_mode), + fix_cubic_quantization(fix_cubic_quantization), + fix_beta_last_max(fix_beta_last_max) {} + + friend std::ostream& operator<<(std::ostream& os, const TestParams& p) { + os << "{ fix_convex_mode: " << p.fix_convex_mode + << " fix_cubic_quantization: " << p.fix_cubic_quantization + << " fix_beta_last_max: " << p.fix_beta_last_max; + os << " }"; + return os; + } + + bool fix_convex_mode; + bool fix_cubic_quantization; + bool fix_beta_last_max; +}; + +string TestParamToString(const testing::TestParamInfo<TestParams>& params) { + return QuicStrCat("convex_mode_", params.param.fix_convex_mode, "_", + "cubic_quantization_", params.param.fix_cubic_quantization, + "_", "beta_last_max_", params.param.fix_beta_last_max); +} + +std::vector<TestParams> GetTestParams() { + std::vector<TestParams> params; + for (bool fix_convex_mode : {true, false}) { + for (bool fix_cubic_quantization : {true, false}) { + for (bool fix_beta_last_max : {true, false}) { + if (!FLAGS_quic_reloadable_flag_quic_fix_cubic_convex_mode && + fix_convex_mode) { + continue; + } + if (!FLAGS_quic_reloadable_flag_quic_fix_cubic_bytes_quantization && + fix_cubic_quantization) { + continue; + } + if (!FLAGS_quic_reloadable_flag_quic_fix_beta_last_max && + fix_beta_last_max) { + continue; + } + TestParams param(fix_convex_mode, fix_cubic_quantization, + fix_beta_last_max); + params.push_back(param); + } + } + } + return params; +} + +} // namespace + +class CubicBytesTest : public ::testing::TestWithParam<TestParams> { protected: CubicBytesTest() : one_ms_(QuicTime::Delta::FromMilliseconds(1)), hundred_ms_(QuicTime::Delta::FromMilliseconds(100)), cubic_(&clock_) { - cubic_.SetFixConvexMode( - FLAGS_quic_reloadable_flag_quic_fix_cubic_convex_mode); - cubic_.SetFixCubicQuantization( - FLAGS_quic_reloadable_flag_quic_fix_cubic_bytes_quantization); - cubic_.SetFixBetaLastMax(FLAGS_quic_reloadable_flag_quic_fix_beta_last_max); + cubic_.SetFixConvexMode(GetParam().fix_convex_mode); + cubic_.SetFixCubicQuantization(GetParam().fix_cubic_quantization); + cubic_.SetFixBetaLastMax(GetParam().fix_beta_last_max); } QuicByteCount RenoCwndInBytes(QuicByteCount current_cwnd) { @@ -53,7 +110,7 @@ class CubicBytesTest : public ::testing::Test { const int64_t offset = ((elapsed_time + rtt).ToMicroseconds() << 10) / 1000000; const QuicByteCount delta_congestion_window = - FLAGS_quic_reloadable_flag_quic_fix_cubic_bytes_quantization + GetParam().fix_cubic_quantization ? ((410 * offset * offset * offset) * kDefaultTCPMSS >> 40) : ((410 * offset * offset * offset) >> 40) * kDefaultTCPMSS; const QuicByteCount cubic_cwnd = initial_cwnd + delta_congestion_window; @@ -70,12 +127,17 @@ class CubicBytesTest : public ::testing::Test { CubicBytes cubic_; }; +INSTANTIATE_TEST_CASE_P(CubicBytesTests, + CubicBytesTest, + ::testing::ValuesIn(GetTestParams()), + TestParamToString); + // TODO(jokulik): The original "AboveOrigin" test, below, is very // loose. It's nearly impossible to make the test tighter without // deploying the fix for convex mode. Once cubic convex is deployed, // replace "AboveOrigin" with this test. -TEST_F(CubicBytesTest, AboveOriginWithTighterBounds) { - if (!FLAGS_quic_reloadable_flag_quic_fix_cubic_convex_mode) { +TEST_P(CubicBytesTest, AboveOriginWithTighterBounds) { + if (!GetParam().fix_convex_mode) { // Without convex mode fixed, the behavior of the algorithm is so // far from expected, there's no point in doing a tighter test. return; @@ -98,7 +160,7 @@ TEST_F(CubicBytesTest, AboveOriginWithTighterBounds) { // The maximum number of expected Reno RTTs is calculated by // finding the point where the cubic curve and the reno curve meet. const int max_reno_rtts = - FLAGS_quic_reloadable_flag_quic_fix_cubic_bytes_quantization + GetParam().fix_cubic_quantization ? std::sqrt(kNConnectionAlpha / (.4 * rtt_min_s * rtt_min_s * rtt_min_s)) - 2 @@ -130,7 +192,7 @@ TEST_F(CubicBytesTest, AboveOriginWithTighterBounds) { clock_.AdvanceTime(hundred_ms_); } - if (!FLAGS_quic_reloadable_flag_quic_fix_cubic_bytes_quantization) { + if (!GetParam().fix_cubic_quantization) { // Because our byte-wise Reno under-estimates the cwnd, we switch to // conservative increases for a few acks before switching to true // cubic increases. @@ -166,9 +228,8 @@ TEST_F(CubicBytesTest, AboveOriginWithTighterBounds) { ASSERT_EQ(expected_cwnd, current_cwnd); } -TEST_F(CubicBytesTest, AboveOrigin) { - if (!FLAGS_quic_reloadable_flag_quic_fix_cubic_convex_mode && - FLAGS_quic_reloadable_flag_quic_fix_cubic_bytes_quantization) { +TEST_P(CubicBytesTest, AboveOrigin) { + if (!GetParam().fix_convex_mode && GetParam().fix_cubic_quantization) { // Without convex mode fixed, the behavior of the algorithm does // not fit the exact pattern of this test. // TODO(jokulik): Once the convex mode fix becomes default, this @@ -181,10 +242,9 @@ TEST_F(CubicBytesTest, AboveOrigin) { QuicByteCount current_cwnd = 10 * kDefaultTCPMSS; // Without the signed-integer, cubic-convex fix, we start out in the // wrong mode. - QuicPacketCount expected_cwnd = - FLAGS_quic_reloadable_flag_quic_fix_cubic_convex_mode - ? RenoCwndInBytes(current_cwnd) - : ConservativeCwndInBytes(current_cwnd); + QuicPacketCount expected_cwnd = GetParam().fix_convex_mode + ? RenoCwndInBytes(current_cwnd) + : ConservativeCwndInBytes(current_cwnd); // Initialize the state. clock_.AdvanceTime(one_ms_); ASSERT_EQ(expected_cwnd, @@ -205,7 +265,7 @@ TEST_F(CubicBytesTest, AboveOrigin) { clock_.AdvanceTime(hundred_ms_); current_cwnd = cubic_.CongestionWindowAfterAck( kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow()); - if (FLAGS_quic_reloadable_flag_quic_fix_cubic_convex_mode) { + if (GetParam().fix_convex_mode) { // When we fix convex mode and the uint64 arithmetic, we // increase the expected_cwnd only after after the first 100ms, // rather than after the initial 1ms. @@ -236,7 +296,7 @@ TEST_F(CubicBytesTest, AboveOrigin) { initial_cwnd / kDefaultTCPMSS + (elapsed_time_s * elapsed_time_s * elapsed_time_s * 410) / 1024; // Without the convex mode fix, the result is off by one. - if (!FLAGS_quic_reloadable_flag_quic_fix_cubic_convex_mode) { + if (!GetParam().fix_convex_mode) { ++expected_cwnd; } EXPECT_EQ(expected_cwnd, current_cwnd / kDefaultTCPMSS); @@ -251,9 +311,8 @@ TEST_F(CubicBytesTest, AboveOrigin) { // // - Sets an artificially large initial cwnd to prevent Reno from the // convex increases on every ack. -TEST_F(CubicBytesTest, AboveOriginFineGrainedCubing) { - if (!FLAGS_quic_reloadable_flag_quic_fix_cubic_convex_mode || - !FLAGS_quic_reloadable_flag_quic_fix_cubic_bytes_quantization) { +TEST_P(CubicBytesTest, AboveOriginFineGrainedCubing) { + if (!GetParam().fix_convex_mode || !GetParam().fix_cubic_quantization) { // Without these two fixes, this test cannot pass. return; } @@ -293,15 +352,14 @@ TEST_F(CubicBytesTest, AboveOriginFineGrainedCubing) { } } -TEST_F(CubicBytesTest, LossEvents) { +TEST_P(CubicBytesTest, LossEvents) { const QuicTime::Delta rtt_min = hundred_ms_; QuicByteCount current_cwnd = 422 * kDefaultTCPMSS; // Without the signed-integer, cubic-convex fix, we mistakenly // increment cwnd after only one_ms_ and a single ack. - QuicPacketCount expected_cwnd = - FLAGS_quic_reloadable_flag_quic_fix_cubic_convex_mode - ? RenoCwndInBytes(current_cwnd) - : current_cwnd + kDefaultTCPMSS / 2; + QuicPacketCount expected_cwnd = GetParam().fix_convex_mode + ? RenoCwndInBytes(current_cwnd) + : current_cwnd + kDefaultTCPMSS / 2; // Initialize the state. clock_.AdvanceTime(one_ms_); EXPECT_EQ(expected_cwnd, @@ -329,11 +387,11 @@ TEST_F(CubicBytesTest, LossEvents) { current_cwnd = expected_cwnd; EXPECT_GT(pre_loss_cwnd, LastMaxCongestionWindow()); QuicByteCount expected_last_max = - FLAGS_quic_reloadable_flag_quic_fix_beta_last_max + GetParam().fix_beta_last_max ? static_cast<QuicByteCount>(pre_loss_cwnd * kNConnectionBetaLastMax) : static_cast<QuicByteCount>(pre_loss_cwnd * kBetaLastMax); EXPECT_EQ(expected_last_max, LastMaxCongestionWindow()); - if (FLAGS_quic_reloadable_flag_quic_fix_beta_last_max) { + if (GetParam().fix_beta_last_max) { EXPECT_LT(expected_cwnd, LastMaxCongestionWindow()); } else { // If we don't scale kLastBetaMax, the current window is exactly @@ -344,7 +402,7 @@ TEST_F(CubicBytesTest, LossEvents) { // Simulate an increase, and check that we are below the origin. current_cwnd = cubic_.CongestionWindowAfterAck( kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow()); - if (FLAGS_quic_reloadable_flag_quic_fix_beta_last_max) { + if (GetParam().fix_beta_last_max) { EXPECT_GT(LastMaxCongestionWindow(), current_cwnd); } else { // Without the bug fix, we will be at or above the origin. @@ -359,22 +417,21 @@ TEST_F(CubicBytesTest, LossEvents) { EXPECT_EQ(expected_cwnd, cubic_.CongestionWindowAfterPacketLoss(current_cwnd)); expected_last_max = - FLAGS_quic_reloadable_flag_quic_fix_beta_last_max + GetParam().fix_beta_last_max ? pre_loss_cwnd : static_cast<QuicByteCount>(pre_loss_cwnd * kBetaLastMax); ASSERT_EQ(expected_last_max, LastMaxCongestionWindow()); } -TEST_F(CubicBytesTest, BelowOrigin) { +TEST_P(CubicBytesTest, BelowOrigin) { // Concave growth. const QuicTime::Delta rtt_min = hundred_ms_; QuicByteCount current_cwnd = 422 * kDefaultTCPMSS; // Without the signed-integer, cubic-convex fix, we mistakenly // increment cwnd after only one_ms_ and a single ack. - QuicPacketCount expected_cwnd = - FLAGS_quic_reloadable_flag_quic_fix_cubic_convex_mode - ? RenoCwndInBytes(current_cwnd) - : current_cwnd + kDefaultTCPMSS / 2; + QuicPacketCount expected_cwnd = GetParam().fix_convex_mode + ? RenoCwndInBytes(current_cwnd) + : current_cwnd + kDefaultTCPMSS / 2; // Initialize the state. clock_.AdvanceTime(one_ms_); EXPECT_EQ(expected_cwnd, diff --git a/chromium/net/quic/core/congestion_control/cubic_test.cc b/chromium/net/quic/core/congestion_control/cubic_test.cc index f9d8aee97f3..4aeb3227141 100644 --- a/chromium/net/quic/core/congestion_control/cubic_test.cc +++ b/chromium/net/quic/core/congestion_control/cubic_test.cc @@ -7,11 +7,15 @@ #include <cstdint> #include "net/quic/core/quic_flags.h" +#include "net/quic/platform/api/quic_str_cat.h" #include "net/quic/test_tools/mock_clock.h" #include "testing/gtest/include/gtest/gtest.h" +using std::string; + namespace net { namespace test { +namespace { const float kBeta = 0.7f; // Default Cubic backoff factor. const float kBetaLastMax = 0.85f; // Default Cubic backoff factor. @@ -22,17 +26,58 @@ const float kNConnectionBetaLastMax = const float kNConnectionAlpha = 3 * kNumConnections * kNumConnections * (1 - kNConnectionBeta) / (1 + kNConnectionBeta); +struct TestParams { + TestParams(bool fix_convex_mode, bool fix_beta_last_max) + : fix_convex_mode(fix_convex_mode), + fix_beta_last_max(fix_beta_last_max) {} + + friend std::ostream& operator<<(std::ostream& os, const TestParams& p) { + os << "{ fix_convex_mode: " << p.fix_convex_mode + << " fix_beta_last_max: " << p.fix_beta_last_max; + os << " }"; + return os; + } + + bool fix_convex_mode; + bool fix_beta_last_max; +}; + +string TestParamToString(const testing::TestParamInfo<TestParams>& params) { + return QuicStrCat("convex_mode_", params.param.fix_convex_mode, "_", + "beta_last_max_", params.param.fix_beta_last_max); +} + +std::vector<TestParams> GetTestParams() { + std::vector<TestParams> params; + for (bool fix_convex_mode : {true, false}) { + for (bool fix_beta_last_max : {true, false}) { + if (!FLAGS_quic_reloadable_flag_quic_fix_cubic_convex_mode && + fix_convex_mode) { + continue; + } + if (!FLAGS_quic_reloadable_flag_quic_fix_beta_last_max && + fix_beta_last_max) { + continue; + } + TestParams param(fix_convex_mode, fix_beta_last_max); + params.push_back(param); + } + } + return params; +} + +} // namespace + // TODO(jokulik): Once we've rolled out the cubic convex fix, we will // no longer need a parameterized test. -class CubicTest : public ::testing::TestWithParam<bool> { +class CubicTest : public ::testing::TestWithParam<TestParams> { protected: CubicTest() : one_ms_(QuicTime::Delta::FromMilliseconds(1)), hundred_ms_(QuicTime::Delta::FromMilliseconds(100)), cubic_(&clock_) { - fix_convex_mode_ = GetParam(); - cubic_.SetFixConvexMode(fix_convex_mode_); - cubic_.SetFixBetaLastMax(FLAGS_quic_reloadable_flag_quic_fix_beta_last_max); + cubic_.SetFixConvexMode(GetParam().fix_convex_mode); + cubic_.SetFixBetaLastMax(GetParam().fix_beta_last_max); } QuicByteCount LastMaxCongestionWindow() { @@ -43,10 +88,12 @@ class CubicTest : public ::testing::TestWithParam<bool> { const QuicTime::Delta hundred_ms_; MockClock clock_; Cubic cubic_; - bool fix_convex_mode_; }; -INSTANTIATE_TEST_CASE_P(CubicTests, CubicTest, testing::Bool()); +INSTANTIATE_TEST_CASE_P(CubicTests, + CubicTest, + ::testing::ValuesIn(GetTestParams()), + TestParamToString); TEST_P(CubicTest, AboveOrigin) { // Convex growth. @@ -56,7 +103,7 @@ TEST_P(CubicTest, AboveOrigin) { // Without the signed-integer, cubic-convex fix, we mistakenly // increment cwnd after only one_ms_ and a single ack. QuicPacketCount expected_cwnd = - fix_convex_mode_ ? current_cwnd : current_cwnd + 1; + GetParam().fix_convex_mode ? current_cwnd : current_cwnd + 1; // Initialize the state. clock_.AdvanceTime(one_ms_); const QuicTime initial_time = clock_.ApproximateNow(); @@ -81,7 +128,7 @@ TEST_P(CubicTest, AboveOrigin) { clock_.AdvanceTime(hundred_ms_); current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min, clock_.ApproximateNow()); - if (fix_convex_mode_) { + if (GetParam().fix_convex_mode) { // When we fix convex mode and the uint64 arithmetic, we // increase the expected_cwnd only after after the first 100ms, // rather than after the initial 1ms. @@ -122,7 +169,7 @@ TEST_P(CubicTest, LossEvents) { // Without the signed-integer, cubic-convex fix, we mistakenly // increment cwnd after only one_ms_ and a single ack. QuicPacketCount expected_cwnd = - fix_convex_mode_ ? current_cwnd : current_cwnd + 1; + GetParam().fix_convex_mode ? current_cwnd : current_cwnd + 1; // Initialize the state. clock_.AdvanceTime(one_ms_); EXPECT_EQ(expected_cwnd, cubic_.CongestionWindowAfterAck( @@ -149,12 +196,12 @@ TEST_P(CubicTest, LossEvents) { current_cwnd = expected_cwnd; EXPECT_GT(pre_loss_cwnd, LastMaxCongestionWindow()); QuicByteCount expected_last_max = - FLAGS_quic_reloadable_flag_quic_fix_beta_last_max + GetParam().fix_beta_last_max ? static_cast<QuicPacketCount>(pre_loss_cwnd * kNConnectionBetaLastMax) : static_cast<QuicPacketCount>(pre_loss_cwnd * kBetaLastMax); EXPECT_EQ(expected_last_max, LastMaxCongestionWindow()); - if (FLAGS_quic_reloadable_flag_quic_fix_beta_last_max) { + if (GetParam().fix_beta_last_max) { EXPECT_LT(expected_cwnd, LastMaxCongestionWindow()); } else { // If we don't scale kLastBetaMax, the current window is exactly @@ -165,7 +212,7 @@ TEST_P(CubicTest, LossEvents) { // Simulate an increase, and check that we are below the origin. current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min, clock_.ApproximateNow()); - if (FLAGS_quic_reloadable_flag_quic_fix_beta_last_max) { + if (GetParam().fix_beta_last_max) { EXPECT_GT(LastMaxCongestionWindow(), current_cwnd); } else { // Without the bug fix, we will be at or above the origin. @@ -189,7 +236,7 @@ TEST_P(CubicTest, BelowOrigin) { // Without the signed-integer, cubic-convex fix, we mistakenly // increment cwnd after only one_ms_ and a single ack. QuicPacketCount expected_cwnd = - fix_convex_mode_ ? current_cwnd : current_cwnd + 1; + GetParam().fix_convex_mode ? current_cwnd : current_cwnd + 1; // Initialize the state. clock_.AdvanceTime(one_ms_); EXPECT_EQ(expected_cwnd, cubic_.CongestionWindowAfterAck( diff --git a/chromium/net/quic/core/congestion_control/general_loss_algorithm.cc b/chromium/net/quic/core/congestion_control/general_loss_algorithm.cc index a68520f0ac6..722134c003a 100644 --- a/chromium/net/quic/core/congestion_control/general_loss_algorithm.cc +++ b/chromium/net/quic/core/congestion_control/general_loss_algorithm.cc @@ -100,9 +100,7 @@ void GeneralLossAlgorithm::DetectLosses( // there are retransmittable packets in flight. // This also implements a timer-protected variant of FACK. if ((!it->retransmittable_frames.empty() && - (FLAGS_quic_reloadable_flag_quic_largest_sent_retransmittable - ? unacked_packets.largest_sent_retransmittable_packet() - : unacked_packets.largest_sent_packet()) <= + unacked_packets.largest_sent_retransmittable_packet() <= largest_newly_acked) || (loss_type_ == kTime || loss_type_ == kAdaptiveTime)) { QuicTime when_lost = it->sent_time + loss_delay; diff --git a/chromium/net/quic/core/congestion_control/general_loss_algorithm_test.cc b/chromium/net/quic/core/congestion_control/general_loss_algorithm_test.cc index 1e9b11e3fa6..da9d11c6aad 100644 --- a/chromium/net/quic/core/congestion_control/general_loss_algorithm_test.cc +++ b/chromium/net/quic/core/congestion_control/general_loss_algorithm_test.cc @@ -192,7 +192,6 @@ TEST_F(GeneralLossAlgorithmTest, DontEarlyRetransmitNeuteredPacket) { } TEST_F(GeneralLossAlgorithmTest, EarlyRetransmitWithLargerUnackablePackets) { - FLAGS_quic_reloadable_flag_quic_largest_sent_retransmittable = true; // Transmit 2 data packets and one ack. SendDataPacket(1); SendDataPacket(2); diff --git a/chromium/net/quic/core/congestion_control/send_algorithm_test.cc b/chromium/net/quic/core/congestion_control/send_algorithm_test.cc index 5e882ea4461..8ee348b582a 100644 --- a/chromium/net/quic/core/congestion_control/send_algorithm_test.cc +++ b/chromium/net/quic/core/congestion_control/send_algorithm_test.cc @@ -11,6 +11,7 @@ #include "net/quic/core/quic_types.h" #include "net/quic/core/quic_utils.h" #include "net/quic/platform/api/quic_logging.h" +#include "net/quic/platform/api/quic_str_cat.h" #include "net/quic/test_tools/mock_clock.h" #include "net/quic/test_tools/quic_config_peer.h" #include "net/quic/test_tools/quic_connection_peer.h" @@ -116,21 +117,37 @@ const char* CongestionControlTypeToString(CongestionControlType cc_type) { } struct TestParams { - explicit TestParams(CongestionControlType congestion_control_type) - : congestion_control_type(congestion_control_type) {} + explicit TestParams(CongestionControlType congestion_control_type, + bool fix_convex_mode, + bool fix_cubic_quantization, + bool fix_beta_last_max) + : congestion_control_type(congestion_control_type), + fix_convex_mode(fix_convex_mode), + fix_cubic_quantization(fix_cubic_quantization), + fix_beta_last_max(fix_beta_last_max) {} friend std::ostream& operator<<(std::ostream& os, const TestParams& p) { os << "{ congestion_control_type: " << CongestionControlTypeToString(p.congestion_control_type); + os << " fix_convex_mode: " << p.fix_convex_mode + << " fix_cubic_quantization: " << p.fix_cubic_quantization + << " fix_beta_last_max: " << p.fix_beta_last_max; os << " }"; return os; } CongestionControlType congestion_control_type; + bool fix_convex_mode; + bool fix_cubic_quantization; + bool fix_beta_last_max; }; string TestParamToString(const testing::TestParamInfo<TestParams>& params) { - return CongestionControlTypeToString(params.param.congestion_control_type); + return QuicStrCat( + CongestionControlTypeToString(params.param.congestion_control_type), "_", + "convex_mode_", params.param.fix_convex_mode, "_", "cubic_quantization_", + params.param.fix_cubic_quantization, "_", "beta_last_max_", + params.param.fix_beta_last_max); } // Constructs various test permutations. @@ -138,7 +155,33 @@ std::vector<TestParams> GetTestParams() { std::vector<TestParams> params; for (const CongestionControlType congestion_control_type : {kBBR, kCubic, kCubicBytes, kReno, kRenoBytes}) { - params.push_back(TestParams(congestion_control_type)); + if (congestion_control_type != kCubic && + congestion_control_type != kCubicBytes) { + params.push_back( + TestParams(congestion_control_type, false, false, false)); + continue; + } + for (bool fix_convex_mode : {true, false}) { + for (bool fix_cubic_quantization : {true, false}) { + for (bool fix_beta_last_max : {true, false}) { + if (!FLAGS_quic_reloadable_flag_quic_fix_cubic_convex_mode && + fix_convex_mode) { + continue; + } + if (!FLAGS_quic_reloadable_flag_quic_fix_cubic_bytes_quantization && + fix_cubic_quantization) { + continue; + } + if (!FLAGS_quic_reloadable_flag_quic_fix_beta_last_max && + fix_beta_last_max) { + continue; + } + TestParams param(congestion_control_type, fix_convex_mode, + fix_cubic_quantization, fix_beta_last_max); + params.push_back(param); + } + } + } } return params; } @@ -185,16 +228,14 @@ class SendAlgorithmTest : public ::testing::TestWithParam<TestParams> { void SetExperimentalOptionsInServerConfig() { QuicConfig client_config; QuicTagVector options; - if (FLAGS_quic_reloadable_flag_quic_fix_cubic_convex_mode) { + if (GetParam().fix_convex_mode) { options.push_back(kCCVX); } - if (FLAGS_quic_reloadable_flag_quic_fix_cubic_convex_mode && - FLAGS_quic_reloadable_flag_quic_fix_cubic_bytes_quantization) { - options.push_back(kCCVX); + if (GetParam().fix_cubic_quantization) { options.push_back(kCBQT); } - if (FLAGS_quic_reloadable_flag_quic_fix_beta_last_max) { + if (GetParam().fix_beta_last_max) { options.push_back(kBLMX); } diff --git a/chromium/net/quic/core/congestion_control/windowed_filter.h b/chromium/net/quic/core/congestion_control/windowed_filter.h index 451164950b0..0d56cfdf39a 100644 --- a/chromium/net/quic/core/congestion_control/windowed_filter.h +++ b/chromium/net/quic/core/congestion_control/windowed_filter.h @@ -90,7 +90,14 @@ class WindowedFilter { if (Compare()(new_sample, estimates_[1].sample)) { estimates_[1] = Sample(new_sample, new_time); estimates_[2] = estimates_[1]; +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-overflow" +#endif } else if (Compare()(new_sample, estimates_[2].sample)) { +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif estimates_[2] = Sample(new_sample, new_time); } diff --git a/chromium/net/quic/core/crypto/aead_base_decrypter.cc b/chromium/net/quic/core/crypto/aead_base_decrypter.cc index 57984245c7a..08345dfda2a 100644 --- a/chromium/net/quic/core/crypto/aead_base_decrypter.cc +++ b/chromium/net/quic/core/crypto/aead_base_decrypter.cc @@ -116,7 +116,6 @@ bool AeadBaseDecrypter::SetDiversificationNonce( } bool AeadBaseDecrypter::DecryptPacket(QuicVersion /*version*/, - QuicPathId path_id, QuicPacketNumber packet_number, StringPiece associated_data, StringPiece ciphertext, @@ -135,10 +134,7 @@ bool AeadBaseDecrypter::DecryptPacket(QuicVersion /*version*/, uint8_t nonce[sizeof(nonce_prefix_) + sizeof(packet_number)]; const size_t nonce_size = nonce_prefix_size_ + sizeof(packet_number); memcpy(nonce, nonce_prefix_, nonce_prefix_size_); - uint64_t path_id_packet_number = - QuicUtils::PackPathIdAndPacketNumber(path_id, packet_number); - memcpy(nonce + nonce_prefix_size_, &path_id_packet_number, - sizeof(path_id_packet_number)); + memcpy(nonce + nonce_prefix_size_, &packet_number, sizeof(packet_number)); if (!EVP_AEAD_CTX_open( ctx_.get(), reinterpret_cast<uint8_t*>(output), output_length, max_output_length, reinterpret_cast<const uint8_t*>(nonce), diff --git a/chromium/net/quic/core/crypto/aead_base_decrypter.h b/chromium/net/quic/core/crypto/aead_base_decrypter.h index 58f8fb595d8..23fbdd6fee4 100644 --- a/chromium/net/quic/core/crypto/aead_base_decrypter.h +++ b/chromium/net/quic/core/crypto/aead_base_decrypter.h @@ -30,7 +30,6 @@ class QUIC_EXPORT_PRIVATE AeadBaseDecrypter : public QuicDecrypter { bool SetPreliminaryKey(base::StringPiece key) override; bool SetDiversificationNonce(const DiversificationNonce& nonce) override; bool DecryptPacket(QuicVersion version, - QuicPathId path_id, QuicPacketNumber packet_number, base::StringPiece associated_data, base::StringPiece ciphertext, diff --git a/chromium/net/quic/core/crypto/aead_base_encrypter.cc b/chromium/net/quic/core/crypto/aead_base_encrypter.cc index 1420b009b16..33183898928 100644 --- a/chromium/net/quic/core/crypto/aead_base_encrypter.cc +++ b/chromium/net/quic/core/crypto/aead_base_encrypter.cc @@ -103,7 +103,6 @@ bool AeadBaseEncrypter::Encrypt(StringPiece nonce, } bool AeadBaseEncrypter::EncryptPacket(QuicVersion /*version*/, - QuicPathId path_id, QuicPacketNumber packet_number, StringPiece associated_data, StringPiece plaintext, @@ -119,10 +118,8 @@ bool AeadBaseEncrypter::EncryptPacket(QuicVersion /*version*/, const size_t nonce_size = nonce_prefix_size_ + sizeof(packet_number); QUIC_ALIGNED(4) char nonce_buffer[kMaxNonceSize]; memcpy(nonce_buffer, nonce_prefix_, nonce_prefix_size_); - uint64_t path_id_packet_number = - QuicUtils::PackPathIdAndPacketNumber(path_id, packet_number); - memcpy(nonce_buffer + nonce_prefix_size_, &path_id_packet_number, - sizeof(path_id_packet_number)); + memcpy(nonce_buffer + nonce_prefix_size_, &packet_number, + sizeof(packet_number)); if (!Encrypt(StringPiece(nonce_buffer, nonce_size), associated_data, plaintext, reinterpret_cast<unsigned char*>(output))) { diff --git a/chromium/net/quic/core/crypto/aead_base_encrypter.h b/chromium/net/quic/core/crypto/aead_base_encrypter.h index 7636276681d..fcbe03926fc 100644 --- a/chromium/net/quic/core/crypto/aead_base_encrypter.h +++ b/chromium/net/quic/core/crypto/aead_base_encrypter.h @@ -28,7 +28,6 @@ class QUIC_EXPORT_PRIVATE AeadBaseEncrypter : public QuicEncrypter { bool SetKey(base::StringPiece key) override; bool SetNoncePrefix(base::StringPiece nonce_prefix) override; bool EncryptPacket(QuicVersion version, - QuicPathId path_id, QuicPacketNumber packet_number, base::StringPiece associated_data, base::StringPiece plaintext, diff --git a/chromium/net/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc b/chromium/net/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc index 4a04d21af3d..c57d6707bfa 100644 --- a/chromium/net/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc +++ b/chromium/net/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc @@ -203,19 +203,15 @@ QuicData* DecryptWithNonce(Aes128Gcm12Decrypter* decrypter, StringPiece nonce, StringPiece associated_data, StringPiece ciphertext) { - QuicPathId path_id = kDefaultPathId; QuicPacketNumber packet_number; StringPiece nonce_prefix(nonce.data(), nonce.size() - sizeof(packet_number)); decrypter->SetNoncePrefix(nonce_prefix); memcpy(&packet_number, nonce.data() + nonce_prefix.size(), sizeof(packet_number)); - path_id = static_cast<QuicPathId>( - packet_number >> 8 * (sizeof(packet_number) - sizeof(path_id))); - packet_number &= UINT64_C(0x00FFFFFFFFFFFFFF); std::unique_ptr<char[]> output(new char[ciphertext.length()]); size_t output_length = 0; const bool success = decrypter->DecryptPacket( - QuicVersionMax(), path_id, packet_number, associated_data, ciphertext, + QuicVersionMax(), packet_number, associated_data, ciphertext, output.get(), &output_length, ciphertext.length()); if (!success) { return nullptr; diff --git a/chromium/net/quic/core/crypto/cert_compressor_test.cc b/chromium/net/quic/core/crypto/cert_compressor_test.cc index 11da03395ff..2ab9094c8d5 100644 --- a/chromium/net/quic/core/crypto/cert_compressor_test.cc +++ b/chromium/net/quic/core/crypto/cert_compressor_test.cc @@ -49,7 +49,7 @@ TEST(CertCompressor, Common) { chain.push_back("testcert"); static const uint64_t set_hash = 42; std::unique_ptr<CommonCertSets> common_sets( - CryptoTestUtils::MockCommonCertSets(chain[0], set_hash, 1)); + crypto_test_utils::MockCommonCertSets(chain[0], set_hash, 1)); const string compressed = CertCompressor::CompressChain( chain, StringPiece(reinterpret_cast<const char*>(&set_hash), sizeof(set_hash)), @@ -115,7 +115,7 @@ TEST(CertCompressor, BadInputs) { cached_certs, nullptr, &chain)); std::unique_ptr<CommonCertSets> common_sets( - CryptoTestUtils::MockCommonCertSets("foo", 42, 1)); + crypto_test_utils::MockCommonCertSets("foo", 42, 1)); /* incorrect hash and index */ EXPECT_FALSE(CertCompressor::DecompressChain( diff --git a/chromium/net/quic/core/crypto/chacha20_poly1305_decrypter.cc b/chromium/net/quic/core/crypto/chacha20_poly1305_decrypter.cc index 0c652296c62..c12b008a23b 100644 --- a/chromium/net/quic/core/crypto/chacha20_poly1305_decrypter.cc +++ b/chromium/net/quic/core/crypto/chacha20_poly1305_decrypter.cc @@ -29,11 +29,11 @@ ChaCha20Poly1305Decrypter::ChaCha20Poly1305Decrypter() ChaCha20Poly1305Decrypter::~ChaCha20Poly1305Decrypter() {} const char* ChaCha20Poly1305Decrypter::cipher_name() const { - return TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305; + return TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256; } uint32_t ChaCha20Poly1305Decrypter::cipher_id() const { - return TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305; + return TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256; } } // namespace net diff --git a/chromium/net/quic/core/crypto/chacha20_poly1305_decrypter_test.cc b/chromium/net/quic/core/crypto/chacha20_poly1305_decrypter_test.cc index 6caa52fc40c..aa766dbb214 100644 --- a/chromium/net/quic/core/crypto/chacha20_poly1305_decrypter_test.cc +++ b/chromium/net/quic/core/crypto/chacha20_poly1305_decrypter_test.cc @@ -117,19 +117,15 @@ QuicData* DecryptWithNonce(ChaCha20Poly1305Decrypter* decrypter, StringPiece nonce, StringPiece associated_data, StringPiece ciphertext) { - QuicPathId path_id = kDefaultPathId; QuicPacketNumber packet_number; StringPiece nonce_prefix(nonce.data(), nonce.size() - sizeof(packet_number)); decrypter->SetNoncePrefix(nonce_prefix); memcpy(&packet_number, nonce.data() + nonce_prefix.size(), sizeof(packet_number)); - path_id = static_cast<QuicPathId>( - packet_number >> 8 * (sizeof(packet_number) - sizeof(path_id))); - packet_number &= UINT64_C(0x00FFFFFFFFFFFFFF); std::unique_ptr<char[]> output(new char[ciphertext.length()]); size_t output_length = 0; const bool success = decrypter->DecryptPacket( - QuicVersionMax(), path_id, packet_number, associated_data, ciphertext, + QuicVersionMax(), packet_number, associated_data, ciphertext, output.get(), &output_length, ciphertext.length()); if (!success) { return nullptr; diff --git a/chromium/net/quic/core/crypto/chacha20_poly1305_encrypter_test.cc b/chromium/net/quic/core/crypto/chacha20_poly1305_encrypter_test.cc index 0ec5308728f..97528430ee3 100644 --- a/chromium/net/quic/core/crypto/chacha20_poly1305_encrypter_test.cc +++ b/chromium/net/quic/core/crypto/chacha20_poly1305_encrypter_test.cc @@ -94,18 +94,17 @@ TEST(ChaCha20Poly1305EncrypterTest, EncryptThenDecrypt) { ASSERT_TRUE(encrypter.SetNoncePrefix("abcd")); ASSERT_TRUE(decrypter.SetNoncePrefix("abcd")); - QuicPathId path_id = 0x42; QuicPacketNumber packet_number = UINT64_C(0x123456789ABC); string associated_data = "associated_data"; string plaintext = "plaintext"; char encrypted[1024]; size_t len; - ASSERT_TRUE(encrypter.EncryptPacket(QuicVersionMax(), path_id, packet_number, + ASSERT_TRUE(encrypter.EncryptPacket(QuicVersionMax(), packet_number, associated_data, plaintext, encrypted, &len, arraysize(encrypted))); StringPiece ciphertext(encrypted, len); char decrypted[1024]; - ASSERT_TRUE(decrypter.DecryptPacket(QuicVersionMax(), path_id, packet_number, + ASSERT_TRUE(decrypter.DecryptPacket(QuicVersionMax(), packet_number, associated_data, ciphertext, decrypted, &len, arraysize(decrypted))); } diff --git a/chromium/net/quic/core/crypto/channel_id_test.cc b/chromium/net/quic/core/crypto/channel_id_test.cc index 0309e65cb3a..38931fd61f1 100644 --- a/chromium/net/quic/core/crypto/channel_id_test.cc +++ b/chromium/net/quic/core/crypto/channel_id_test.cc @@ -283,7 +283,7 @@ TEST(ChannelIDTest, VerifyKnownAnswerTest) { TEST(ChannelIDTest, SignAndVerify) { std::unique_ptr<ChannelIDSource> source( - CryptoTestUtils::ChannelIDSourceForTesting()); + crypto_test_utils::ChannelIDSourceForTesting()); const string signed_data = "signed data"; const string hostname = "foo.example.com"; diff --git a/chromium/net/quic/core/crypto/crypto_framer_test.cc b/chromium/net/quic/core/crypto/crypto_framer_test.cc index 5e045a45532..4210b5f6166 100644 --- a/chromium/net/quic/core/crypto/crypto_framer_test.cc +++ b/chromium/net/quic/core/crypto/crypto_framer_test.cc @@ -274,8 +274,8 @@ TEST(CryptoFramerTest, ProcessInput) { const CryptoHandshakeMessage& message = visitor.messages_[0]; EXPECT_EQ(0xFFAA7733, message.tag()); EXPECT_EQ(2u, message.tag_value_map().size()); - EXPECT_EQ("abcdef", CryptoTestUtils::GetValueForTag(message, 0x12345678)); - EXPECT_EQ("ghijk", CryptoTestUtils::GetValueForTag(message, 0x12345679)); + EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678)); + EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679)); } TEST(CryptoFramerTest, ProcessInputWithThreeKeys) { @@ -318,9 +318,9 @@ TEST(CryptoFramerTest, ProcessInputWithThreeKeys) { const CryptoHandshakeMessage& message = visitor.messages_[0]; EXPECT_EQ(0xFFAA7733, message.tag()); EXPECT_EQ(3u, message.tag_value_map().size()); - EXPECT_EQ("abcdef", CryptoTestUtils::GetValueForTag(message, 0x12345678)); - EXPECT_EQ("ghijk", CryptoTestUtils::GetValueForTag(message, 0x12345679)); - EXPECT_EQ("lmnopqr", CryptoTestUtils::GetValueForTag(message, 0x1234567A)); + EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678)); + EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679)); + EXPECT_EQ("lmnopqr", crypto_test_utils::GetValueForTag(message, 0x1234567A)); } TEST(CryptoFramerTest, ProcessInputIncrementally) { @@ -357,8 +357,8 @@ TEST(CryptoFramerTest, ProcessInputIncrementally) { const CryptoHandshakeMessage& message = visitor.messages_[0]; EXPECT_EQ(0xFFAA7733, message.tag()); EXPECT_EQ(2u, message.tag_value_map().size()); - EXPECT_EQ("abcdef", CryptoTestUtils::GetValueForTag(message, 0x12345678)); - EXPECT_EQ("ghijk", CryptoTestUtils::GetValueForTag(message, 0x12345679)); + EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678)); + EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679)); } TEST(CryptoFramerTest, ProcessInputTagsOutOfOrder) { diff --git a/chromium/net/quic/core/crypto/crypto_handshake_message.cc b/chromium/net/quic/core/crypto/crypto_handshake_message.cc index fcaf59b5f6f..968f75564a4 100644 --- a/chromium/net/quic/core/crypto/crypto_handshake_message.cc +++ b/chromium/net/quic/core/crypto/crypto_handshake_message.cc @@ -6,18 +6,16 @@ #include <memory> -#include "base/stl_util.h" -#include "base/strings/stringprintf.h" #include "net/quic/core/crypto/crypto_framer.h" #include "net/quic/core/crypto/crypto_protocol.h" #include "net/quic/core/crypto/crypto_utils.h" #include "net/quic/core/quic_socket_address_coder.h" #include "net/quic/core/quic_utils.h" +#include "net/quic/platform/api/quic_map_util.h" +#include "net/quic/platform/api/quic_str_cat.h" #include "net/quic/platform/api/quic_text_utils.h" -using base::ContainsKey; using base::StringPiece; -using base::StringPrintf; using std::string; namespace net { @@ -112,7 +110,7 @@ bool CryptoHandshakeMessage::GetStringPiece(QuicTag tag, } bool CryptoHandshakeMessage::HasStringPiece(QuicTag tag) const { - return ContainsKey(tag_value_map_, tag); + return QuicContainsKey(tag_value_map_, tag); } QuicErrorCode CryptoHandshakeMessage::GetNthValue24(QuicTag tag, @@ -305,8 +303,8 @@ string CryptoHandshakeMessage::DebugStringInternal(size_t indent) const { } break; case kPAD: - ret += StringPrintf("(%d bytes of padding)", - static_cast<int>(it->second.size())); + ret += QuicStringPrintf("(%d bytes of padding)", + static_cast<int>(it->second.size())); done = true; break; case kSNI: diff --git a/chromium/net/quic/core/crypto/crypto_secret_boxer.cc b/chromium/net/quic/core/crypto/crypto_secret_boxer.cc index 15d0720e95c..a1091524925 100644 --- a/chromium/net/quic/core/crypto/crypto_secret_boxer.cc +++ b/chromium/net/quic/core/crypto/crypto_secret_boxer.cc @@ -108,8 +108,7 @@ bool CryptoSecretBoxer::Unbox(StringPiece ciphertext, for (const string& key : keys_) { if (decrypter->SetKey(key)) { decrypter->SetNoncePrefix(nonce_prefix); - if (decrypter->DecryptPacket(QUIC_VERSION_36, - /*path_id=*/0u, packet_number, + if (decrypter->DecryptPacket(QUIC_VERSION_36, packet_number, /*associated data=*/StringPiece(), ciphertext, plaintext, &plaintext_length, kMaxPacketSize)) { diff --git a/chromium/net/quic/core/crypto/crypto_server_test.cc b/chromium/net/quic/core/crypto/crypto_server_test.cc index 941e2fedd0b..67cd077a919 100644 --- a/chromium/net/quic/core/crypto/crypto_server_test.cc +++ b/chromium/net/quic/core/crypto/crypto_server_test.cc @@ -8,7 +8,6 @@ #include <ostream> #include <vector> -#include "crypto/secure_hash.h" #include "net/quic/core/crypto/cert_compressor.h" #include "net/quic/core/crypto/common_cert_set.h" #include "net/quic/core/crypto/crypto_handshake.h" @@ -29,6 +28,7 @@ #include "net/quic/test_tools/quic_crypto_server_config_peer.h" #include "net/quic/test_tools/quic_test_utils.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/boringssl/src/include/openssl/sha.h" using base::StringPiece; using std::string; @@ -107,7 +107,7 @@ class CryptoServerTest : public ::testing::TestWithParam<TestParams> { client_address_(QuicIpAddress::Loopback4(), 1234), config_(QuicCryptoServerConfig::TESTING, rand_, - CryptoTestUtils::ProofSourceForTesting()), + crypto_test_utils::ProofSourceForTesting()), peer_(&config_), compressed_certs_cache_( QuicCompressedCertsCache::kQuicCompressedCertsCacheSize), @@ -149,19 +149,15 @@ class CryptoServerTest : public ::testing::TestWithParam<TestParams> { pub_hex_ = "#" + QuicTextUtils::HexEncode(public_value, sizeof(public_value)); - // clang-format off - CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "AEAD", "AESG", - "KEXS", "C255", - "PUBS", pub_hex_.c_str(), - "NONC", nonce_hex_.c_str(), - "CSCT", "", - "VER\0", client_version_string_.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage client_hello = + crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"CSCT", ""}, + {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); ShouldSucceed(client_hello); // The message should be rejected because the source-address token is // missing. @@ -386,7 +382,7 @@ class CryptoServerTest : public ::testing::TestWithParam<TestParams> { } string XlctHexString() { - uint64_t xlct = CryptoTestUtils::LeafCertHashForTesting(); + uint64_t xlct = crypto_test_utils::LeafCertHashForTesting(); return "#" + QuicTextUtils::HexEncode(reinterpret_cast<char*>(&xlct), sizeof(xlct)); } @@ -434,15 +430,11 @@ TEST_P(CryptoServerTest, BadSNI) { // clang-format on for (size_t i = 0; i < arraysize(kBadSNIs); i++) { - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "SNI", kBadSNIs[i], - "VER\0", client_version_string_.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg = + crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, + {"SNI", kBadSNIs[i]}, + {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); ShouldFailMentioning("SNI", msg); const HandshakeFailureReason kRejectReasons[] = { SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; @@ -454,18 +446,14 @@ TEST_P(CryptoServerTest, DefaultCert) { // Check that the server replies with a default certificate when no SNI is // specified. The CHLO is constructed to generate a REJ with certs, so must // not contain a valid STK, and must include PDMD. - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "AEAD", "AESG", - "KEXS", "C255", - "PUBS", pub_hex_.c_str(), - "NONC", nonce_hex_.c_str(), - "PDMD", "X509", - "VER\0", client_version_string_.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg = + crypto_test_utils::CreateCHLO({{"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"PDMD", "X509"}, + {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); ShouldSucceed(msg); StringPiece cert, proof, cert_sct; @@ -483,19 +471,15 @@ TEST_P(CryptoServerTest, DefaultCert) { TEST_P(CryptoServerTest, RejectTooLarge) { // Check that the server replies with no certificate when a CHLO is // constructed with a PDMD but no SKT when the REJ would be too large. - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "AEAD", "AESG", - "KEXS", "C255", - "PUBS", pub_hex_.c_str(), - "NONC", nonce_hex_.c_str(), - "PDMD", "X509", - "VER\0", client_version_string_.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg = + crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"PDMD", "X509"}, + {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); // The REJ will be larger than the CHLO so no PROF or CRT will be sent. config_.set_chlo_multiplier(1); @@ -514,19 +498,15 @@ TEST_P(CryptoServerTest, RejectNotTooLarge) { // When the CHLO packet is large enough, ensure that a full REJ is sent. chlo_packet_size_ *= 2; - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "AEAD", "AESG", - "KEXS", "C255", - "PUBS", pub_hex_.c_str(), - "NONC", nonce_hex_.c_str(), - "PDMD", "X509", - "VER\0", client_version_string_.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg = + crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"PDMD", "X509"}, + {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); // The REJ will be larger than the CHLO so no PROF or CRT will be sent. config_.set_chlo_multiplier(1); @@ -544,20 +524,16 @@ TEST_P(CryptoServerTest, RejectNotTooLarge) { TEST_P(CryptoServerTest, RejectTooLargeButValidSTK) { // Check that the server replies with no certificate when a CHLO is // constructed with a PDMD but no SKT when the REJ would be too large. - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "AEAD", "AESG", - "KEXS", "C255", - "PUBS", pub_hex_.c_str(), - "NONC", nonce_hex_.c_str(), - "#004b5453", srct_hex_.c_str(), - "PDMD", "X509", - "VER\0", client_version_string_.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg = + crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"#004b5453", srct_hex_}, + {"PDMD", "X509"}, + {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); // The REJ will be larger than the CHLO so no PROF or CRT will be sent. config_.set_chlo_multiplier(1); @@ -575,13 +551,11 @@ TEST_P(CryptoServerTest, RejectTooLargeButValidSTK) { } TEST_P(CryptoServerTest, TooSmall) { - // clang-format off - ShouldFailMentioning("too small", CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "VER\0", client_version_string_.c_str(), - nullptr)); - // clang-format on + ShouldFailMentioning( + "too small", + crypto_test_utils::CreateCHLO( + {{"PDMD", "X509"}, {"VER\0", client_version_string_.c_str()}})); + const HandshakeFailureReason kRejectReasons[] = { SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); @@ -599,14 +573,11 @@ TEST_P(CryptoServerTest, BadSourceAddressToken) { // clang-format on for (size_t i = 0; i < arraysize(kBadSourceAddressTokens); i++) { - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "STK", kBadSourceAddressTokens[i], - "VER\0", client_version_string_.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), nullptr); - // clang-format on + CryptoHandshakeMessage msg = + crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, + {"STK", kBadSourceAddressTokens[i]}, + {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); ShouldSucceed(msg); const HandshakeFailureReason kRejectReasons[] = { SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; @@ -625,37 +596,31 @@ TEST_P(CryptoServerTest, BadClientNonce) { for (size_t i = 0; i < arraysize(kBadNonces); i++) { // Invalid nonces should be ignored, in an inchoate CHLO. - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "NONC", kBadNonces[i], - "VER\0", client_version_string_.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + + CryptoHandshakeMessage msg = + crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, + {"NONC", kBadNonces[i]}, + {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); + ShouldSucceed(msg); const HandshakeFailureReason kRejectReasons[] = { SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); // Invalid nonces should result in CLIENT_NONCE_INVALID_FAILURE. - // clang-format off - CryptoHandshakeMessage msg1 = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "AEAD", "AESG", - "KEXS", "C255", - "SCID", scid_hex_.c_str(), - "#004b5453", srct_hex_.c_str(), - "PUBS", pub_hex_.c_str(), - "NONC", kBadNonces[i], - "NONP", kBadNonces[i], - "XLCT", XlctHexString().c_str(), - "VER\0", client_version_string_.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg1 = + crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, + {"#004b5453", srct_hex_}, + {"PUBS", pub_hex_}, + {"NONC", kBadNonces[i]}, + {"NONP", kBadNonces[i]}, + {"XLCT", XlctHexString()}, + {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); ShouldSucceed(msg1); @@ -668,34 +633,26 @@ TEST_P(CryptoServerTest, BadClientNonce) { TEST_P(CryptoServerTest, NoClientNonce) { // No client nonces should result in INCHOATE_HELLO_FAILURE. - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "VER\0", client_version_string_.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + + CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO( + {{"PDMD", "X509"}, {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); ShouldSucceed(msg); const HandshakeFailureReason kRejectReasons[] = { SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); - // clang-format off - CryptoHandshakeMessage msg1 = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "AEAD", "AESG", - "KEXS", "C255", - "SCID", scid_hex_.c_str(), - "#004b5453", srct_hex_.c_str(), - "PUBS", pub_hex_.c_str(), - "XLCT", XlctHexString().c_str(), - "VER\0", client_version_string_.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg1 = + crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, + {"#004b5453", srct_hex_}, + {"PUBS", pub_hex_}, + {"XLCT", XlctHexString()}, + {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); ShouldSucceed(msg1); CheckRejectTag(); @@ -714,14 +671,9 @@ TEST_P(CryptoServerTest, DowngradeAttack) { string bad_version = QuicTagToString(QuicVersionToQuicTag(supported_versions_.back())); - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "VER\0", bad_version.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO( + {{"PDMD", "X509"}, {"VER\0", bad_version}}, kClientHelloMinimumSize); + ShouldFailMentioning("Downgrade", msg); const HandshakeFailureReason kRejectReasons[] = { SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; @@ -730,20 +682,17 @@ TEST_P(CryptoServerTest, DowngradeAttack) { TEST_P(CryptoServerTest, CorruptServerConfig) { // This tests corrupted server config. - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "AEAD", "AESG", - "KEXS", "C255", - "SCID", (string(1, 'X') + scid_hex_).c_str(), - "#004b5453", srct_hex_.c_str(), - "PUBS", pub_hex_.c_str(), - "NONC", nonce_hex_.c_str(), - "VER\0", client_version_string_.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg = + crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", (string(1, 'X') + scid_hex_)}, + {"#004b5453", srct_hex_}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); + ShouldSucceed(msg); CheckRejectTag(); const HandshakeFailureReason kRejectReasons[] = { @@ -753,21 +702,18 @@ TEST_P(CryptoServerTest, CorruptServerConfig) { TEST_P(CryptoServerTest, CorruptSourceAddressToken) { // This tests corrupted source address token. - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "AEAD", "AESG", - "KEXS", "C255", - "SCID", scid_hex_.c_str(), - "#004b5453", (string(1, 'X') + srct_hex_).c_str(), - "PUBS", pub_hex_.c_str(), - "NONC", nonce_hex_.c_str(), - "XLCT", XlctHexString().c_str(), - "VER\0", client_version_string_.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO( + {{"PDMD", "X509"}, + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, + {"#004b5453", (string(1, 'X') + srct_hex_)}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"XLCT", XlctHexString()}, + {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); + ShouldSucceed(msg); CheckRejectTag(); const HandshakeFailureReason kRejectReasons[] = { @@ -777,21 +723,18 @@ TEST_P(CryptoServerTest, CorruptSourceAddressToken) { TEST_P(CryptoServerTest, CorruptClientNonceAndSourceAddressToken) { // This test corrupts client nonce and source address token. - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "AEAD", "AESG", - "KEXS", "C255", - "SCID", scid_hex_.c_str(), - "#004b5453", (string(1, 'X') + srct_hex_).c_str(), - "PUBS", pub_hex_.c_str(), - "NONC", (string(1, 'X') + nonce_hex_).c_str(), - "XLCT", XlctHexString().c_str(), - "VER\0", client_version_string_.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO( + {{"PDMD", "X509"}, + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, + {"#004b5453", (string(1, 'X') + srct_hex_)}, + {"PUBS", pub_hex_}, + {"NONC", (string(1, 'X') + nonce_hex_)}, + {"XLCT", XlctHexString()}, + {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); + ShouldSucceed(msg); CheckRejectTag(); const HandshakeFailureReason kRejectReasons[] = { @@ -801,23 +744,20 @@ TEST_P(CryptoServerTest, CorruptClientNonceAndSourceAddressToken) { TEST_P(CryptoServerTest, CorruptMultipleTags) { // This test corrupts client nonce, server nonce and source address token. - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "AEAD", "AESG", - "KEXS", "C255", - "SCID", scid_hex_.c_str(), - "#004b5453", (string(1, 'X') + srct_hex_).c_str(), - "PUBS", pub_hex_.c_str(), - "NONC", (string(1, 'X') + nonce_hex_).c_str(), - "NONP", (string(1, 'X') + nonce_hex_).c_str(), - "SNO\0", (string(1, 'X') + nonce_hex_).c_str(), - "XLCT", XlctHexString().c_str(), - "VER\0", client_version_string_.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO( + {{"PDMD", "X509"}, + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, + {"#004b5453", (string(1, 'X') + srct_hex_)}, + {"PUBS", pub_hex_}, + {"NONC", (string(1, 'X') + nonce_hex_)}, + {"NONP", (string(1, 'X') + nonce_hex_)}, + {"SNO\0", (string(1, 'X') + nonce_hex_)}, + {"XLCT", XlctHexString()}, + {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); + ShouldSucceed(msg); CheckRejectTag(); @@ -829,22 +769,18 @@ TEST_P(CryptoServerTest, CorruptMultipleTags) { TEST_P(CryptoServerTest, NoServerNonce) { // When no server nonce is present and no strike register is configured, // the CHLO should be rejected. - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "AEAD", "AESG", - "KEXS", "C255", - "SCID", scid_hex_.c_str(), - "#004b5453", srct_hex_.c_str(), - "PUBS", pub_hex_.c_str(), - "NONC", nonce_hex_.c_str(), - "NONP", nonce_hex_.c_str(), - "XLCT", XlctHexString().c_str(), - "VER\0", client_version_string_.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg = + crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, + {"#004b5453", srct_hex_}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"NONP", nonce_hex_}, + {"XLCT", XlctHexString()}, + {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); ShouldSucceed(msg); @@ -856,22 +792,20 @@ TEST_P(CryptoServerTest, NoServerNonce) { TEST_P(CryptoServerTest, ProofForSuppliedServerConfig) { client_address_ = QuicSocketAddress(QuicIpAddress::Loopback6(), 1234); - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "AEAD", "AESG", - "KEXS", "C255", - "PDMD", "X509", - "SCID", kOldConfigId, - "#004b5453", srct_hex_.c_str(), - "PUBS", pub_hex_.c_str(), - "NONC", nonce_hex_.c_str(), - "NONP", "123456789012345678901234567890", - "VER\0", client_version_string_.c_str(), - "XLCT", XlctHexString().c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + + CryptoHandshakeMessage msg = + crypto_test_utils::CreateCHLO({{"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"PDMD", "X509"}, + {"SCID", kOldConfigId}, + {"#004b5453", srct_hex_}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"NONP", "123456789012345678901234567890"}, + {"VER\0", client_version_string_}, + {"XLCT", XlctHexString()}}, + kClientHelloMinimumSize); + ShouldSucceed(msg); // The message should be rejected because the source-address token is no // longer valid. @@ -900,9 +834,9 @@ TEST_P(CryptoServerTest, ProofForSuppliedServerConfig) { // Check that the proof in the REJ message is valid. std::unique_ptr<ProofVerifier> proof_verifier( - CryptoTestUtils::ProofVerifierForTesting()); + crypto_test_utils::ProofVerifierForTesting()); std::unique_ptr<ProofVerifyContext> verify_context( - CryptoTestUtils::ProofVerifyContextForTesting()); + crypto_test_utils::ProofVerifyContextForTesting()); std::unique_ptr<ProofVerifyDetails> details; string error_details; std::unique_ptr<ProofVerifierCallback> callback( @@ -917,51 +851,44 @@ TEST_P(CryptoServerTest, ProofForSuppliedServerConfig) { } TEST_P(CryptoServerTest, RejectInvalidXlct) { - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "AEAD", "AESG", - "KEXS", "C255", - "SCID", scid_hex_.c_str(), - "#004b5453", srct_hex_.c_str(), - "PUBS", pub_hex_.c_str(), - "NONC", nonce_hex_.c_str(), - "VER\0", client_version_string_.c_str(), - "XLCT", "#0102030405060708", - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg = + crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, + {"#004b5453", srct_hex_}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"VER\0", client_version_string_}, + {"XLCT", "#0102030405060708"}}, + kClientHelloMinimumSize); + // If replay protection isn't disabled, then // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false // and cause ProcessClientHello to exit early (and generate a REJ message). config_.set_replay_protection(false); ShouldSucceed(msg); - // clang-format off + const HandshakeFailureReason kRejectReasons[] = { - INVALID_EXPECTED_LEAF_CERTIFICATE - }; - // clang-format on + INVALID_EXPECTED_LEAF_CERTIFICATE}; + CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); } TEST_P(CryptoServerTest, ValidXlct) { - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "AEAD", "AESG", - "KEXS", "C255", - "SCID", scid_hex_.c_str(), - "#004b5453", srct_hex_.c_str(), - "PUBS", pub_hex_.c_str(), - "NONC", nonce_hex_.c_str(), - "VER\0", client_version_string_.c_str(), - "XLCT", XlctHexString().c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg = + crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, + {"#004b5453", srct_hex_}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"VER\0", client_version_string_}, + {"XLCT", XlctHexString()}}, + kClientHelloMinimumSize); + // If replay protection isn't disabled, then // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false // and cause ProcessClientHello to exit early (and generate a REJ message). @@ -972,21 +899,18 @@ TEST_P(CryptoServerTest, ValidXlct) { } TEST_P(CryptoServerTest, NonceInSHLO) { - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "AEAD", "AESG", - "KEXS", "C255", - "SCID", scid_hex_.c_str(), - "#004b5453", srct_hex_.c_str(), - "PUBS", pub_hex_.c_str(), - "NONC", nonce_hex_.c_str(), - "VER\0", client_version_string_.c_str(), - "XLCT", XlctHexString().c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg = + crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, + {"#004b5453", srct_hex_}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"VER\0", client_version_string_}, + {"XLCT", XlctHexString()}}, + kClientHelloMinimumSize); + // If replay protection isn't disabled, then // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false // and cause ProcessClientHello to exit early (and generate a REJ message). @@ -1003,19 +927,15 @@ TEST_P(CryptoServerTest, ProofSourceFailure) { // Install a ProofSource which will unconditionally fail peer_.ResetProofSource(std::unique_ptr<ProofSource>(new FailingProofSource)); - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "AEAD", "AESG", - "KEXS", "C255", - "SCID", scid_hex_.c_str(), - "PUBS", pub_hex_.c_str(), - "NONC", nonce_hex_.c_str(), - "PDMD", "X509", - "VER\0", client_version_string_.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg = + crypto_test_utils::CreateCHLO({{"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"PDMD", "X509"}, + {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); // Just ensure that we don't crash as occurred in b/33916924. ShouldFailMentioning("", msg); @@ -1030,9 +950,9 @@ TEST(CryptoServerConfigGenerationTest, Determinism) { MockClock clock; QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a, - CryptoTestUtils::ProofSourceForTesting()); + crypto_test_utils::ProofSourceForTesting()); QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b, - CryptoTestUtils::ProofSourceForTesting()); + crypto_test_utils::ProofSourceForTesting()); std::unique_ptr<CryptoHandshakeMessage> scfg_a( a.AddDefaultConfig(&rand_a, &clock, options)); std::unique_ptr<CryptoHandshakeMessage> scfg_b( @@ -1050,10 +970,10 @@ TEST(CryptoServerConfigGenerationTest, SCIDVaries) { MockClock clock; QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a, - CryptoTestUtils::ProofSourceForTesting()); + crypto_test_utils::ProofSourceForTesting()); rand_b.ChangeValue(); QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b, - CryptoTestUtils::ProofSourceForTesting()); + crypto_test_utils::ProofSourceForTesting()); std::unique_ptr<CryptoHandshakeMessage> scfg_a( a.AddDefaultConfig(&rand_a, &clock, options)); std::unique_ptr<CryptoHandshakeMessage> scfg_b( @@ -1072,7 +992,7 @@ TEST(CryptoServerConfigGenerationTest, SCIDIsHashOfServerConfig) { MockClock clock; QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a, - CryptoTestUtils::ProofSourceForTesting()); + crypto_test_utils::ProofSourceForTesting()); std::unique_ptr<CryptoHandshakeMessage> scfg( a.AddDefaultConfig(&rand_a, &clock, options)); @@ -1085,14 +1005,13 @@ TEST(CryptoServerConfigGenerationTest, SCIDIsHashOfServerConfig) { scfg->MarkDirty(); const QuicData& serialized(scfg->GetSerialized()); - std::unique_ptr<crypto::SecureHash> hash( - crypto::SecureHash::Create(crypto::SecureHash::SHA256)); - hash->Update(serialized.data(), serialized.length()); - uint8_t digest[16]; - hash->Finish(digest, sizeof(digest)); + uint8_t digest[SHA256_DIGEST_LENGTH]; + SHA256(reinterpret_cast<const uint8_t*>(serialized.data()), + serialized.length(), digest); - ASSERT_EQ(scid.size(), sizeof(digest)); - EXPECT_EQ(0, memcmp(digest, scid_str.c_str(), sizeof(digest))); + // scid is a SHA-256 hash, truncated to 16 bytes. + ASSERT_EQ(scid.size(), 16u); + EXPECT_EQ(0, memcmp(digest, scid_str.c_str(), scid.size())); } class CryptoServerTestNoConfig : public CryptoServerTest { @@ -1103,14 +1022,10 @@ class CryptoServerTestNoConfig : public CryptoServerTest { }; TEST_P(CryptoServerTestNoConfig, DontCrash) { - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "VER\0", client_version_string_.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO( + {{"PDMD", "X509"}, {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); + ShouldFailMentioning("No config", msg); const HandshakeFailureReason kRejectReasons[] = { @@ -1129,21 +1044,18 @@ class CryptoServerTestOldVersion : public CryptoServerTest { }; TEST_P(CryptoServerTestOldVersion, ServerIgnoresXlct) { - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "AEAD", "AESG", - "KEXS", "C255", - "SCID", scid_hex_.c_str(), - "#004b5453", srct_hex_.c_str(), - "PUBS", pub_hex_.c_str(), - "NONC", nonce_hex_.c_str(), - "VER\0", client_version_string_.c_str(), - "XLCT", "#0100000000000000", - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg = + crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, + {"#004b5453", srct_hex_}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"VER\0", client_version_string_}, + {"XLCT", "#0100000000000000"}}, + kClientHelloMinimumSize); + // If replay protection isn't disabled, then // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false // and cause ProcessClientHello to exit early (and generate a REJ message). @@ -1154,20 +1066,17 @@ TEST_P(CryptoServerTestOldVersion, ServerIgnoresXlct) { } TEST_P(CryptoServerTestOldVersion, XlctNotRequired) { - // clang-format off - CryptoHandshakeMessage msg = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "AEAD", "AESG", - "KEXS", "C255", - "SCID", scid_hex_.c_str(), - "#004b5453", srct_hex_.c_str(), - "PUBS", pub_hex_.c_str(), - "NONC", nonce_hex_.c_str(), - "VER\0", client_version_string_.c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on + CryptoHandshakeMessage msg = + crypto_test_utils::CreateCHLO({{"PDMD", "X509"}, + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"SCID", scid_hex_}, + {"#004b5453", srct_hex_}, + {"PUBS", pub_hex_}, + {"NONC", nonce_hex_}, + {"VER\0", client_version_string_}}, + kClientHelloMinimumSize); + // If replay protection isn't disabled, then // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false // and cause ProcessClientHello to exit early (and generate a REJ message). diff --git a/chromium/net/quic/core/crypto/crypto_utils.cc b/chromium/net/quic/core/crypto/crypto_utils.cc index 15f4a99f1f1..a60a4f28621 100644 --- a/chromium/net/quic/core/crypto/crypto_utils.cc +++ b/chromium/net/quic/core/crypto/crypto_utils.cc @@ -7,8 +7,6 @@ #include <memory> #include "crypto/hkdf.h" -#include "crypto/secure_hash.h" -#include "net/base/url_util.h" #include "net/quic/core/crypto/crypto_handshake.h" #include "net/quic/core/crypto/crypto_protocol.h" #include "net/quic/core/crypto/quic_decrypter.h" @@ -18,7 +16,7 @@ #include "net/quic/core/quic_utils.h" #include "net/quic/platform/api/quic_bug_tracker.h" #include "net/quic/platform/api/quic_logging.h" -#include "url/url_canon.h" +#include "third_party/boringssl/src/include/openssl/sha.h" using base::StringPiece; using std::string; @@ -53,38 +51,6 @@ void CryptoUtils::GenerateNonce(QuicWallTime now, } // static -bool CryptoUtils::IsValidSNI(StringPiece sni) { - // TODO(rtenneti): Support RFC2396 hostname. - // NOTE: Microsoft does NOT enforce this spec, so if we throw away hostnames - // based on the above spec, we may be losing some hostnames that windows - // would consider valid. By far the most common hostname character NOT - // accepted by the above spec is '_'. - url::CanonHostInfo host_info; - string canonicalized_host(CanonicalizeHost(sni.as_string(), &host_info)); - return !host_info.IsIPAddress() && - IsCanonicalizedHostCompliant(canonicalized_host) && - sni.find_last_of('.') != string::npos; -} - -// static -string CryptoUtils::NormalizeHostname(const char* hostname) { - url::CanonHostInfo host_info; - string host(CanonicalizeHost(hostname, &host_info)); - - // Walk backwards over the string, stopping at the first trailing dot. - size_t host_end = host.length(); - while (host_end != 0 && host[host_end - 1] == '.') { - host_end--; - } - - // Erase the trailing dots. - if (host_end != host.length()) { - host.erase(host_end, host.length() - host_end); - } - return host; -} - -// static bool CryptoUtils::DeriveKeys(StringPiece premaster_secret, QuicTag aead, StringPiece client_nonce, @@ -329,12 +295,10 @@ const char* CryptoUtils::HandshakeFailureReasonToString( void CryptoUtils::HashHandshakeMessage(const CryptoHandshakeMessage& message, string* output) { const QuicData& serialized = message.GetSerialized(); - std::unique_ptr<crypto::SecureHash> hash( - crypto::SecureHash::Create(crypto::SecureHash::SHA256)); - hash->Update(serialized.data(), serialized.length()); - uint8_t digest[32]; - hash->Finish(digest, sizeof(digest)); - output->assign(reinterpret_cast<const char*>(&digest), sizeof(digest)); + uint8_t digest[SHA256_DIGEST_LENGTH]; + SHA256(reinterpret_cast<const uint8_t*>(serialized.data()), + serialized.length(), digest); + output->assign(reinterpret_cast<const char*>(digest), sizeof(digest)); } } // namespace net diff --git a/chromium/net/quic/core/crypto/crypto_utils.h b/chromium/net/quic/core/crypto/crypto_utils.h index ee0825f3acb..e956e885dac 100644 --- a/chromium/net/quic/core/crypto/crypto_utils.h +++ b/chromium/net/quic/core/crypto/crypto_utils.h @@ -77,17 +77,6 @@ class QUIC_EXPORT_PRIVATE CryptoUtils { base::StringPiece orbit, std::string* nonce); - // Returns true if the sni is valid, false otherwise. - // (1) disallow IP addresses; - // (2) check that the hostname contains valid characters only; and - // (3) contains at least one dot. - static bool IsValidSNI(base::StringPiece sni); - - // Convert hostname to lowercase and remove the trailing '.'. - // Returns |hostname|. NormalizeHostname() doesn't support IP address - // literals. IsValidSNI() should be called before calling NormalizeHostname(). - static std::string NormalizeHostname(const char* hostname); - // DeriveKeys populates |crypters->encrypter|, |crypters->decrypter|, and // |subkey_secret| (optional -- may be null) given the contents of // |premaster_secret|, |client_nonce|, |server_nonce| and |hkdf_input|. |aead| diff --git a/chromium/net/quic/core/crypto/crypto_utils_test.cc b/chromium/net/quic/core/crypto/crypto_utils_test.cc index 0d5bea0da76..641de83b061 100644 --- a/chromium/net/quic/core/crypto/crypto_utils_test.cc +++ b/chromium/net/quic/core/crypto/crypto_utils_test.cc @@ -15,52 +15,6 @@ namespace net { namespace test { namespace { -TEST(CryptoUtilsTest, IsValidSNI) { - // IP as SNI. - EXPECT_FALSE(CryptoUtils::IsValidSNI("192.168.0.1")); - // SNI without any dot. - EXPECT_FALSE(CryptoUtils::IsValidSNI("somedomain")); - // Invalid by RFC2396 but unfortunately domains of this form exist. - EXPECT_TRUE(CryptoUtils::IsValidSNI("some_domain.com")); - // An empty string must be invalid otherwise the QUIC client will try sending - // it. - EXPECT_FALSE(CryptoUtils::IsValidSNI("")); - - // Valid SNI - EXPECT_TRUE(CryptoUtils::IsValidSNI("test.google.com")); -} - -TEST(CryptoUtilsTest, NormalizeHostname) { - struct { - const char *input, *expected; - } tests[] = { - { - "www.google.com", "www.google.com", - }, - { - "WWW.GOOGLE.COM", "www.google.com", - }, - { - "www.google.com.", "www.google.com", - }, - { - "www.google.COM.", "www.google.com", - }, - { - "www.google.com..", "www.google.com", - }, - { - "www.google.com........", "www.google.com", - }, - }; - - for (size_t i = 0; i < arraysize(tests); ++i) { - char buf[256]; - snprintf(buf, sizeof(buf), "%s", tests[i].input); - EXPECT_EQ(string(tests[i].expected), CryptoUtils::NormalizeHostname(buf)); - } -} - TEST(CryptoUtilsTest, TestExportKeyingMaterial) { const struct TestVector { // Input (strings of hexadecimal digits): diff --git a/chromium/net/quic/core/crypto/null_decrypter.cc b/chromium/net/quic/core/crypto/null_decrypter.cc index dbc6db97480..6f05b4f3c1a 100644 --- a/chromium/net/quic/core/crypto/null_decrypter.cc +++ b/chromium/net/quic/core/crypto/null_decrypter.cc @@ -38,7 +38,6 @@ bool NullDecrypter::SetDiversificationNonce(const DiversificationNonce& nonce) { } bool NullDecrypter::DecryptPacket(QuicVersion version, - QuicPathId /*path_id*/, QuicPacketNumber /*packet_number*/, StringPiece associated_data, StringPiece ciphertext, diff --git a/chromium/net/quic/core/crypto/null_decrypter.h b/chromium/net/quic/core/crypto/null_decrypter.h index 3f6aecb5e66..db93c445f51 100644 --- a/chromium/net/quic/core/crypto/null_decrypter.h +++ b/chromium/net/quic/core/crypto/null_decrypter.h @@ -33,7 +33,6 @@ class QUIC_EXPORT_PRIVATE NullDecrypter : public QuicDecrypter { bool SetPreliminaryKey(base::StringPiece key) override; bool SetDiversificationNonce(const DiversificationNonce& nonce) override; bool DecryptPacket(QuicVersion version, - QuicPathId path_id, QuicPacketNumber packet_number, base::StringPiece associated_data, base::StringPiece ciphertext, diff --git a/chromium/net/quic/core/crypto/null_decrypter_test.cc b/chromium/net/quic/core/crypto/null_decrypter_test.cc index 56d20c2ccb6..c70964ca003 100644 --- a/chromium/net/quic/core/crypto/null_decrypter_test.cc +++ b/chromium/net/quic/core/crypto/null_decrypter_test.cc @@ -24,9 +24,9 @@ TEST_F(NullDecrypterTest, DecryptClient) { NullDecrypter decrypter(Perspective::IS_SERVER); char buffer[256]; size_t length = 0; - ASSERT_TRUE(decrypter.DecryptPacket(QUIC_VERSION_37, kDefaultPathId, 0, - "hello world!", StringPiece(data, len), - buffer, &length, 256)); + ASSERT_TRUE(decrypter.DecryptPacket(QUIC_VERSION_37, 0, "hello world!", + StringPiece(data, len), buffer, &length, + 256)); EXPECT_LT(0u, length); EXPECT_EQ("goodbye!", StringPiece(buffer, length)); } @@ -43,9 +43,9 @@ TEST_F(NullDecrypterTest, DecryptServer) { NullDecrypter decrypter(Perspective::IS_CLIENT); char buffer[256]; size_t length = 0; - ASSERT_TRUE(decrypter.DecryptPacket(QUIC_VERSION_37, kDefaultPathId, 0, - "hello world!", StringPiece(data, len), - buffer, &length, 256)); + ASSERT_TRUE(decrypter.DecryptPacket(QUIC_VERSION_37, 0, "hello world!", + StringPiece(data, len), buffer, &length, + 256)); EXPECT_LT(0u, length); EXPECT_EQ("goodbye!", StringPiece(buffer, length)); } @@ -62,9 +62,9 @@ TEST_F(NullDecrypterTest, DecryptClientPre37) { NullDecrypter decrypter(Perspective::IS_CLIENT); char buffer[256]; size_t length = 0; - ASSERT_TRUE(decrypter.DecryptPacket(QUIC_VERSION_36, kDefaultPathId, 0, - "hello world!", StringPiece(data, len), - buffer, &length, 256)); + ASSERT_TRUE(decrypter.DecryptPacket(QUIC_VERSION_36, 0, "hello world!", + StringPiece(data, len), buffer, &length, + 256)); EXPECT_LT(0u, length); EXPECT_EQ("goodbye!", StringPiece(buffer, length)); } @@ -81,9 +81,9 @@ TEST_F(NullDecrypterTest, DecryptServerPre37) { NullDecrypter decrypter(Perspective::IS_SERVER); char buffer[256]; size_t length = 0; - ASSERT_TRUE(decrypter.DecryptPacket(QUIC_VERSION_36, kDefaultPathId, 0, - "hello world!", StringPiece(data, len), - buffer, &length, 256)); + ASSERT_TRUE(decrypter.DecryptPacket(QUIC_VERSION_36, 0, "hello world!", + StringPiece(data, len), buffer, &length, + 256)); EXPECT_LT(0u, length); EXPECT_EQ("goodbye!", StringPiece(buffer, length)); } @@ -100,9 +100,9 @@ TEST_F(NullDecrypterTest, BadHash) { NullDecrypter decrypter(Perspective::IS_CLIENT); char buffer[256]; size_t length = 0; - ASSERT_FALSE(decrypter.DecryptPacket(QUIC_VERSION_35, kDefaultPathId, 0, - "hello world!", StringPiece(data, len), - buffer, &length, 256)); + ASSERT_FALSE(decrypter.DecryptPacket(QUIC_VERSION_35, 0, "hello world!", + StringPiece(data, len), buffer, &length, + 256)); } TEST_F(NullDecrypterTest, ShortInput) { @@ -115,9 +115,9 @@ TEST_F(NullDecrypterTest, ShortInput) { NullDecrypter decrypter(Perspective::IS_CLIENT); char buffer[256]; size_t length = 0; - ASSERT_FALSE(decrypter.DecryptPacket(QUIC_VERSION_35, kDefaultPathId, 0, - "hello world!", StringPiece(data, len), - buffer, &length, 256)); + ASSERT_FALSE(decrypter.DecryptPacket(QUIC_VERSION_35, 0, "hello world!", + StringPiece(data, len), buffer, &length, + 256)); } } // namespace test diff --git a/chromium/net/quic/core/crypto/null_encrypter.cc b/chromium/net/quic/core/crypto/null_encrypter.cc index 986563bd852..a7cb5d1794d 100644 --- a/chromium/net/quic/core/crypto/null_encrypter.cc +++ b/chromium/net/quic/core/crypto/null_encrypter.cc @@ -26,7 +26,6 @@ bool NullEncrypter::SetNoncePrefix(StringPiece nonce_prefix) { } bool NullEncrypter::EncryptPacket(QuicVersion version, - QuicPathId /*path_id*/, QuicPacketNumber /*packet_number*/, StringPiece associated_data, StringPiece plaintext, diff --git a/chromium/net/quic/core/crypto/null_encrypter.h b/chromium/net/quic/core/crypto/null_encrypter.h index 96b1bb72562..d605d8e0667 100644 --- a/chromium/net/quic/core/crypto/null_encrypter.h +++ b/chromium/net/quic/core/crypto/null_encrypter.h @@ -27,7 +27,6 @@ class QUIC_EXPORT_PRIVATE NullEncrypter : public QuicEncrypter { bool SetKey(base::StringPiece key) override; bool SetNoncePrefix(base::StringPiece nonce_prefix) override; bool EncryptPacket(QuicVersion version, - QuicPathId path_id, QuicPacketNumber packet_number, base::StringPiece associated_data, base::StringPiece plaintext, diff --git a/chromium/net/quic/core/crypto/null_encrypter_test.cc b/chromium/net/quic/core/crypto/null_encrypter_test.cc index e0296e4915b..d875e0e7dc9 100644 --- a/chromium/net/quic/core/crypto/null_encrypter_test.cc +++ b/chromium/net/quic/core/crypto/null_encrypter_test.cc @@ -22,9 +22,9 @@ TEST_F(NullEncrypterTest, EncryptClient) { char encrypted[256]; size_t encrypted_len = 0; NullEncrypter encrypter(Perspective::IS_CLIENT); - ASSERT_TRUE(encrypter.EncryptPacket(QUIC_VERSION_37, kDefaultPathId, 0, - "hello world!", "goodbye!", encrypted, - &encrypted_len, 256)); + ASSERT_TRUE(encrypter.EncryptPacket(QUIC_VERSION_37, 0, "hello world!", + "goodbye!", encrypted, &encrypted_len, + 256)); test::CompareCharArraysWithHexError( "encrypted data", encrypted, encrypted_len, reinterpret_cast<const char*>(expected), arraysize(expected)); @@ -40,9 +40,9 @@ TEST_F(NullEncrypterTest, EncryptServer) { char encrypted[256]; size_t encrypted_len = 0; NullEncrypter encrypter(Perspective::IS_SERVER); - ASSERT_TRUE(encrypter.EncryptPacket(QUIC_VERSION_37, kDefaultPathId, 0, - "hello world!", "goodbye!", encrypted, - &encrypted_len, 256)); + ASSERT_TRUE(encrypter.EncryptPacket(QUIC_VERSION_37, 0, "hello world!", + "goodbye!", encrypted, &encrypted_len, + 256)); test::CompareCharArraysWithHexError( "encrypted data", encrypted, encrypted_len, reinterpret_cast<const char*>(expected), arraysize(expected)); @@ -58,9 +58,9 @@ TEST_F(NullEncrypterTest, EncryptClientPre37) { char encrypted[256]; size_t encrypted_len = 0; NullEncrypter encrypter(Perspective::IS_CLIENT); - ASSERT_TRUE(encrypter.EncryptPacket(QUIC_VERSION_36, kDefaultPathId, 0, - "hello world!", "goodbye!", encrypted, - &encrypted_len, 256)); + ASSERT_TRUE(encrypter.EncryptPacket(QUIC_VERSION_36, 0, "hello world!", + "goodbye!", encrypted, &encrypted_len, + 256)); test::CompareCharArraysWithHexError( "encrypted data", encrypted, encrypted_len, reinterpret_cast<const char*>(expected), arraysize(expected)); @@ -76,9 +76,9 @@ TEST_F(NullEncrypterTest, EncryptServerPre37) { char encrypted[256]; size_t encrypted_len = 0; NullEncrypter encrypter(Perspective::IS_SERVER); - ASSERT_TRUE(encrypter.EncryptPacket(QUIC_VERSION_36, kDefaultPathId, 0, - "hello world!", "goodbye!", encrypted, - &encrypted_len, 256)); + ASSERT_TRUE(encrypter.EncryptPacket(QUIC_VERSION_36, 0, "hello world!", + "goodbye!", encrypted, &encrypted_len, + 256)); test::CompareCharArraysWithHexError( "encrypted data", encrypted, encrypted_len, reinterpret_cast<const char*>(expected), arraysize(expected)); diff --git a/chromium/net/quic/core/crypto/proof_source.h b/chromium/net/quic/core/crypto/proof_source.h index 8fd184f65d2..a8d7f0a7826 100644 --- a/chromium/net/quic/core/crypto/proof_source.h +++ b/chromium/net/quic/core/crypto/proof_source.h @@ -75,9 +75,8 @@ class QUIC_EXPORT_PRIVATE ProofSource { virtual ~ProofSource() {} - // GetProof finds a certificate chain for |hostname|, sets |out_chain| to - // point to it (in leaf-first order), calculates a signature of - // |server_config| using that chain and puts the result in |out_signature|. + // GetProof finds a certificate chain for |hostname| (in leaf-first order), + // and calculates a signature of |server_config| using that chain. // // The signature uses SHA-256 as the hash function and PSS padding when the // key is RSA. @@ -85,36 +84,15 @@ class QUIC_EXPORT_PRIVATE ProofSource { // The signature uses SHA-256 as the hash function when the key is ECDSA. // The signature may use an ECDSA key. // - // |out_chain| is reference counted to avoid the (assumed) expense of copying - // out the certificates. - // - // The number of certificate chains is expected to be small and fixed, thus - // the ProofSource retains ownership of the contents of |out_chain|. The - // expectation is that they will be cached forever. - // // The signature depends on |chlo_hash| which means that the signature can not - // be cached. The caller takes ownership of |*out_signature|. + // be cached. // // |hostname| may be empty to signify that a default certificate should be // used. // - // |out_leaf_cert_sct| points to the signed timestamp (RFC6962) of the leaf - // cert. - // // This function may be called concurrently. - virtual bool GetProof(const QuicSocketAddress& server_address, - const std::string& hostname, - const std::string& server_config, - QuicVersion quic_version, - base::StringPiece chlo_hash, - const QuicTagVector& connection_options, - QuicReferenceCountedPointer<Chain>* out_chain, - QuicCryptoProof* out_proof) = 0; - - // Async version of GetProof with identical semantics, except that the results - // are delivered to |callback|. Callers should expect that |callback| might - // be invoked synchronously. The ProofSource takes ownership of |callback| in - // any case. + // + // Callers should expect that |callback| might be invoked synchronously. virtual void GetProof(const QuicSocketAddress& server_address, const std::string& hostname, const std::string& server_config, diff --git a/chromium/net/quic/core/crypto/quic_crypto_client_config.cc b/chromium/net/quic/core/crypto/quic_crypto_client_config.cc index 28c936a6efa..e4366a962a7 100644 --- a/chromium/net/quic/core/crypto/quic_crypto_client_config.cc +++ b/chromium/net/quic/core/crypto/quic_crypto_client_config.cc @@ -8,7 +8,6 @@ #include <memory> #include "base/metrics/histogram_macros.h" -#include "base/stl_util.h" #include "net/quic/core/crypto/cert_compressor.h" #include "net/quic/core/crypto/chacha20_poly1305_encrypter.h" #include "net/quic/core/crypto/channel_id.h" @@ -23,11 +22,12 @@ #include "net/quic/core/crypto/quic_random.h" #include "net/quic/core/quic_utils.h" #include "net/quic/platform/api/quic_bug_tracker.h" +#include "net/quic/platform/api/quic_hostname_utils.h" #include "net/quic/platform/api/quic_logging.h" +#include "net/quic/platform/api/quic_map_util.h" #include "net/quic/platform/api/quic_ptr_util.h" #include "net/quic/platform/api/quic_text_utils.h" -using base::ContainsKey; using base::StringPiece; using std::string; @@ -428,7 +428,7 @@ void QuicCryptoClientConfig::FillInchoateClientHello( // Server name indication. We only send SNI if it's a valid domain name, as // per the spec. - if (CryptoUtils::IsValidSNI(server_id.host())) { + if (QuicHostnameUtils::IsValidSNI(server_id.host())) { out->SetStringPiece(kSNI, server_id.host()); } out->SetValue(kVER, QuicVersionToQuicTag(preferred_version)); @@ -658,10 +658,9 @@ QuicErrorCode QuicCryptoClientConfig::FillClientHello( std::unique_ptr<char[]> output(new char[encrypted_len]); size_t output_size = 0; if (!crypters.encrypter->EncryptPacket( - preferred_version, kDefaultPathId /* path id */, - 0 /* packet number */, StringPiece() /* associated data */, - cetv_plaintext.AsStringPiece(), output.get(), &output_size, - encrypted_len)) { + preferred_version, 0 /* packet number */, + StringPiece() /* associated data */, cetv_plaintext.AsStringPiece(), + output.get(), &output_size, encrypted_len)) { *error_details = "Packet encryption failed"; return QUIC_ENCRYPTION_FAILURE; } @@ -963,7 +962,7 @@ bool QuicCryptoClientConfig::PopulateFromCanonicalConfig( QuicServerId suffix_server_id(canonical_suffixes_[i], server_id.port(), server_id.privacy_mode()); - if (!ContainsKey(canonical_server_map_, suffix_server_id)) { + if (!QuicContainsKey(canonical_server_map_, suffix_server_id)) { // This is the first host we've seen which matches the suffix, so make it // canonical. canonical_server_map_[suffix_server_id] = server_id; diff --git a/chromium/net/quic/core/crypto/quic_crypto_client_config_test.cc b/chromium/net/quic/core/crypto/quic_crypto_client_config_test.cc index 5d15437143f..68bae7d1845 100644 --- a/chromium/net/quic/core/crypto/quic_crypto_client_config_test.cc +++ b/chromium/net/quic/core/crypto/quic_crypto_client_config_test.cc @@ -168,7 +168,7 @@ TEST(QuicCryptoClientConfigTest, CachedState_InitializeFrom) { TEST(QuicCryptoClientConfigTest, InchoateChlo) { QuicCryptoClientConfig::CachedState state; - QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); + QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting()); QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params( new QuicCryptoNegotiatedParameters); CryptoHandshakeMessage msg; @@ -186,7 +186,7 @@ TEST(QuicCryptoClientConfigTest, InchoateChlo) { } TEST(QuicCryptoClientConfigTest, PreferAesGcm) { - QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); + QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting()); if (config.aead.size() > 1) EXPECT_NE(kAESG, config.aead[0]); config.PreferAesGcm(); @@ -195,7 +195,7 @@ TEST(QuicCryptoClientConfigTest, PreferAesGcm) { TEST(QuicCryptoClientConfigTest, InchoateChloSecure) { QuicCryptoClientConfig::CachedState state; - QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); + QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting()); QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params( new QuicCryptoNegotiatedParameters); CryptoHandshakeMessage msg; @@ -224,7 +224,7 @@ TEST(QuicCryptoClientConfigTest, InchoateChloSecureWithSCIDNoEXPY) { state.SetServerConfig(scfg.GetSerialized().AsStringPiece(), now, expiry, &details); - QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); + QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting()); QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params( new QuicCryptoNegotiatedParameters); CryptoHandshakeMessage msg; @@ -250,7 +250,7 @@ TEST(QuicCryptoClientConfigTest, InchoateChloSecureWithSCID) { QuicWallTime::FromUNIXSeconds(1), QuicWallTime::FromUNIXSeconds(0), &details); - QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); + QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting()); QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params( new QuicCryptoNegotiatedParameters); CryptoHandshakeMessage msg; @@ -266,7 +266,7 @@ TEST(QuicCryptoClientConfigTest, InchoateChloSecureWithSCID) { TEST(QuicCryptoClientConfigTest, FillClientHello) { QuicCryptoClientConfig::CachedState state; - QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); + QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting()); QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params( new QuicCryptoNegotiatedParameters); QuicConnectionId kConnectionId = 1234; @@ -304,7 +304,7 @@ TEST(QuicCryptoClientConfigTest, ProcessServerDowngradeAttack) { QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params( new QuicCryptoNegotiatedParameters); string error; - QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); + QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting()); EXPECT_EQ(QUIC_VERSION_NEGOTIATION_MISMATCH, config.ProcessServerHello(msg, 0, supported_versions.front(), supported_versions, &cached, out_params, @@ -313,7 +313,7 @@ TEST(QuicCryptoClientConfigTest, ProcessServerDowngradeAttack) { } TEST(QuicCryptoClientConfigTest, InitializeFrom) { - QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); + QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting()); QuicServerId canonical_server_id("www.google.com", 443, PRIVACY_MODE_DISABLED); QuicCryptoClientConfig::CachedState* state = @@ -334,7 +334,7 @@ TEST(QuicCryptoClientConfigTest, InitializeFrom) { } TEST(QuicCryptoClientConfigTest, Canonical) { - QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); + QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting()); config.AddCanonicalSuffix(".google.com"); QuicServerId canonical_id1("www.google.com", 443, PRIVACY_MODE_DISABLED); QuicServerId canonical_id2("mail.google.com", 443, PRIVACY_MODE_DISABLED); @@ -358,7 +358,7 @@ TEST(QuicCryptoClientConfigTest, Canonical) { } TEST(QuicCryptoClientConfigTest, CanonicalNotUsedIfNotValid) { - QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); + QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting()); config.AddCanonicalSuffix(".google.com"); QuicServerId canonical_id1("www.google.com", 443, PRIVACY_MODE_DISABLED); QuicServerId canonical_id2("mail.google.com", 443, PRIVACY_MODE_DISABLED); @@ -373,7 +373,7 @@ TEST(QuicCryptoClientConfigTest, CanonicalNotUsedIfNotValid) { } TEST(QuicCryptoClientConfigTest, ClearCachedStates) { - QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); + QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting()); // Create two states on different origins. struct TestCase { @@ -461,14 +461,14 @@ TEST(QuicCryptoClientConfigTest, ClearCachedStates) { TEST(QuicCryptoClientConfigTest, ProcessReject) { CryptoHandshakeMessage rej; - CryptoTestUtils::FillInDummyReject(&rej, /* stateless */ false); + crypto_test_utils::FillInDummyReject(&rej, /* stateless */ false); // Now process the rejection. QuicCryptoClientConfig::CachedState cached; QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params( new QuicCryptoNegotiatedParameters); string error; - QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); + QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting()); EXPECT_EQ(QUIC_NO_ERROR, config.ProcessRejection(rej, QuicWallTime::FromUNIXSeconds(0), AllSupportedVersions().front(), "", &cached, @@ -479,7 +479,7 @@ TEST(QuicCryptoClientConfigTest, ProcessReject) { TEST(QuicCryptoClientConfigTest, ProcessRejectWithLongTTL) { CryptoHandshakeMessage rej; - CryptoTestUtils::FillInDummyReject(&rej, /* stateless */ false); + crypto_test_utils::FillInDummyReject(&rej, /* stateless */ false); QuicTime::Delta one_week = QuicTime::Delta::FromSeconds(kNumSecondsPerWeek); int64_t long_ttl = 3 * one_week.ToSeconds(); rej.SetValue(kSTTL, long_ttl); @@ -489,7 +489,7 @@ TEST(QuicCryptoClientConfigTest, ProcessRejectWithLongTTL) { QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params( new QuicCryptoNegotiatedParameters); string error; - QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); + QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting()); EXPECT_EQ(QUIC_NO_ERROR, config.ProcessRejection(rej, QuicWallTime::FromUNIXSeconds(0), AllSupportedVersions().front(), "", &cached, @@ -505,7 +505,7 @@ TEST(QuicCryptoClientConfigTest, ProcessRejectWithLongTTL) { TEST(QuicCryptoClientConfigTest, ProcessStatelessReject) { // Create a dummy reject message and mark it as stateless. CryptoHandshakeMessage rej; - CryptoTestUtils::FillInDummyReject(&rej, /* stateless */ true); + crypto_test_utils::FillInDummyReject(&rej, /* stateless */ true); const QuicConnectionId kConnectionId = 0xdeadbeef; const string server_nonce = "SERVER_NONCE"; rej.SetValue(kRCID, kConnectionId); @@ -516,7 +516,7 @@ TEST(QuicCryptoClientConfigTest, ProcessStatelessReject) { QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params( new QuicCryptoNegotiatedParameters); string error; - QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); + QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting()); EXPECT_EQ(QUIC_NO_ERROR, config.ProcessRejection(rej, QuicWallTime::FromUNIXSeconds(0), AllSupportedVersions().front(), "", &cached, @@ -530,14 +530,14 @@ TEST(QuicCryptoClientConfigTest, BadlyFormattedStatelessReject) { // Create a dummy reject message and mark it as stateless. Do not // add an server-designated connection-id. CryptoHandshakeMessage rej; - CryptoTestUtils::FillInDummyReject(&rej, /* stateless */ true); + crypto_test_utils::FillInDummyReject(&rej, /* stateless */ true); // Now process the rejection. QuicCryptoClientConfig::CachedState cached; QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params( new QuicCryptoNegotiatedParameters); string error; - QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); + QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting()); EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, config.ProcessRejection(rej, QuicWallTime::FromUNIXSeconds(0), AllSupportedVersions().front(), "", &cached, @@ -558,7 +558,7 @@ TEST(QuicCryptoClientConfigTest, ServerNonceinSHLO) { versions.push_back(QuicVersionToQuicTag(version)); msg.SetVector(kVER, versions); - QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); + QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting()); QuicCryptoClientConfig::CachedState cached; QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params( new QuicCryptoNegotiatedParameters); diff --git a/chromium/net/quic/core/crypto/quic_crypto_server_config.cc b/chromium/net/quic/core/crypto/quic_crypto_server_config.cc index 171e4b510b9..c5582fd124d 100644 --- a/chromium/net/quic/core/crypto/quic_crypto_server_config.cc +++ b/chromium/net/quic/core/crypto/quic_crypto_server_config.cc @@ -11,7 +11,6 @@ #include "base/macros.h" #include "crypto/hkdf.h" -#include "crypto/secure_hash.h" #include "net/quic/core/crypto/aes_128_gcm_12_decrypter.h" #include "net/quic/core/crypto/aes_128_gcm_12_encrypter.h" #include "net/quic/core/crypto/cert_compressor.h" @@ -36,12 +35,13 @@ #include "net/quic/core/quic_utils.h" #include "net/quic/platform/api/quic_bug_tracker.h" #include "net/quic/platform/api/quic_clock.h" +#include "net/quic/platform/api/quic_hostname_utils.h" #include "net/quic/platform/api/quic_logging.h" #include "net/quic/platform/api/quic_reference_counted.h" #include "net/quic/platform/api/quic_text_utils.h" +#include "third_party/boringssl/src/include/openssl/sha.h" using base::StringPiece; -using crypto::SecureHash; using std::string; namespace net { @@ -262,12 +262,14 @@ QuicCryptoServerConfig::GenerateConfig(QuicRandom* rand, // thus we make it a hash of the rest of the server config. std::unique_ptr<QuicData> serialized( CryptoFramer::ConstructHandshakeMessage(msg)); - std::unique_ptr<SecureHash> hash(SecureHash::Create(SecureHash::SHA256)); - hash->Update(serialized->data(), serialized->length()); - char scid_bytes[16]; - hash->Finish(scid_bytes, sizeof(scid_bytes)); - msg.SetStringPiece(kSCID, StringPiece(scid_bytes, sizeof(scid_bytes))); + uint8_t scid_bytes[SHA256_DIGEST_LENGTH]; + SHA256(reinterpret_cast<const uint8_t*>(serialized->data()), + serialized->length(), scid_bytes); + // The SCID is a truncated SHA-256 digest. + static_assert(16 <= SHA256_DIGEST_LENGTH, "SCID length too high."); + msg.SetStringPiece( + kSCID, StringPiece(reinterpret_cast<const char*>(scid_bytes), 16)); } else { msg.SetStringPiece(kSCID, options.id); } @@ -696,31 +698,19 @@ void QuicCryptoServerConfig::ProcessClientHello( if (client_hello.GetTaglist(kCOPT, &tag_ptr, &num_tags) == QUIC_NO_ERROR) { connection_options.assign(tag_ptr, tag_ptr + num_tags); } - if (FLAGS_quic_reloadable_flag_enable_async_get_proof) { - std::unique_ptr<ProcessClientHelloCallback> cb( - new ProcessClientHelloCallback( - this, validate_chlo_result, reject_only, connection_id, - client_address, version, supported_versions, - use_stateless_rejects, server_designated_connection_id, clock, - rand, compressed_certs_cache, params, signed_config, - total_framing_overhead, chlo_packet_size, requested_config, - primary_config, std::move(done_cb))); - proof_source_->GetProof(server_address, info.sni.as_string(), - primary_config->serialized, version, chlo_hash, - connection_options, std::move(cb)); - helper.DetachCallback(); - return; - } - - QuicCryptoProof proof; - if (!proof_source_->GetProof(server_address, info.sni.as_string(), - primary_config->serialized, version, chlo_hash, - connection_options, &signed_config->chain, - &proof)) { - helper.Fail(QUIC_HANDSHAKE_FAILED, "Missing or invalid crypto proof."); - return; - } - signed_config->proof = proof; + std::unique_ptr<ProcessClientHelloCallback> cb( + new ProcessClientHelloCallback( + this, validate_chlo_result, reject_only, connection_id, + client_address, version, supported_versions, use_stateless_rejects, + server_designated_connection_id, clock, rand, + compressed_certs_cache, params, signed_config, + total_framing_overhead, chlo_packet_size, requested_config, + primary_config, std::move(done_cb))); + proof_source_->GetProof(server_address, info.sni.as_string(), + primary_config->serialized, version, chlo_hash, + connection_options, std::move(cb)); + helper.DetachCallback(); + return; } helper.DetachCallback(); @@ -854,7 +844,7 @@ void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof( std::unique_ptr<char[]> sni_tmp(new char[info.sni.length() + 1]); memcpy(sni_tmp.get(), info.sni.data(), info.sni.length()); sni_tmp[info.sni.length()] = 0; - params->sni = CryptoUtils::NormalizeHostname(sni_tmp.get()); + params->sni = QuicHostnameUtils::NormalizeHostname(sni_tmp.get()); } string hkdf_suffix; @@ -905,7 +895,7 @@ void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof( char plaintext[kMaxPacketSize]; size_t plaintext_length = 0; const bool success = crypters.decrypter->DecryptPacket( - QUIC_VERSION_35, kDefaultPathId, 0 /* packet number */, + QUIC_VERSION_35, 0 /* packet number */, StringPiece() /* associated data */, cetv_ciphertext, plaintext, &plaintext_length, kMaxPacketSize); if (!success) { @@ -1208,7 +1198,7 @@ void QuicCryptoServerConfig::EvaluateClientHello( } if (client_hello.GetStringPiece(kSNI, &info->sni) && - !CryptoUtils::IsValidSNI(info->sni)) { + !QuicHostnameUtils::IsValidSNI(info->sni)) { helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "Invalid SNI name", nullptr); return; @@ -1273,34 +1263,20 @@ void QuicCryptoServerConfig::EvaluateClientHello( if (client_hello.GetTaglist(kCOPT, &tag_ptr, &num_tags) == QUIC_NO_ERROR) { connection_options.assign(tag_ptr, tag_ptr + num_tags); } - if (FLAGS_quic_reloadable_flag_enable_async_get_proof) { - if (need_proof) { - // Make an async call to GetProof and setup the callback to trampoline - // back into EvaluateClientHelloAfterGetProof - std::unique_ptr<EvaluateClientHelloCallback> cb( - new EvaluateClientHelloCallback( - *this, found_error, server_address.host(), version, - requested_config, primary_config, signed_config, - client_hello_state, std::move(done_cb))); - proof_source_->GetProof(server_address, info->sni.as_string(), - serialized_config, version, chlo_hash, - connection_options, std::move(cb)); - helper.DetachCallback(); - return; - } - } - // No need to get a new proof if one was already generated. if (need_proof) { - QuicCryptoProof proof; - - if (proof_source_->GetProof( - server_address, info->sni.as_string(), serialized_config, version, - chlo_hash, connection_options, &signed_config->chain, &proof)) { - signed_config->proof = proof; - } else { - get_proof_failed = true; - } + // Make an async call to GetProof and setup the callback to trampoline + // back into EvaluateClientHelloAfterGetProof + std::unique_ptr<EvaluateClientHelloCallback> cb( + new EvaluateClientHelloCallback( + *this, found_error, server_address.host(), version, + requested_config, primary_config, signed_config, client_hello_state, + std::move(done_cb))); + proof_source_->GetProof(server_address, info->sni.as_string(), + serialized_config, version, chlo_hash, + connection_options, std::move(cb)); + helper.DetachCallback(); + return; } // Details are null because the synchronous version of GetProof does not @@ -1359,65 +1335,6 @@ void QuicCryptoServerConfig::EvaluateClientHelloAfterGetProof( helper.ValidationComplete(QUIC_NO_ERROR, "", std::move(proof_source_details)); } -bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage( - QuicVersion version, - StringPiece chlo_hash, - const SourceAddressTokens& previous_source_address_tokens, - const QuicSocketAddress& server_address, - const QuicIpAddress& client_ip, - const QuicClock* clock, - QuicRandom* rand, - QuicCompressedCertsCache* compressed_certs_cache, - const QuicCryptoNegotiatedParameters& params, - const CachedNetworkParameters* cached_network_params, - const QuicTagVector& connection_options, - CryptoHandshakeMessage* out) const { - string serialized; - string source_address_token; - QuicWallTime expiry_time = QuicWallTime::Zero(); - const CommonCertSets* common_cert_sets; - { - QuicReaderMutexLock locked(&configs_lock_); - serialized = primary_config_->serialized; - common_cert_sets = primary_config_->common_cert_sets; - expiry_time = primary_config_->expiry_time; - source_address_token = NewSourceAddressToken( - *primary_config_, previous_source_address_tokens, client_ip, rand, - clock->WallNow(), cached_network_params); - } - - out->set_tag(kSCUP); - out->SetStringPiece(kSCFG, serialized); - out->SetStringPiece(kSourceAddressTokenTag, source_address_token); - out->SetValue(kSTTL, - expiry_time.AbsoluteDifference(clock->WallNow()).ToSeconds()); - - QuicReferenceCountedPointer<ProofSource::Chain> chain; - QuicCryptoProof proof; - if (!proof_source_->GetProof(server_address, params.sni, serialized, version, - chlo_hash, connection_options, &chain, &proof)) { - QUIC_DVLOG(1) << "Server: failed to get proof."; - return false; - } - - const string compressed = CompressChain( - compressed_certs_cache, chain, params.client_common_set_hashes, - params.client_cached_cert_hashes, common_cert_sets); - - out->SetStringPiece(kCertificateTag, compressed); - out->SetStringPiece(kPROF, proof.signature); - if (params.sct_supported_by_client && enable_serving_sct_) { - if (proof.leaf_cert_scts.empty()) { - QUIC_LOG_EVERY_N_SEC(WARNING, 60) - << "SCT is expected but it is empty. sni: " << params.sni - << " server_address: " << server_address.ToString(); - } else { - out->SetStringPiece(kCertificateSCTTag, proof.leaf_cert_scts); - } - } - return true; -} - void QuicCryptoServerConfig::BuildServerConfigUpdateMessage( QuicVersion version, StringPiece chlo_hash, diff --git a/chromium/net/quic/core/crypto/quic_crypto_server_config.h b/chromium/net/quic/core/crypto/quic_crypto_server_config.h index 42e9e2ed342..358f6afabb6 100644 --- a/chromium/net/quic/core/crypto/quic_crypto_server_config.h +++ b/chromium/net/quic/core/crypto/quic_crypto_server_config.h @@ -327,29 +327,6 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig { QuicByteCount chlo_packet_size, std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const; - // BuildServerConfigUpdateMessage sets |out| to be a SCUP message containing - // the current primary config, an up to date source-address token, and cert - // chain and proof in the case of secure QUIC. Returns true if successfully - // filled |out|. - // - // |cached_network_params| is optional, and can be nullptr. - // - // TODO(gredner): remove this when - // FLAGS_quic_reloadable_flag_enable_async_get_proof is removed. - bool BuildServerConfigUpdateMessage( - QuicVersion version, - base::StringPiece chlo_hash, - const SourceAddressTokens& previous_source_address_tokens, - const QuicSocketAddress& server_address, - const QuicIpAddress& client_ip, - const QuicClock* clock, - QuicRandom* rand, - QuicCompressedCertsCache* compressed_certs_cache, - const QuicCryptoNegotiatedParameters& params, - const CachedNetworkParameters* cached_network_params, - const QuicTagVector& connection_options, - CryptoHandshakeMessage* out) const; - // BuildServerConfigUpdateMessage invokes |cb| with a SCUP message containing // the current primary config, an up to date source-address token, and cert // chain and proof in the case of secure QUIC. Passes true to |cb| if the @@ -357,9 +334,6 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig { // assumes ownership of |cb|. // // |cached_network_params| is optional, and can be nullptr. - // - // TODO(gredner): This method is an async version of the above. The - // synchronous version will eventually be removed. void BuildServerConfigUpdateMessage( QuicVersion version, base::StringPiece chlo_hash, diff --git a/chromium/net/quic/core/crypto/quic_crypto_server_config_test.cc b/chromium/net/quic/core/crypto/quic_crypto_server_config_test.cc index da7f858c4c3..c002e57f928 100644 --- a/chromium/net/quic/core/crypto/quic_crypto_server_config_test.cc +++ b/chromium/net/quic/core/crypto/quic_crypto_server_config_test.cc @@ -30,7 +30,7 @@ namespace test { TEST(QuicCryptoServerConfigTest, ServerConfig) { QuicRandom* rand = QuicRandom::GetInstance(); QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand, - CryptoTestUtils::ProofSourceForTesting()); + crypto_test_utils::ProofSourceForTesting()); MockClock clock; std::unique_ptr<CryptoHandshakeMessage> message(server.AddDefaultConfig( @@ -52,7 +52,7 @@ TEST(QuicCryptoServerConfigTest, CompressCerts) { QuicRandom* rand = QuicRandom::GetInstance(); QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand, - CryptoTestUtils::ProofSourceForTesting()); + crypto_test_utils::ProofSourceForTesting()); QuicCryptoServerConfigPeer peer(&server); std::vector<string> certs = {"testcert"}; @@ -71,7 +71,7 @@ TEST(QuicCryptoServerConfigTest, CompressSameCertsTwice) { QuicRandom* rand = QuicRandom::GetInstance(); QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand, - CryptoTestUtils::ProofSourceForTesting()); + crypto_test_utils::ProofSourceForTesting()); QuicCryptoServerConfigPeer peer(&server); // Compress the certs for the first time. @@ -100,7 +100,7 @@ TEST(QuicCryptoServerConfigTest, CompressDifferentCerts) { QuicRandom* rand = QuicRandom::GetInstance(); QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand, - CryptoTestUtils::ProofSourceForTesting()); + crypto_test_utils::ProofSourceForTesting()); QuicCryptoServerConfigPeer peer(&server); std::vector<string> certs = {"testcert"}; @@ -124,7 +124,7 @@ TEST(QuicCryptoServerConfigTest, CompressDifferentCerts) { // Compress a similar certs which only differs in common certs field. static const uint64_t set_hash = 42; std::unique_ptr<CommonCertSets> common_sets( - CryptoTestUtils::MockCommonCertSets(certs[0], set_hash, 1)); + crypto_test_utils::MockCommonCertSets(certs[0], set_hash, 1)); StringPiece different_common_certs(reinterpret_cast<const char*>(&set_hash), sizeof(set_hash)); string compressed3 = QuicCryptoServerConfigPeer::CompressChain( @@ -143,7 +143,7 @@ class SourceAddressTokenTest : public ::testing::Test { rand_(QuicRandom::GetInstance()), server_(QuicCryptoServerConfig::TESTING, rand_, - CryptoTestUtils::ProofSourceForTesting()), + crypto_test_utils::ProofSourceForTesting()), peer_(&server_) { // Advance the clock to some non-zero time. clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1000000)); @@ -281,7 +281,7 @@ class CryptoServerConfigsTest : public ::testing::Test { : rand_(QuicRandom::GetInstance()), config_(QuicCryptoServerConfig::TESTING, rand_, - CryptoTestUtils::ProofSourceForTesting()), + crypto_test_utils::ProofSourceForTesting()), test_peer_(&config_) {} void SetUp() override { @@ -289,49 +289,42 @@ class CryptoServerConfigsTest : public ::testing::Test { } // SetConfigs constructs suitable config protobufs and calls SetConfigs on - // |config_|. The arguments are given as nullptr-terminated pairs. The first - // of each pair is the server config ID of a Config. The second is the - // |primary_time| of that Config, given in epoch seconds. (Although note that, - // in these tests, time is set to 1000 seconds since the epoch.) For example: - // SetConfigs(nullptr); // calls |config_.SetConfigs| with no protobufs. + // |config_|. + // Each struct in the input vector contains 3 elements. + // The first is the server config ID of a Config. The second is + // the |primary_time| of that Config, given in epoch seconds. (Although note + // that, in these tests, time is set to 1000 seconds since the epoch.). + // The third is the priority. + // + // For example: + // SetConfigs(std::vector<ServerConfigIDWithTimeAndPriority>()); // calls + // |config_.SetConfigs| with no protobufs. // // // Calls |config_.SetConfigs| with two protobufs: one for a Config with // // a |primary_time| of 900 and priority 1, and another with // // a |primary_time| of 1000 and priority 2. // CheckConfigs( - // "id1", 900, 1, - // "id2", 1000, 2, - // nullptr); + // {{"id1", 900, 1}, + // {"id2", 1000, 2}}); // // If the server config id starts with "INVALID" then the generated protobuf // will be invalid. - void SetConfigs(const char* server_config_id1, ...) { + struct ServerConfigIDWithTimeAndPriority { + ServerConfigID server_config_id; + int primary_time; + int priority; + }; + void SetConfigs(std::vector<ServerConfigIDWithTimeAndPriority> configs) { const char kOrbit[] = "12345678"; - va_list ap; - va_start(ap, server_config_id1); bool has_invalid = false; - bool is_empty = true; std::vector<std::unique_ptr<QuicServerConfigProtobuf>> protobufs; - bool first = true; - for (;;) { - const char* server_config_id; - if (first) { - server_config_id = server_config_id1; - first = false; - } else { - server_config_id = va_arg(ap, const char*); - } - - if (!server_config_id) { - break; - } - - is_empty = false; - int primary_time = va_arg(ap, int); - int priority = va_arg(ap, int); + for (const auto& config : configs) { + const ServerConfigID& server_config_id = config.server_config_id; + const int primary_time = config.primary_time; + const int priority = config.priority; QuicCryptoServerConfig::ConfigOptions options; options.id = server_config_id; @@ -347,7 +340,7 @@ class CryptoServerConfigsTest : public ::testing::Test { protobufs.push_back(std::move(protobuf)); } - ASSERT_EQ(!has_invalid && !is_empty, + ASSERT_EQ(!has_invalid && !configs.empty(), config_.SetConfigs(protobufs, clock_.WallNow())); } @@ -359,104 +352,104 @@ class CryptoServerConfigsTest : public ::testing::Test { }; TEST_F(CryptoServerConfigsTest, NoConfigs) { - test_peer_.CheckConfigs(nullptr); + test_peer_.CheckConfigs(std::vector<std::pair<string, bool>>()); } TEST_F(CryptoServerConfigsTest, MakePrimaryFirst) { // Make sure that "b" is primary even though "a" comes first. - SetConfigs("a", 1100, 1, "b", 900, 1, nullptr); - test_peer_.CheckConfigs("a", false, "b", true, nullptr); + SetConfigs({{"a", 1100, 1}, {"b", 900, 1}}); + test_peer_.CheckConfigs({{"a", false}, {"b", true}}); } TEST_F(CryptoServerConfigsTest, MakePrimarySecond) { // Make sure that a remains primary after b is added. - SetConfigs("a", 900, 1, "b", 1100, 1, nullptr); - test_peer_.CheckConfigs("a", true, "b", false, nullptr); + SetConfigs({{"a", 900, 1}, {"b", 1100, 1}}); + test_peer_.CheckConfigs({{"a", true}, {"b", false}}); } TEST_F(CryptoServerConfigsTest, Delete) { // Ensure that configs get deleted when removed. - SetConfigs("a", 800, 1, "b", 900, 1, "c", 1100, 1, nullptr); - test_peer_.CheckConfigs("a", false, "b", true, "c", false, nullptr); - SetConfigs("b", 900, 1, "c", 1100, 1, nullptr); - test_peer_.CheckConfigs("b", true, "c", false, nullptr); + SetConfigs({{"a", 800, 1}, {"b", 900, 1}, {"c", 1100, 1}}); + test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}}); + SetConfigs({{"b", 900, 1}, {"c", 1100, 1}}); + test_peer_.CheckConfigs({{"b", true}, {"c", false}}); } TEST_F(CryptoServerConfigsTest, DeletePrimary) { // Ensure that deleting the primary config works. - SetConfigs("a", 800, 1, "b", 900, 1, "c", 1100, 1, nullptr); - test_peer_.CheckConfigs("a", false, "b", true, "c", false, nullptr); - SetConfigs("a", 800, 1, "c", 1100, 1, nullptr); - test_peer_.CheckConfigs("a", true, "c", false, nullptr); + SetConfigs({{"a", 800, 1}, {"b", 900, 1}, {"c", 1100, 1}}); + test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}}); + SetConfigs({{"a", 800, 1}, {"c", 1100, 1}}); + test_peer_.CheckConfigs({{"a", true}, {"c", false}}); } TEST_F(CryptoServerConfigsTest, FailIfDeletingAllConfigs) { // Ensure that configs get deleted when removed. - SetConfigs("a", 800, 1, "b", 900, 1, nullptr); - test_peer_.CheckConfigs("a", false, "b", true, nullptr); - SetConfigs(nullptr); + SetConfigs({{"a", 800, 1}, {"b", 900, 1}}); + test_peer_.CheckConfigs({{"a", false}, {"b", true}}); + SetConfigs(std::vector<ServerConfigIDWithTimeAndPriority>()); // Config change is rejected, still using old configs. - test_peer_.CheckConfigs("a", false, "b", true, nullptr); + test_peer_.CheckConfigs({{"a", false}, {"b", true}}); } TEST_F(CryptoServerConfigsTest, ChangePrimaryTime) { // Check that updates to primary time get picked up. - SetConfigs("a", 400, 1, "b", 800, 1, "c", 1200, 1, nullptr); + SetConfigs({{"a", 400, 1}, {"b", 800, 1}, {"c", 1200, 1}}); test_peer_.SelectNewPrimaryConfig(500); - test_peer_.CheckConfigs("a", true, "b", false, "c", false, nullptr); - SetConfigs("a", 1200, 1, "b", 800, 1, "c", 400, 1, nullptr); + test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}}); + SetConfigs({{"a", 1200, 1}, {"b", 800, 1}, {"c", 400, 1}}); test_peer_.SelectNewPrimaryConfig(500); - test_peer_.CheckConfigs("a", false, "b", false, "c", true, nullptr); + test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}}); } TEST_F(CryptoServerConfigsTest, AllConfigsInThePast) { // Check that the most recent config is selected. - SetConfigs("a", 400, 1, "b", 800, 1, "c", 1200, 1, nullptr); + SetConfigs({{"a", 400, 1}, {"b", 800, 1}, {"c", 1200, 1}}); test_peer_.SelectNewPrimaryConfig(1500); - test_peer_.CheckConfigs("a", false, "b", false, "c", true, nullptr); + test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}}); } TEST_F(CryptoServerConfigsTest, AllConfigsInTheFuture) { // Check that the first config is selected. - SetConfigs("a", 400, 1, "b", 800, 1, "c", 1200, 1, nullptr); + SetConfigs({{"a", 400, 1}, {"b", 800, 1}, {"c", 1200, 1}}); test_peer_.SelectNewPrimaryConfig(100); - test_peer_.CheckConfigs("a", true, "b", false, "c", false, nullptr); + test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}}); } TEST_F(CryptoServerConfigsTest, SortByPriority) { // Check that priority is used to decide on a primary config when // configs have the same primary time. - SetConfigs("a", 900, 1, "b", 900, 2, "c", 900, 3, nullptr); - test_peer_.CheckConfigs("a", true, "b", false, "c", false, nullptr); + SetConfigs({{"a", 900, 1}, {"b", 900, 2}, {"c", 900, 3}}); + test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}}); test_peer_.SelectNewPrimaryConfig(800); - test_peer_.CheckConfigs("a", true, "b", false, "c", false, nullptr); + test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}}); test_peer_.SelectNewPrimaryConfig(1000); - test_peer_.CheckConfigs("a", true, "b", false, "c", false, nullptr); + test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}}); // Change priorities and expect sort order to change. - SetConfigs("a", 900, 2, "b", 900, 1, "c", 900, 0, nullptr); - test_peer_.CheckConfigs("a", false, "b", false, "c", true, nullptr); + SetConfigs({{"a", 900, 2}, {"b", 900, 1}, {"c", 900, 0}}); + test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}}); test_peer_.SelectNewPrimaryConfig(800); - test_peer_.CheckConfigs("a", false, "b", false, "c", true, nullptr); + test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}}); test_peer_.SelectNewPrimaryConfig(1000); - test_peer_.CheckConfigs("a", false, "b", false, "c", true, nullptr); + test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}}); } TEST_F(CryptoServerConfigsTest, AdvancePrimary) { // Check that a new primary config is enabled at the right time. - SetConfigs("a", 900, 1, "b", 1100, 1, nullptr); + SetConfigs({{"a", 900, 1}, {"b", 1100, 1}}); test_peer_.SelectNewPrimaryConfig(1000); - test_peer_.CheckConfigs("a", true, "b", false, nullptr); + test_peer_.CheckConfigs({{"a", true}, {"b", false}}); test_peer_.SelectNewPrimaryConfig(1101); - test_peer_.CheckConfigs("a", false, "b", true, nullptr); + test_peer_.CheckConfigs({{"a", false}, {"b", true}}); } TEST_F(CryptoServerConfigsTest, InvalidConfigs) { // Ensure that invalid configs don't change anything. - SetConfigs("a", 800, 1, "b", 900, 1, "c", 1100, 1, nullptr); - test_peer_.CheckConfigs("a", false, "b", true, "c", false, nullptr); - SetConfigs("a", 800, 1, "c", 1100, 1, "INVALID1", 1000, 1, nullptr); - test_peer_.CheckConfigs("a", false, "b", true, "c", false, nullptr); + SetConfigs({{"a", 800, 1}, {"b", 900, 1}, {"c", 1100, 1}}); + test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}}); + SetConfigs({{"a", 800, 1}, {"c", 1100, 1}, {"INVALID1", 1000, 1}}); + test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}}); } } // namespace test diff --git a/chromium/net/quic/core/crypto/quic_decrypter.h b/chromium/net/quic/core/crypto/quic_decrypter.h index 824cf929f3e..a47643ea8b7 100644 --- a/chromium/net/quic/core/crypto/quic_decrypter.h +++ b/chromium/net/quic/core/crypto/quic_decrypter.h @@ -67,7 +67,6 @@ class QUIC_EXPORT_PRIVATE QuicDecrypter { // TODO(wtc): add a way for DecryptPacket to report decryption failure due // to non-authentic inputs, as opposed to other reasons for failure. virtual bool DecryptPacket(QuicVersion version, - QuicPathId path_id, QuicPacketNumber packet_number, base::StringPiece associated_data, base::StringPiece ciphertext, diff --git a/chromium/net/quic/core/crypto/quic_encrypter.h b/chromium/net/quic/core/crypto/quic_encrypter.h index 67398672495..40d079ce4a1 100644 --- a/chromium/net/quic/core/crypto/quic_encrypter.h +++ b/chromium/net/quic/core/crypto/quic_encrypter.h @@ -49,7 +49,6 @@ class QUIC_EXPORT_PRIVATE QuicEncrypter { // |associated_data|. If |output| overlaps with |plaintext| then // |plaintext| must be <= |output|. virtual bool EncryptPacket(QuicVersion version, - QuicPathId path_id, QuicPacketNumber packet_number, base::StringPiece associated_data, base::StringPiece plaintext, diff --git a/chromium/net/quic/core/frames/quic_ack_frame.h b/chromium/net/quic/core/frames/quic_ack_frame.h index 9e76aee8dc7..816a4ace874 100644 --- a/chromium/net/quic/core/frames/quic_ack_frame.h +++ b/chromium/net/quic/core/frames/quic_ack_frame.h @@ -9,8 +9,8 @@ #include <string> #include "base/strings/string_piece.h" -#include "net/quic/core/interval_set.h" #include "net/quic/core/quic_types.h" +#include "net/quic/platform/api/quic_containers.h" #include "net/quic/platform/api/quic_export.h" namespace net { @@ -20,9 +20,9 @@ namespace net { // larger new packet numbers are added, with the occasional random access. class QUIC_EXPORT_PRIVATE PacketNumberQueue { public: - using const_iterator = IntervalSet<QuicPacketNumber>::const_iterator; + using const_iterator = QuicIntervalSet<QuicPacketNumber>::const_iterator; using const_reverse_iterator = - IntervalSet<QuicPacketNumber>::const_reverse_iterator; + QuicIntervalSet<QuicPacketNumber>::const_reverse_iterator; PacketNumberQueue(); PacketNumberQueue(const PacketNumberQueue& other); @@ -92,7 +92,7 @@ class QUIC_EXPORT_PRIVATE PacketNumberQueue { const PacketNumberQueue& q); private: - IntervalSet<QuicPacketNumber> packet_number_intervals_; + QuicIntervalSet<QuicPacketNumber> packet_number_intervals_; }; struct QUIC_EXPORT_PRIVATE QuicAckFrame { diff --git a/chromium/net/quic/core/interval.h b/chromium/net/quic/core/interval.h deleted file mode 100644 index eaae9c98b58..00000000000 --- a/chromium/net/quic/core/interval.h +++ /dev/null @@ -1,302 +0,0 @@ -// Copyright 2015 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. -// -// An Interval<T> is a data structure used to represent a contiguous, mutable -// range over an ordered type T. Supported operations include testing a value to -// see whether it is included in the interval, comparing two intervals, and -// performing their union, intersection, and difference. For the purposes of -// this library, an "ordered type" is any type that induces a total order on its -// values via its less-than operator (operator<()). Examples of such types are -// basic arithmetic types like int and double as well as class types like -// string. -// -// An Interval<T> is represented using the usual C++ STL convention, namely as -// the half-open interval [min, max). A point p is considered to be contained in -// the interval iff p >= min && p < max. One consequence of this definition is -// that for any non-empty interval, min is contained in the interval but max is -// not. There is no canonical representation for the empty interval; rather, any -// interval where max <= min is regarded as empty. As a consequence, two empty -// intervals will still compare as equal despite possibly having different -// underlying min() or max() values. Also beware of the terminology used here: -// the library uses the terms "min" and "max" rather than "begin" and "end" as -// is conventional for the STL. -// -// T is required to be default- and copy-constructable, to have an assignment -// operator, and the full complement of comparison operators (<, <=, ==, !=, >=, -// >). A difference operator (operator-()) is required if Interval<T>::Length -// is used. -// -// For equality comparisons, Interval<T> supports an Equals() method and an -// operator==() which delegates to it. Two intervals are considered equal if -// either they are both empty or if their corresponding min and max fields -// compare equal. For ordered comparisons, Interval<T> also provides the -// comparator Interval<T>::Less and an operator<() which delegates to it. -// Unfortunately this comparator is currently buggy because its behavior is -// inconsistent with Equals(): two empty ranges with different representations -// may be regarded as equivalent by Equals() but regarded as different by -// the comparator. Bug 9240050 has been created to address this. -// -// This class is thread-compatible if T is thread-compatible. (See -// go/thread-compatible). -// -// Examples: -// Interval<int> r1(0, 100); // The interval [0, 100). -// EXPECT_TRUE(r1.Contains(0)); -// EXPECT_TRUE(r1.Contains(50)); -// EXPECT_FALSE(r1.Contains(100)); // 100 is just outside the interval. -// -// Interval<int> r2(50, 150); // The interval [50, 150). -// EXPECT_TRUE(r1.Intersects(r2)); -// EXPECT_FALSE(r1.Contains(r2)); -// EXPECT_TRUE(r1.IntersectWith(r2)); // Mutates r1. -// EXPECT_EQ(Interval<int>(50, 100), r1); // r1 is now [50, 100). -// -// Interval<int> r3(1000, 2000); // The interval [1000, 2000). -// EXPECT_TRUE(r1.IntersectWith(r3)); // Mutates r1. -// EXPECT_TRUE(r1.Empty()); // Now r1 is empty. -// EXPECT_FALSE(r1.Contains(r1.min())); // e.g. doesn't contain its own min. - -#ifndef NET_QUIC_CORE_INTERVAL_H_ -#define NET_QUIC_CORE_INTERVAL_H_ - -#include <stddef.h> - -#include <algorithm> -#include <functional> -#include <ostream> -#include <string> -#include <utility> -#include <vector> - -namespace net { - -template <typename T> -class Interval { - private: -// TODO(rtenneti): Implement after suupport for std::decay. -#if 0 - // Type trait for deriving the return type for Interval::Length. If - // operator-() is not defined for T, then the return type is void. This makes - // the signature for Length compile so that the class can be used for such T, - // but code that calls Length would still generate a compilation error. - template <typename U> - class DiffTypeOrVoid { - private: - template <typename V> - static auto f(const V* v) -> decltype(*v - *v); - template <typename V> - static void f(...); - - public: - using type = typename std::decay<decltype(f<U>(0))>::type; - }; -#endif - - public: - // Compatibility alias. - using Less = std::less<Interval>; - - // Construct an Interval representing an empty interval. - Interval() : min_(), max_() {} - - // Construct an Interval representing the interval [min, max). If min < max, - // the constructed object will represent the non-empty interval containing all - // values from min up to (but not including) max. On the other hand, if min >= - // max, the constructed object will represent the empty interval. - Interval(const T& min, const T& max) : min_(min), max_(max) {} - - const T& min() const { return min_; } - const T& max() const { return max_; } - void SetMin(const T& t) { min_ = t; } - void SetMax(const T& t) { max_ = t; } - - void Set(const T& min, const T& max) { - SetMin(min); - SetMax(max); - } - - void Clear() { *this = {}; } - void CopyFrom(const Interval& i) { *this = i; } - bool Equals(const Interval& i) const { return *this == i; } - bool Empty() const { return min() >= max(); } - - // Returns the length of this interval. The value returned is zero if - // IsEmpty() is true; otherwise the value returned is max() - min(). - const T Length() const { return (min_ >= max_ ? min_ : max_) - min_; } - - // Returns true iff t >= min() && t < max(). - bool Contains(const T& t) const { return min() <= t && max() > t; } - - // Returns true iff *this and i are non-empty, and *this includes i. "*this - // includes i" means that for all t, if i.Contains(t) then this->Contains(t). - // Note the unintuitive consequence of this definition: this method always - // returns false when i is the empty interval. - bool Contains(const Interval& i) const { - return !Empty() && !i.Empty() && min() <= i.min() && max() >= i.max(); - } - - // Returns true iff there exists some point t for which this->Contains(t) && - // i.Contains(t) evaluates to true, i.e. if the intersection is non-empty. - bool Intersects(const Interval& i) const { - return !Empty() && !i.Empty() && min() < i.max() && max() > i.min(); - } - - // Returns true iff there exists some point t for which this->Contains(t) && - // i.Contains(t) evaluates to true, i.e. if the intersection is non-empty. - // Furthermore, if the intersection is non-empty and the intersection pointer - // is not null, this method stores the calculated intersection in - // *intersection. - bool Intersects(const Interval& i, Interval* out) const; - - // Sets *this to be the intersection of itself with i. Returns true iff - // *this was modified. - bool IntersectWith(const Interval& i); - - // Calculates the smallest interval containing both *this i, and updates *this - // to represent that interval, and returns true iff *this was modified. - bool SpanningUnion(const Interval& i); - - // Determines the difference between two intervals as in - // Difference(Interval&, vector*), but stores the results directly in out - // parameters rather than dynamically allocating an Interval* and appending - // it to a vector. If two results are generated, the one with the smaller - // value of min() will be stored in *lo and the other in *hi. Otherwise (if - // fewer than two results are generated), unused arguments will be set to the - // empty interval (it is possible that *lo will be empty and *hi non-empty). - // The method returns true iff the intersection of *this and i is non-empty. - bool Difference(const Interval& i, Interval* lo, Interval* hi) const; - - friend bool operator==(const Interval& a, const Interval& b) { - bool ae = a.Empty(); - bool be = b.Empty(); - if (ae && be) - return true; // All empties are equal. - if (ae != be) - return false; // Empty cannot equal nonempty. - return a.min() == b.min() && a.max() == b.max(); - } - - friend bool operator!=(const Interval& a, const Interval& b) { - return !(a == b); - } - - // Defines a comparator which can be used to induce an order on Intervals, so - // that, for example, they can be stored in an ordered container such as - // std::set. The ordering is arbitrary, but does provide the guarantee that, - // for non-empty intervals X and Y, if X contains Y, then X <= Y. - // TODO(kosak): The current implementation of this comparator has a problem - // because the ordering it induces is inconsistent with that of Equals(). In - // particular, this comparator does not properly consider all empty intervals - // equivalent. Bug b/9240050 has been created to track this. - friend bool operator<(const Interval& a, const Interval& b) { - return a.min() < b.min() || (a.min() == b.min() && a.max() > b.max()); - } - - friend std::ostream& operator<<(std::ostream& out, const Interval& i) { - return out << "[" << i.min() << ", " << i.max() << ")"; - } - - private: - T min_; // Inclusive lower bound. - T max_; // Exclusive upper bound. -}; - -//============================================================================== -// Implementation details: Clients can stop reading here. - -template <typename T> -bool Interval<T>::Intersects(const Interval& i, Interval* out) const { - if (!Intersects(i)) - return false; - if (out != nullptr) { - *out = Interval(std::max(min(), i.min()), std::min(max(), i.max())); - } - return true; -} - -template <typename T> -bool Interval<T>::IntersectWith(const Interval& i) { - if (Empty()) - return false; - bool modified = false; - if (i.min() > min()) { - SetMin(i.min()); - modified = true; - } - if (i.max() < max()) { - SetMax(i.max()); - modified = true; - } - return modified; -} - -template <typename T> -bool Interval<T>::SpanningUnion(const Interval& i) { - if (i.Empty()) - return false; - if (Empty()) { - *this = i; - return true; - } - bool modified = false; - if (i.min() < min()) { - SetMin(i.min()); - modified = true; - } - if (i.max() > max()) { - SetMax(i.max()); - modified = true; - } - return modified; -} - -template <typename T> -bool Interval<T>::Difference(const Interval& i, - Interval* lo, - Interval* hi) const { - // Initialize *lo and *hi to empty - *lo = {}; - *hi = {}; - if (Empty()) - return false; - if (i.Empty()) { - *lo = *this; - return false; - } - if (min() < i.max() && min() >= i.min() && max() > i.max()) { - // [------ this ------) - // [------ i ------) - // [-- result ---) - *hi = Interval(i.max(), max()); - return true; - } - if (max() > i.min() && max() <= i.max() && min() < i.min()) { - // [------ this ------) - // [------ i ------) - // [- result -) - *lo = Interval(min(), i.min()); - return true; - } - if (min() < i.min() && max() > i.max()) { - // [------- this --------) - // [---- i ----) - // [ R1 ) [ R2 ) - // There are two results: R1 and R2. - *lo = Interval(min(), i.min()); - *hi = Interval(i.max(), max()); - return true; - } - if (min() >= i.min() && max() <= i.max()) { - // [--- this ---) - // [------ i --------) - // Intersection is <this>, so difference yields the empty interval. - return true; - } - *lo = *this; // No intersection. - return false; -} - -} // namespace net - -#endif // NET_QUIC_CORE_INTERVAL_H_ diff --git a/chromium/net/quic/core/interval_set.h b/chromium/net/quic/core/interval_set.h deleted file mode 100644 index ac0695c5f19..00000000000 --- a/chromium/net/quic/core/interval_set.h +++ /dev/null @@ -1,858 +0,0 @@ -// Copyright 2015 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. -// -// IntervalSet<T> is a data structure used to represent a sorted set of -// non-empty, non-adjacent, and mutually disjoint intervals. Mutations to an -// interval set preserve these properties, altering the set as needed. For -// example, adding [2, 3) to a set containing only [1, 2) would result in the -// set containing the single interval [1, 3). -// -// Supported operations include testing whether an Interval is contained in the -// IntervalSet, comparing two IntervalSets, and performing IntervalSet union, -// intersection, and difference. -// -// IntervalSet maintains the minimum number of entries needed to represent the -// set of underlying intervals. When the IntervalSet is modified (e.g. due to an -// Add operation), other interval entries may be coalesced, removed, or -// otherwise modified in order to maintain this invariant. The intervals are -// maintained in sorted order, by ascending min() value. -// -// The reader is cautioned to beware of the terminology used here: this library -// uses the terms "min" and "max" rather than "begin" and "end" as is -// conventional for the STL. The terminology [min, max) refers to the half-open -// interval which (if the interval is not empty) contains min but does not -// contain max. An interval is considered empty if min >= max. -// -// T is required to be default- and copy-constructible, to have an assignment -// operator, a difference operator (operator-()), and the full complement of -// comparison operators (<, <=, ==, !=, >=, >). These requirements are inherited -// from Interval<T>. -// -// IntervalSet has constant-time move operations. -// -// This class is thread-compatible if T is thread-compatible. (See -// go/thread-compatible). -// -// Examples: -// IntervalSet<int> intervals; -// intervals.Add(Interval<int>(10, 20)); -// intervals.Add(Interval<int>(30, 40)); -// // intervals contains [10,20) and [30,40). -// intervals.Add(Interval<int>(15, 35)); -// // intervals has been coalesced. It now contains the single range [10,40). -// EXPECT_EQ(1, intervals.Size()); -// EXPECT_TRUE(intervals.Contains(Interval<int>(10, 40))); -// -// intervals.Difference(Interval<int>(10, 20)); -// // intervals should now contain the single range [20, 40). -// EXPECT_EQ(1, intervals.Size()); -// EXPECT_TRUE(intervals.Contains(Interval<int>(20, 40))); - -#ifndef NET_QUIC_CORE_INTERVAL_SET_H_ -#define NET_QUIC_CORE_INTERVAL_SET_H_ - -#include <stddef.h> - -#include <algorithm> -#include <ostream> -#include <set> -#include <string> -#include <utility> -#include <vector> - -#include "base/logging.h" -#include "net/quic/core/interval.h" - -namespace net { - -template <typename T> -class IntervalSet { - private: - struct IntervalComparator { - bool operator()(const Interval<T>& a, const Interval<T>& b) const; - }; - typedef std::set<Interval<T>, IntervalComparator> Set; - - public: - typedef typename Set::value_type value_type; - typedef typename Set::const_iterator const_iterator; - typedef typename Set::const_reverse_iterator const_reverse_iterator; - - // Instantiates an empty IntervalSet. - IntervalSet() {} - - // Instantiates an IntervalSet containing exactly one initial half-open - // interval [min, max), unless the given interval is empty, in which case the - // IntervalSet will be empty. - explicit IntervalSet(const Interval<T>& interval) { Add(interval); } - - // Instantiates an IntervalSet containing the half-open interval [min, max). - IntervalSet(const T& min, const T& max) { Add(min, max); } - -// TODO(rtenneti): Implement after suupport for std::initializer_list. -#if 0 - IntervalSet(std::initializer_list<value_type> il) { assign(il); } -#endif - - // Clears this IntervalSet. - void Clear() { intervals_.clear(); } - - // Returns the number of disjoint intervals contained in this IntervalSet. - size_t Size() const { return intervals_.size(); } - - // Returns the smallest interval that contains all intervals in this - // IntervalSet, or the empty interval if the set is empty. - Interval<T> SpanningInterval() const; - - // Adds "interval" to this IntervalSet. Adding the empty interval has no - // effect. - void Add(const Interval<T>& interval); - - // Adds the interval [min, max) to this IntervalSet. Adding the empty interval - // has no effect. - void Add(const T& min, const T& max) { Add(Interval<T>(min, max)); } - - // DEPRECATED(kosak). Use Union() instead. This method merges all of the - // values contained in "other" into this IntervalSet. - void Add(const IntervalSet& other); - - // Returns true if this IntervalSet represents exactly the same set of - // intervals as the ones represented by "other". - bool Equals(const IntervalSet& other) const; - - // Returns true if this IntervalSet is empty. - bool Empty() const { return intervals_.empty(); } - - // Returns true if any interval in this IntervalSet contains the indicated - // value. - bool Contains(const T& value) const; - - // Returns true if there is some interval in this IntervalSet that wholly - // contains the given interval. An interval O "wholly contains" a non-empty - // interval I if O.Contains(p) is true for every p in I. This is the same - // definition used by Interval<T>::Contains(). This method returns false on - // the empty interval, due to a (perhaps unintuitive) convention inherited - // from Interval<T>. - // Example: - // Assume an IntervalSet containing the entries { [10,20), [30,40) }. - // Contains(Interval(15, 16)) returns true, because [10,20) contains - // [15,16). However, Contains(Interval(15, 35)) returns false. - bool Contains(const Interval<T>& interval) const; - - // Returns true if for each interval in "other", there is some (possibly - // different) interval in this IntervalSet which wholly contains it. See - // Contains(const Interval<T>& interval) for the meaning of "wholly contains". - // Perhaps unintuitively, this method returns false if "other" is the empty - // set. The algorithmic complexity of this method is O(other.Size() * - // log(this->Size())), which is not efficient. The method could be rewritten - // to run in O(other.Size() + this->Size()). - bool Contains(const IntervalSet<T>& other) const; - - // Returns true if there is some interval in this IntervalSet that wholly - // contains the interval [min, max). See Contains(const Interval<T>&). - bool Contains(const T& min, const T& max) const { - return Contains(Interval<T>(min, max)); - } - - // Returns true if for some interval in "other", there is some interval in - // this IntervalSet that intersects with it. See Interval<T>::Intersects() - // for the definition of interval intersection. - bool Intersects(const IntervalSet& other) const; - - // Returns an iterator to the Interval<T> in the IntervalSet that contains the - // given value. In other words, returns an iterator to the unique interval - // [min, max) in the IntervalSet that has the property min <= value < max. If - // there is no such interval, this method returns end(). - const_iterator Find(const T& value) const; - - // Returns an iterator to the Interval<T> in the IntervalSet that wholly - // contains the given interval. In other words, returns an iterator to the - // unique interval outer in the IntervalSet that has the property that - // outer.Contains(interval). If there is no such interval, or if interval is - // empty, returns end(). - const_iterator Find(const Interval<T>& interval) const; - - // Returns an iterator to the Interval<T> in the IntervalSet that wholly - // contains [min, max). In other words, returns an iterator to the unique - // interval outer in the IntervalSet that has the property that - // outer.Contains(Interval<T>(min, max)). If there is no such interval, or if - // interval is empty, returns end(). - const_iterator Find(const T& min, const T& max) const { - return Find(Interval<T>(min, max)); - } - - // Returns true if every value within the passed interval is not Contained - // within the IntervalSet. - bool IsDisjoint(const Interval<T>& interval) const; - - // Merges all the values contained in "other" into this IntervalSet. - void Union(const IntervalSet& other); - - // Modifies this IntervalSet so that it contains only those values that are - // currently present both in *this and in the IntervalSet "other". - void Intersection(const IntervalSet& other); - - // Mutates this IntervalSet so that it contains only those values that are - // currently in *this but not in "interval". - void Difference(const Interval<T>& interval); - - // Mutates this IntervalSet so that it contains only those values that are - // currently in *this but not in the interval [min, max). - void Difference(const T& min, const T& max); - - // Mutates this IntervalSet so that it contains only those values that are - // currently in *this but not in the IntervalSet "other". - void Difference(const IntervalSet& other); - - // Mutates this IntervalSet so that it contains only those values that are - // in [min, max) but not currently in *this. - void Complement(const T& min, const T& max); - - // IntervalSet's begin() iterator. The invariants of IntervalSet guarantee - // that for each entry e in the set, e.min() < e.max() (because the entries - // are non-empty) and for each entry f that appears later in the set, - // e.max() < f.min() (because the entries are ordered, pairwise-disjoint, and - // non-adjacent). Modifications to this IntervalSet invalidate these - // iterators. - const_iterator begin() const { return intervals_.begin(); } - - // IntervalSet's end() iterator. - const_iterator end() const { return intervals_.end(); } - - // IntervalSet's rbegin() and rend() iterators. Iterator invalidation - // semantics are the same as those for begin() / end(). - const_reverse_iterator rbegin() const { return intervals_.rbegin(); } - - const_reverse_iterator rend() const { return intervals_.rend(); } - - // Appends the intervals in this IntervalSet to the end of *out. - void Get(std::vector<Interval<T>>* out) const { - out->insert(out->end(), begin(), end()); - } - - // Copies the intervals in this IntervalSet to the given output iterator. - template <typename Iter> - Iter Get(Iter out_iter) const { - return std::copy(begin(), end(), out_iter); - } - - template <typename Iter> - void assign(Iter first, Iter last) { - Clear(); - for (; first != last; ++first) - Add(*first); - } - -// TODO(rtenneti): Implement after suupport for std::initializer_list. -#if 0 - void assign(std::initializer_list<value_type> il) { - assign(il.begin(), il.end()); - } -#endif - - // Returns a human-readable representation of this set. This will typically be - // (though is not guaranteed to be) of the form - // "[a1, b1) [a2, b2) ... [an, bn)" - // where the intervals are in the same order as given by traversal from - // begin() to end(). This representation is intended for human consumption; - // computer programs should not rely on the output being in exactly this form. - std::string ToString() const; - - // Equality for IntervalSet<T>. Delegates to Equals(). - bool operator==(const IntervalSet& other) const { return Equals(other); } - - // Inequality for IntervalSet<T>. Delegates to Equals() (and returns its - // negation). - bool operator!=(const IntervalSet& other) const { return !Equals(other); } - -// TODO(rtenneti): Implement after suupport for std::initializer_list. -#if 0 - IntervalSet& operator=(std::initializer_list<value_type> il) { - assign(il.begin(), il.end()); - return *this; - } -#endif - - // Swap this IntervalSet with *other. This is a constant-time operation. - void Swap(IntervalSet<T>* other) { intervals_.swap(other->intervals_); } - - private: - // Removes overlapping ranges and coalesces adjacent intervals as needed. - void Compact(const typename Set::iterator& begin, - const typename Set::iterator& end); - - // Returns true if this set is valid (i.e. all intervals in it are non-empty, - // non-adjacent, and mutually disjoint). Currently this is used as an - // integrity check by the Intersection() and Difference() methods, but is only - // invoked for debug builds (via DCHECK). - bool Valid() const; - - // Finds the first interval that potentially intersects 'other'. - const_iterator FindIntersectionCandidate(const IntervalSet& other) const; - - // Finds the first interval that potentially intersects 'interval'. - const_iterator FindIntersectionCandidate(const Interval<T>& interval) const; - - // Helper for Intersection() and Difference(): Finds the next pair of - // intervals from 'x' and 'y' that intersect. 'mine' is an iterator - // over x->intervals_. 'theirs' is an iterator over y.intervals_. 'mine' - // and 'theirs' are advanced until an intersecting pair is found. - // Non-intersecting intervals (aka "holes") from x->intervals_ can be - // optionally erased by "on_hole". - template <typename X, typename Func> - static bool FindNextIntersectingPairImpl(X* x, - const IntervalSet& y, - const_iterator* mine, - const_iterator* theirs, - Func on_hole); - - // The variant of the above method that doesn't mutate this IntervalSet. - bool FindNextIntersectingPair(const IntervalSet& other, - const_iterator* mine, - const_iterator* theirs) const { - return FindNextIntersectingPairImpl( - this, other, mine, theirs, - [](const IntervalSet*, const_iterator, const_iterator) {}); - } - - // The variant of the above method that mutates this IntervalSet by erasing - // holes. - bool FindNextIntersectingPairAndEraseHoles(const IntervalSet& other, - const_iterator* mine, - const_iterator* theirs) { - return FindNextIntersectingPairImpl( - this, other, mine, theirs, - [](IntervalSet* x, const_iterator from, const_iterator to) { - x->intervals_.erase(from, to); - }); - } - - // The representation for the intervals. The intervals in this set are - // non-empty, pairwise-disjoint, non-adjacent and ordered in ascending order - // by min(). - Set intervals_; -}; - -template <typename T> -std::ostream& operator<<(std::ostream& out, const IntervalSet<T>& seq); - -template <typename T> -void swap(IntervalSet<T>& x, IntervalSet<T>& y); - -//============================================================================== -// Implementation details: Clients can stop reading here. - -template <typename T> -Interval<T> IntervalSet<T>::SpanningInterval() const { - Interval<T> result; - if (!intervals_.empty()) { - result.SetMin(intervals_.begin()->min()); - result.SetMax(intervals_.rbegin()->max()); - } - return result; -} - -template <typename T> -void IntervalSet<T>::Add(const Interval<T>& interval) { - if (interval.Empty()) - return; - std::pair<typename Set::iterator, bool> ins = intervals_.insert(interval); - if (!ins.second) { - // This interval already exists. - return; - } - // Determine the minimal range that will have to be compacted. We know that - // the IntervalSet was valid before the addition of the interval, so only - // need to start with the interval itself (although Compact takes an open - // range so begin needs to be the interval to the left). We don't know how - // many ranges this interval may cover, so we need to find the appropriate - // interval to end with on the right. - typename Set::iterator begin = ins.first; - if (begin != intervals_.begin()) - --begin; - const Interval<T> target_end(interval.max(), interval.max()); - const typename Set::iterator end = intervals_.upper_bound(target_end); - Compact(begin, end); -} - -template <typename T> -void IntervalSet<T>::Add(const IntervalSet& other) { - for (const_iterator it = other.begin(); it != other.end(); ++it) { - Add(*it); - } -} - -template <typename T> -bool IntervalSet<T>::Equals(const IntervalSet& other) const { - if (intervals_.size() != other.intervals_.size()) - return false; - for (typename Set::iterator i = intervals_.begin(), - j = other.intervals_.begin(); - i != intervals_.end(); ++i, ++j) { - // Simple member-wise equality, since all intervals are non-empty. - if (i->min() != j->min() || i->max() != j->max()) - return false; - } - return true; -} - -template <typename T> -bool IntervalSet<T>::Contains(const T& value) const { - Interval<T> tmp(value, value); - // Find the first interval with min() > value, then move back one step - const_iterator it = intervals_.upper_bound(tmp); - if (it == intervals_.begin()) - return false; - --it; - return it->Contains(value); -} - -template <typename T> -bool IntervalSet<T>::Contains(const Interval<T>& interval) const { - // Find the first interval with min() > value, then move back one step. - const_iterator it = intervals_.upper_bound(interval); - if (it == intervals_.begin()) - return false; - --it; - return it->Contains(interval); -} - -template <typename T> -bool IntervalSet<T>::Contains(const IntervalSet<T>& other) const { - if (!SpanningInterval().Contains(other.SpanningInterval())) { - return false; - } - - for (const_iterator i = other.begin(); i != other.end(); ++i) { - // If we don't contain the interval, can return false now. - if (!Contains(*i)) { - return false; - } - } - return true; -} - -// This method finds the interval that Contains() "value", if such an interval -// exists in the IntervalSet. The way this is done is to locate the "candidate -// interval", the only interval that could *possibly* contain value, and test it -// using Contains(). The candidate interval is the interval with the largest -// min() having min() <= value. -// -// Determining the candidate interval takes a couple of steps. First, since the -// underlying std::set stores intervals, not values, we need to create a "probe -// interval" suitable for use as a search key. The probe interval used is -// [value, value). Now we can restate the problem as finding the largest -// interval in the IntervalSet that is <= the probe interval. -// -// This restatement only works if the set's comparator behaves in a certain way. -// In particular it needs to order first by ascending min(), and then by -// descending max(). The comparator used by this library is defined in exactly -// this way. To see why descending max() is required, consider the following -// example. Assume an IntervalSet containing these intervals: -// -// [0, 5) [10, 20) [50, 60) -// -// Consider searching for the value 15. The probe interval [15, 15) is created, -// and [10, 20) is identified as the largest interval in the set <= the probe -// interval. This is the correct interval needed for the Contains() test, which -// will then return true. -// -// Now consider searching for the value 30. The probe interval [30, 30) is -// created, and again [10, 20] is identified as the largest interval <= the -// probe interval. This is again the correct interval needed for the Contains() -// test, which in this case returns false. -// -// Finally, consider searching for the value 10. The probe interval [10, 10) is -// created. Here the ordering relationship between [10, 10) and [10, 20) becomes -// vitally important. If [10, 10) were to come before [10, 20), then [0, 5) -// would be the largest interval <= the probe, leading to the wrong choice of -// interval for the Contains() test. Therefore [10, 10) needs to come after -// [10, 20). The simplest way to make this work in the general case is to order -// by ascending min() but descending max(). In this ordering, the empty interval -// is larger than any non-empty interval with the same min(). The comparator -// used by this library is careful to induce this ordering. -// -// Another detail involves the choice of which std::set method to use to try to -// find the candidate interval. The most appropriate entry point is -// set::upper_bound(), which finds the smallest interval which is > the probe -// interval. The semantics of upper_bound() are slightly different from what we -// want (namely, to find the largest interval which is <= the probe interval) -// but they are close enough; the interval found by upper_bound() will always be -// one step past the interval we are looking for (if it exists) or at begin() -// (if it does not). Getting to the proper interval is a simple matter of -// decrementing the iterator. -template <typename T> -typename IntervalSet<T>::const_iterator IntervalSet<T>::Find( - const T& value) const { - Interval<T> tmp(value, value); - const_iterator it = intervals_.upper_bound(tmp); - if (it == intervals_.begin()) - return intervals_.end(); - --it; - if (it->Contains(value)) - return it; - else - return intervals_.end(); -} - -// This method finds the interval that Contains() the interval "probe", if such -// an interval exists in the IntervalSet. The way this is done is to locate the -// "candidate interval", the only interval that could *possibly* contain -// "probe", and test it using Contains(). The candidate interval is the largest -// interval that is <= the probe interval. -// -// The search for the candidate interval only works if the comparator used -// behaves in a certain way. In particular it needs to order first by ascending -// min(), and then by descending max(). The comparator used by this library is -// defined in exactly this way. To see why descending max() is required, -// consider the following example. Assume an IntervalSet containing these -// intervals: -// -// [0, 5) [10, 20) [50, 60) -// -// Consider searching for the probe [15, 17). [10, 20) is the largest interval -// in the set which is <= the probe interval. This is the correct interval -// needed for the Contains() test, which will then return true, because [10, 20) -// contains [15, 17). -// -// Now consider searching for the probe [30, 32). Again [10, 20] is the largest -// interval <= the probe interval. This is again the correct interval needed for -// the Contains() test, which in this case returns false, because [10, 20) does -// not contain [30, 32). -// -// Finally, consider searching for the probe [10, 12). Here the ordering -// relationship between [10, 12) and [10, 20) becomes vitally important. If -// [10, 12) were to come before [10, 20), then [0, 5) would be the largest -// interval <= the probe, leading to the wrong choice of interval for the -// Contains() test. Therefore [10, 12) needs to come after [10, 20). The -// simplest way to make this work in the general case is to order by ascending -// min() but descending max(). In this ordering, given two intervals with the -// same min(), the wider one goes before the narrower one. The comparator used -// by this library is careful to induce this ordering. -// -// Another detail involves the choice of which std::set method to use to try to -// find the candidate interval. The most appropriate entry point is -// set::upper_bound(), which finds the smallest interval which is > the probe -// interval. The semantics of upper_bound() are slightly different from what we -// want (namely, to find the largest interval which is <= the probe interval) -// but they are close enough; the interval found by upper_bound() will always be -// one step past the interval we are looking for (if it exists) or at begin() -// (if it does not). Getting to the proper interval is a simple matter of -// decrementing the iterator. -template <typename T> -typename IntervalSet<T>::const_iterator IntervalSet<T>::Find( - const Interval<T>& probe) const { - const_iterator it = intervals_.upper_bound(probe); - if (it == intervals_.begin()) - return intervals_.end(); - --it; - if (it->Contains(probe)) - return it; - else - return intervals_.end(); -} - -template <typename T> -bool IntervalSet<T>::IsDisjoint(const Interval<T>& interval) const { - Interval<T> tmp(interval.min(), interval.min()); - // Find the first interval with min() > interval.min() - const_iterator it = intervals_.upper_bound(tmp); - if (it != intervals_.end() && interval.max() > it->min()) - return false; - if (it == intervals_.begin()) - return true; - --it; - return it->max() <= interval.min(); -} - -template <typename T> -void IntervalSet<T>::Union(const IntervalSet& other) { - intervals_.insert(other.begin(), other.end()); - Compact(intervals_.begin(), intervals_.end()); -} - -template <typename T> -typename IntervalSet<T>::const_iterator -IntervalSet<T>::FindIntersectionCandidate(const IntervalSet& other) const { - return FindIntersectionCandidate(*other.intervals_.begin()); -} - -template <typename T> -typename IntervalSet<T>::const_iterator -IntervalSet<T>::FindIntersectionCandidate(const Interval<T>& interval) const { - // Use upper_bound to efficiently find the first interval in intervals_ - // where min() is greater than interval.min(). If the result - // isn't the beginning of intervals_ then move backwards one interval since - // the interval before it is the first candidate where max() may be - // greater than interval.min(). - // In other words, no interval before that can possibly intersect with any - // of other.intervals_. - const_iterator mine = intervals_.upper_bound(interval); - if (mine != intervals_.begin()) { - --mine; - } - return mine; -} - -template <typename T> -template <typename X, typename Func> -bool IntervalSet<T>::FindNextIntersectingPairImpl(X* x, - const IntervalSet& y, - const_iterator* mine, - const_iterator* theirs, - Func on_hole) { - CHECK(x != nullptr); - if ((*mine == x->intervals_.end()) || (*theirs == y.intervals_.end())) { - return false; - } - while (!(**mine).Intersects(**theirs)) { - const_iterator erase_first = *mine; - // Skip over intervals in 'mine' that don't reach 'theirs'. - while (*mine != x->intervals_.end() && (**mine).max() <= (**theirs).min()) { - ++(*mine); - } - on_hole(x, erase_first, *mine); - // We're done if the end of intervals_ is reached. - if (*mine == x->intervals_.end()) { - return false; - } - // Skip over intervals 'theirs' that don't reach 'mine'. - while (*theirs != y.intervals_.end() && - (**theirs).max() <= (**mine).min()) { - ++(*theirs); - } - // If the end of other.intervals_ is reached, we're done. - if (*theirs == y.intervals_.end()) { - on_hole(x, *mine, x->intervals_.end()); - return false; - } - } - return true; -} - -template <typename T> -void IntervalSet<T>::Intersection(const IntervalSet& other) { - if (!SpanningInterval().Intersects(other.SpanningInterval())) { - intervals_.clear(); - return; - } - - const_iterator mine = FindIntersectionCandidate(other); - // Remove any intervals that cannot possibly intersect with other.intervals_. - intervals_.erase(intervals_.begin(), mine); - const_iterator theirs = other.FindIntersectionCandidate(*this); - - while (FindNextIntersectingPairAndEraseHoles(other, &mine, &theirs)) { - // OK, *mine and *theirs intersect. Now, we find the largest - // span of intervals in other (starting at theirs) - say [a..b] - // - that intersect *mine, and we replace *mine with (*mine - // intersect x) for all x in [a..b] Note that subsequent - // intervals in this can't intersect any intervals in [a..b) -- - // they may only intersect b or subsequent intervals in other. - Interval<T> i(*mine); - intervals_.erase(mine); - mine = intervals_.end(); - Interval<T> intersection; - while (theirs != other.intervals_.end() && - i.Intersects(*theirs, &intersection)) { - std::pair<typename Set::iterator, bool> ins = - intervals_.insert(intersection); - DCHECK(ins.second); - mine = ins.first; - ++theirs; - } - DCHECK(mine != intervals_.end()); - --theirs; - ++mine; - } - DCHECK(Valid()); -} - -template <typename T> -bool IntervalSet<T>::Intersects(const IntervalSet& other) const { - if (!SpanningInterval().Intersects(other.SpanningInterval())) { - return false; - } - - const_iterator mine = FindIntersectionCandidate(other); - if (mine == intervals_.end()) { - return false; - } - const_iterator theirs = other.FindIntersectionCandidate(*mine); - - return FindNextIntersectingPair(other, &mine, &theirs); -} - -template <typename T> -void IntervalSet<T>::Difference(const Interval<T>& interval) { - if (!SpanningInterval().Intersects(interval)) { - return; - } - Difference(IntervalSet<T>(interval)); -} - -template <typename T> -void IntervalSet<T>::Difference(const T& min, const T& max) { - Difference(Interval<T>(min, max)); -} - -template <typename T> -void IntervalSet<T>::Difference(const IntervalSet& other) { - if (!SpanningInterval().Intersects(other.SpanningInterval())) { - return; - } - - const_iterator mine = FindIntersectionCandidate(other); - // If no interval in mine reaches the first interval of theirs then we're - // done. - if (mine == intervals_.end()) { - return; - } - const_iterator theirs = other.FindIntersectionCandidate(*this); - - while (FindNextIntersectingPair(other, &mine, &theirs)) { - // At this point *mine and *theirs overlap. Remove mine from - // intervals_ and replace it with the possibly two intervals that are - // the difference between mine and theirs. - Interval<T> i(*mine); - intervals_.erase(mine++); - Interval<T> lo; - Interval<T> hi; - i.Difference(*theirs, &lo, &hi); - - if (!lo.Empty()) { - // We have a low end. This can't intersect anything else. - std::pair<typename Set::iterator, bool> ins = intervals_.insert(lo); - DCHECK(ins.second); - } - - if (!hi.Empty()) { - std::pair<typename Set::iterator, bool> ins = intervals_.insert(hi); - DCHECK(ins.second); - mine = ins.first; - } - } - DCHECK(Valid()); -} - -template <typename T> -void IntervalSet<T>::Complement(const T& min, const T& max) { - IntervalSet<T> span(min, max); - span.Difference(*this); - intervals_.swap(span.intervals_); -} - -template <typename T> -std::string IntervalSet<T>::ToString() const { - std::ostringstream os; - os << *this; - return os.str(); -} - -// This method compacts the IntervalSet, merging pairs of overlapping intervals -// into a single interval. In the steady state, the IntervalSet does not contain -// any such pairs. However, the way the Union() and Add() methods work is to -// temporarily put the IntervalSet into such a state and then to call Compact() -// to "fix it up" so that it is no longer in that state. -// -// Compact() needs the interval set to allow two intervals [a,b) and [a,c) -// (having the same min() but different max()) to briefly coexist in the set at -// the same time, and be adjacent to each other, so that they can be efficiently -// located and merged into a single interval. This state would be impossible -// with a comparator which only looked at min(), as such a comparator would -// consider such pairs equal. Fortunately, the comparator used by IntervalSet -// does exactly what is needed, ordering first by ascending min(), then by -// descending max(). -template <typename T> -void IntervalSet<T>::Compact(const typename Set::iterator& begin, - const typename Set::iterator& end) { - if (begin == end) - return; - typename Set::iterator next = begin; - typename Set::iterator prev = begin; - typename Set::iterator it = begin; - ++it; - ++next; - while (it != end) { - ++next; - if (prev->max() >= it->min()) { - // Overlapping / coalesced range; merge the two intervals. - T min = prev->min(); - T max = std::max(prev->max(), it->max()); - Interval<T> i(min, max); - intervals_.erase(prev); - intervals_.erase(it); - std::pair<typename Set::iterator, bool> ins = intervals_.insert(i); - DCHECK(ins.second); - prev = ins.first; - } else { - prev = it; - } - it = next; - } -} - -template <typename T> -bool IntervalSet<T>::Valid() const { - const_iterator prev = end(); - for (const_iterator it = begin(); it != end(); ++it) { - // invalid or empty interval. - if (it->min() >= it->max()) - return false; - // Not sorted, not disjoint, or adjacent. - if (prev != end() && prev->max() >= it->min()) - return false; - prev = it; - } - return true; -} - -template <typename T> -inline std::ostream& operator<<(std::ostream& out, const IntervalSet<T>& seq) { -// TODO(rtenneti): Implement << method of IntervalSet. -#if 0 - util::gtl::LogRangeToStream(out, seq.begin(), seq.end(), - util::gtl::LogLegacy()); -#endif // 0 - return out; -} - -template <typename T> -void swap(IntervalSet<T>& x, IntervalSet<T>& y) { - x.Swap(&y); -} - -// This comparator orders intervals first by ascending min() and then by -// descending max(). Readers who are satisified with that explanation can stop -// reading here. The remainder of this comment is for the benefit of future -// maintainers of this library. -// -// The reason for this ordering is that this comparator has to serve two -// masters. First, it has to maintain the intervals in its internal set in the -// order that clients expect to see them. Clients see these intervals via the -// iterators provided by begin()/end() or as a result of invoking Get(). For -// this reason, the comparator orders intervals by ascending min(). -// -// If client iteration were the only consideration, then ordering by ascending -// min() would be good enough. This is because the intervals in the IntervalSet -// are non-empty, non-adjacent, and mutually disjoint; such intervals happen to -// always have disjoint min() values, so such a comparator would never even have -// to look at max() in order to work correctly for this class. -// -// However, in addition to ordering by ascending min(), this comparator also has -// a second responsibility: satisfying the special needs of this library's -// peculiar internal implementation. These needs require the comparator to order -// first by ascending min() and then by descending max(). The best way to -// understand why this is so is to check out the comments associated with the -// Find() and Compact() methods. -template <typename T> -inline bool IntervalSet<T>::IntervalComparator::operator()( - const Interval<T>& a, - const Interval<T>& b) const { - return (a.min() < b.min() || (a.min() == b.min() && a.max() > b.max())); -} - -} // namespace net - -#endif // NET_QUIC_CORE_INTERVAL_SET_H_ diff --git a/chromium/net/quic/core/interval_set_test.cc b/chromium/net/quic/core/interval_set_test.cc deleted file mode 100644 index 9fcdddb289a..00000000000 --- a/chromium/net/quic/core/interval_set_test.cc +++ /dev/null @@ -1,978 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/core/interval_set.h" - -#include <stdarg.h> - -#include <iterator> -#include <limits> - -#include "net/test/gtest_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -using std::string; - -namespace net { -namespace test { -namespace { - -using ::testing::ElementsAreArray; - -class IntervalSetTest : public ::testing::Test { - protected: - void SetUp() override { - // Initialize two IntervalSets for union, intersection, and difference - // tests - is.Add(100, 200); - is.Add(300, 400); - is.Add(500, 600); - is.Add(700, 800); - is.Add(900, 1000); - is.Add(1100, 1200); - is.Add(1300, 1400); - is.Add(1500, 1600); - is.Add(1700, 1800); - is.Add(1900, 2000); - is.Add(2100, 2200); - - // Lots of different cases: - other.Add(50, 70); // disjoint, at the beginning - other.Add(2250, 2270); // disjoint, at the end - other.Add(650, 670); // disjoint, in the middle - other.Add(350, 360); // included - other.Add(370, 380); // also included (two at once) - other.Add(470, 530); // overlaps low end - other.Add(770, 830); // overlaps high end - other.Add(870, 900); // meets at low end - other.Add(1200, 1230); // meets at high end - other.Add(1270, 1830); // overlaps multiple ranges - } - - void TearDown() override { - is.Clear(); - EXPECT_TRUE(is.Empty()); - other.Clear(); - EXPECT_TRUE(other.Empty()); - } - IntervalSet<int> is; - IntervalSet<int> other; -}; - -TEST_F(IntervalSetTest, IsDisjoint) { - EXPECT_TRUE(is.IsDisjoint(Interval<int>(0, 99))); - EXPECT_TRUE(is.IsDisjoint(Interval<int>(0, 100))); - EXPECT_TRUE(is.IsDisjoint(Interval<int>(200, 200))); - EXPECT_TRUE(is.IsDisjoint(Interval<int>(200, 299))); - EXPECT_TRUE(is.IsDisjoint(Interval<int>(400, 407))); - EXPECT_TRUE(is.IsDisjoint(Interval<int>(405, 499))); - EXPECT_TRUE(is.IsDisjoint(Interval<int>(2300, 2300))); - EXPECT_TRUE( - is.IsDisjoint(Interval<int>(2300, std::numeric_limits<int>::max()))); - EXPECT_FALSE(is.IsDisjoint(Interval<int>(100, 100))); - EXPECT_FALSE(is.IsDisjoint(Interval<int>(100, 105))); - EXPECT_FALSE(is.IsDisjoint(Interval<int>(199, 300))); - EXPECT_FALSE(is.IsDisjoint(Interval<int>(250, 450))); - EXPECT_FALSE(is.IsDisjoint(Interval<int>(299, 400))); - EXPECT_FALSE(is.IsDisjoint(Interval<int>(250, 2000))); - EXPECT_FALSE( - is.IsDisjoint(Interval<int>(2199, std::numeric_limits<int>::max()))); -} - -// Base helper method for verifying the contents of an interval set. -// Returns true iff <is> contains <count> intervals whose successive -// endpoints match the sequence of args in <ap>: -static bool VA_Check(const IntervalSet<int>& is, size_t count, va_list ap) { - std::vector<Interval<int>> intervals; - is.Get(&intervals); - if (count != intervals.size()) { - LOG(ERROR) << "Expected " << count << " intervals, got " << intervals.size() - << ": " << is.ToString(); - return false; - } - if (count != is.Size()) { - LOG(ERROR) << "Expected " << count << " intervals, got Size " << is.Size() - << ": " << is.ToString(); - return false; - } - bool result = true; - for (size_t i = 0; i < count; i++) { - int min = va_arg(ap, int); - int max = va_arg(ap, int); - if (min != intervals[i].min() || max != intervals[i].max()) { - LOG(ERROR) << "Expected: [" << min << ", " << max << ") got " - << intervals[i] << " in " << is.ToString(); - result = false; - } - } - return result; -} - -static bool Check(const IntervalSet<int>& is, int count, ...) { - va_list ap; - va_start(ap, count); - const bool result = VA_Check(is, count, ap); - va_end(ap); - return result; -} - -// Some helper functions for testing Contains and Find, which are logically the -// same. -static void TestContainsAndFind(const IntervalSet<int>& is, int value) { - EXPECT_TRUE(is.Contains(value)) << "Set does not contain " << value; - auto it = is.Find(value); - EXPECT_NE(it, is.end()) << "No iterator to interval containing " << value; - EXPECT_TRUE(it->Contains(value)) << "Iterator does not contain " << value; -} - -static void TestContainsAndFind(const IntervalSet<int>& is, int min, int max) { - EXPECT_TRUE(is.Contains(min, max)) - << "Set does not contain interval with min " << min << "and max " << max; - auto it = is.Find(min, max); - EXPECT_NE(it, is.end()) << "No iterator to interval with min " << min - << "and max " << max; - EXPECT_TRUE(it->Contains(Interval<int>(min, max))) - << "Iterator does not contain interval with min " << min << "and max " - << max; -} - -static void TestNotContainsAndFind(const IntervalSet<int>& is, int value) { - EXPECT_FALSE(is.Contains(value)) << "Set contains " << value; - auto it = is.Find(value); - EXPECT_EQ(it, is.end()) << "There is iterator to interval containing " - << value; -} - -static void TestNotContainsAndFind(const IntervalSet<int>& is, - int min, - int max) { - EXPECT_FALSE(is.Contains(min, max)) << "Set contains interval with min " - << min << "and max " << max; - auto it = is.Find(min, max); - EXPECT_EQ(it, is.end()) << "There is iterator to interval with min " << min - << "and max " << max; -} - -TEST_F(IntervalSetTest, IntervalSetBasic) { - // Test Add, Get, Contains and Find - IntervalSet<int> iset; - EXPECT_TRUE(iset.Empty()); - EXPECT_EQ(0u, iset.Size()); - iset.Add(100, 200); - EXPECT_FALSE(iset.Empty()); - EXPECT_EQ(1u, iset.Size()); - iset.Add(100, 150); - iset.Add(150, 200); - iset.Add(130, 170); - iset.Add(90, 150); - iset.Add(170, 220); - iset.Add(300, 400); - iset.Add(250, 450); - EXPECT_FALSE(iset.Empty()); - EXPECT_EQ(2u, iset.Size()); - EXPECT_TRUE(Check(iset, 2, 90, 220, 250, 450)); - - // Test two intervals with a.max == b.min, that will just join up. - iset.Clear(); - iset.Add(100, 200); - iset.Add(200, 300); - EXPECT_FALSE(iset.Empty()); - EXPECT_EQ(1u, iset.Size()); - EXPECT_TRUE(Check(iset, 1, 100, 300)); - - // Test adding two sets together. - iset.Clear(); - IntervalSet<int> iset_add; - iset.Add(100, 200); - iset.Add(100, 150); - iset.Add(150, 200); - iset.Add(130, 170); - iset_add.Add(90, 150); - iset_add.Add(170, 220); - iset_add.Add(300, 400); - iset_add.Add(250, 450); - - iset.Add(iset_add); - EXPECT_FALSE(iset.Empty()); - EXPECT_EQ(2u, iset.Size()); - EXPECT_TRUE(Check(iset, 2, 90, 220, 250, 450)); - - // Test Get() (using an output iterator), begin()/end(), and rbegin()/rend() - // to iterate over intervals. - { - std::vector<Interval<int>> expected; - iset.Get(&expected); - - std::vector<Interval<int>> actual1; - iset.Get(back_inserter(actual1)); - ASSERT_EQ(expected.size(), actual1.size()); - - std::vector<Interval<int>> actual2; - std::copy(iset.begin(), iset.end(), back_inserter(actual2)); - ASSERT_EQ(expected.size(), actual2.size()); - - for (size_t i = 0; i < expected.size(); i++) { - EXPECT_EQ(expected[i].min(), actual1[i].min()); - EXPECT_EQ(expected[i].max(), actual1[i].max()); - - EXPECT_EQ(expected[i].min(), actual2[i].min()); - EXPECT_EQ(expected[i].max(), actual2[i].max()); - } - - // Ensure that the rbegin()/rend() iterators correctly yield the intervals - // in reverse order. - EXPECT_THAT(std::vector<Interval<int>>(iset.rbegin(), iset.rend()), - ElementsAreArray(expected.rbegin(), expected.rend())); - } - - TestNotContainsAndFind(iset, 89); - TestContainsAndFind(iset, 90); - TestContainsAndFind(iset, 120); - TestContainsAndFind(iset, 219); - TestNotContainsAndFind(iset, 220); - TestNotContainsAndFind(iset, 235); - TestNotContainsAndFind(iset, 249); - TestContainsAndFind(iset, 250); - TestContainsAndFind(iset, 300); - TestContainsAndFind(iset, 449); - TestNotContainsAndFind(iset, 450); - TestNotContainsAndFind(iset, 451); - - TestNotContainsAndFind(iset, 50, 60); - TestNotContainsAndFind(iset, 50, 90); - TestNotContainsAndFind(iset, 50, 200); - TestNotContainsAndFind(iset, 90, 90); - TestContainsAndFind(iset, 90, 200); - TestContainsAndFind(iset, 100, 200); - TestContainsAndFind(iset, 100, 220); - TestNotContainsAndFind(iset, 100, 221); - TestNotContainsAndFind(iset, 220, 220); - TestNotContainsAndFind(iset, 240, 300); - TestContainsAndFind(iset, 250, 300); - TestContainsAndFind(iset, 260, 300); - TestContainsAndFind(iset, 300, 450); - TestNotContainsAndFind(iset, 300, 451); - - IntervalSet<int> iset_contains; - iset_contains.Add(50, 90); - EXPECT_FALSE(iset.Contains(iset_contains)); - iset_contains.Clear(); - - iset_contains.Add(90, 200); - EXPECT_TRUE(iset.Contains(iset_contains)); - iset_contains.Add(100, 200); - EXPECT_TRUE(iset.Contains(iset_contains)); - iset_contains.Add(100, 220); - EXPECT_TRUE(iset.Contains(iset_contains)); - iset_contains.Add(250, 300); - EXPECT_TRUE(iset.Contains(iset_contains)); - iset_contains.Add(300, 450); - EXPECT_TRUE(iset.Contains(iset_contains)); - iset_contains.Add(300, 451); - EXPECT_FALSE(iset.Contains(iset_contains)); - EXPECT_FALSE(iset.Contains(Interval<int>())); - EXPECT_FALSE(iset.Contains(IntervalSet<int>())); -} - -TEST_F(IntervalSetTest, IntervalSetContainsEmpty) { - const IntervalSet<int> empty; - const IntervalSet<int> other_empty; - EXPECT_FALSE(empty.Contains(empty)); - EXPECT_FALSE(empty.Contains(other_empty)); -// TODO(rtenneti): Implement after suupport for std::initializer_list. -#if 0 - const IntervalSet<int> non_empty({{10, 20}, {40, 50}}); - EXPECT_FALSE(empty.Contains(non_empty)); - EXPECT_FALSE(non_empty.Contains(empty)); -#endif -} - -TEST_F(IntervalSetTest, Equality) { - IntervalSet<int> is_copy = is; - EXPECT_TRUE(is.Equals(is)); - EXPECT_EQ(is, is); - EXPECT_TRUE(is.Equals(is_copy)); - EXPECT_EQ(is, is_copy); - EXPECT_FALSE(is.Equals(other)); - EXPECT_NE(is, other); - EXPECT_FALSE(is.Equals(IntervalSet<int>())); - EXPECT_NE(is, IntervalSet<int>()); - EXPECT_TRUE(IntervalSet<int>().Equals(IntervalSet<int>())); - EXPECT_EQ(IntervalSet<int>(), IntervalSet<int>()); -} - -TEST_F(IntervalSetTest, SpanningInterval) { - // Spanning interval of an empty set is empty: - { - IntervalSet<int> iset; - const Interval<int>& ival = iset.SpanningInterval(); - EXPECT_TRUE(ival.Empty()); - } - - // Spanning interval of a set with one interval is that interval: - { - IntervalSet<int> iset; - iset.Add(100, 200); - const Interval<int>& ival = iset.SpanningInterval(); - EXPECT_EQ(100, ival.min()); - EXPECT_EQ(200, ival.max()); - } - - // Spanning interval of a set with multiple elements is determined - // by the endpoints of the first and last element: - { - const Interval<int>& ival = is.SpanningInterval(); - EXPECT_EQ(100, ival.min()); - EXPECT_EQ(2200, ival.max()); - } - { - const Interval<int>& ival = other.SpanningInterval(); - EXPECT_EQ(50, ival.min()); - EXPECT_EQ(2270, ival.max()); - } -} - -TEST_F(IntervalSetTest, IntervalSetUnion) { - is.Union(other); - EXPECT_TRUE(Check(is, 12, 50, 70, 100, 200, 300, 400, 470, 600, 650, 670, 700, - 830, 870, 1000, 1100, 1230, 1270, 1830, 1900, 2000, 2100, - 2200, 2250, 2270)); -} - -TEST_F(IntervalSetTest, IntervalSetIntersection) { - EXPECT_TRUE(is.Intersects(other)); - EXPECT_TRUE(other.Intersects(is)); - is.Intersection(other); - EXPECT_TRUE(Check(is, 7, 350, 360, 370, 380, 500, 530, 770, 800, 1300, 1400, - 1500, 1600, 1700, 1800)); - EXPECT_TRUE(is.Intersects(other)); - EXPECT_TRUE(other.Intersects(is)); -} - -TEST_F(IntervalSetTest, IntervalSetIntersectionBothEmpty) { - IntervalSet<string> mine, theirs; - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); - mine.Intersection(theirs); - EXPECT_TRUE(mine.Empty()); - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); -} - -TEST_F(IntervalSetTest, IntervalSetIntersectionEmptyMine) { - IntervalSet<string> mine; - IntervalSet<string> theirs("a", "b"); - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); - mine.Intersection(theirs); - EXPECT_TRUE(mine.Empty()); - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); -} - -TEST_F(IntervalSetTest, IntervalSetIntersectionEmptyTheirs) { - IntervalSet<string> mine("a", "b"); - IntervalSet<string> theirs; - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); - mine.Intersection(theirs); - EXPECT_TRUE(mine.Empty()); - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); -} - -TEST_F(IntervalSetTest, IntervalSetIntersectionTheirsBeforeMine) { - IntervalSet<string> mine("y", "z"); - IntervalSet<string> theirs; - theirs.Add("a", "b"); - theirs.Add("c", "d"); - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); - mine.Intersection(theirs); - EXPECT_TRUE(mine.Empty()); - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); -} - -TEST_F(IntervalSetTest, IntervalSetIntersectionMineBeforeTheirs) { - IntervalSet<string> mine; - mine.Add("a", "b"); - mine.Add("c", "d"); - IntervalSet<string> theirs("y", "z"); - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); - mine.Intersection(theirs); - EXPECT_TRUE(mine.Empty()); - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); -} - -// TODO(rtenneti): Implement after suupport for std::initializer_list. -#if 0 -TEST_F(IntervalSetTest, - IntervalSetIntersectionTheirsBeforeMineInt64Singletons) { - IntervalSet<int64_t> mine({{10, 15}}); - IntervalSet<int64_t> theirs({{-20, -5}}); - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); - mine.Intersection(theirs); - EXPECT_TRUE(mine.Empty()); - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); -} - -TEST_F(IntervalSetTest, IntervalSetIntersectionMineBeforeTheirsIntSingletons) { - IntervalSet<int> mine({{10, 15}}); - IntervalSet<int> theirs({{90, 95}}); - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); - mine.Intersection(theirs); - EXPECT_TRUE(mine.Empty()); - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); -} - -TEST_F(IntervalSetTest, IntervalSetIntersectionTheirsBetweenMine) { - IntervalSet<int64_t> mine({{0, 5}, {40, 50}}); - IntervalSet<int64_t> theirs({{10, 15}}); - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); - mine.Intersection(theirs); - EXPECT_TRUE(mine.Empty()); - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); -} - -TEST_F(IntervalSetTest, IntervalSetIntersectionMineBetweenTheirs) { - IntervalSet<int> mine({{20, 25}}); - IntervalSet<int> theirs({{10, 15}, {30, 32}}); - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); - mine.Intersection(theirs); - EXPECT_TRUE(mine.Empty()); - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); -} -#endif // 0 - -TEST_F(IntervalSetTest, IntervalSetIntersectionAlternatingIntervals) { - IntervalSet<int> mine, theirs; - mine.Add(10, 20); - mine.Add(40, 50); - mine.Add(60, 70); - theirs.Add(25, 39); - theirs.Add(55, 59); - theirs.Add(75, 79); - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); - mine.Intersection(theirs); - EXPECT_TRUE(mine.Empty()); - EXPECT_FALSE(mine.Intersects(theirs)); - EXPECT_FALSE(theirs.Intersects(mine)); -} - -// TODO(rtenneti): Implement after suupport for std::initializer_list. -#if 0 -TEST_F(IntervalSetTest, - IntervalSetIntersectionAdjacentAlternatingNonIntersectingIntervals) { - // Make sure that intersection with adjacent interval set is empty. - const IntervalSet<int> x1({{0, 10}}); - const IntervalSet<int> y1({{-50, 0}, {10, 95}}); - - IntervalSet<int> result1 = x1; - result1.Intersection(y1); - EXPECT_TRUE(result1.Empty()) << result1; - - const IntervalSet<int16_t> x2({{0, 10}, {20, 30}, {40, 90}}); - const IntervalSet<int16_t> y2( - {{-50, -40}, {-2, 0}, {10, 20}, {32, 40}, {90, 95}}); - - IntervalSet<int16_t> result2 = x2; - result2.Intersection(y2); - EXPECT_TRUE(result2.Empty()) << result2; - - const IntervalSet<int64_t> x3({{-1, 5}, {5, 10}}); - const IntervalSet<int64_t> y3({{-10, -1}, {10, 95}}); - - IntervalSet<int64_t> result3 = x3; - result3.Intersection(y3); - EXPECT_TRUE(result3.Empty()) << result3; -} - -TEST_F(IntervalSetTest, - IntervalSetIntersectionAlternatingIntersectingIntervals) { - const IntervalSet<int> x1({{0, 10}}); - const IntervalSet<int> y1({{-50, 1}, {9, 95}}); - const IntervalSet<int> expected_result1({{0, 1}, {9, 10}}); - - IntervalSet<int> result1 = x1; - result1.Intersection(y1); - EXPECT_EQ(result1, expected_result1); - - const IntervalSet<int16_t> x2({{0, 10}, {20, 30}, {40, 90}}); - const IntervalSet<int16_t> y2( - {{-50, -40}, {-2, 2}, {9, 21}, {32, 41}, {85, 95}}); - const IntervalSet<int16_t> expected_result2( - {{0, 2}, {9, 10}, {20, 21}, {40, 41}, {85, 90}}); - - IntervalSet<int16_t> result2 = x2; - result2.Intersection(y2); - EXPECT_EQ(result2, expected_result2); - - const IntervalSet<int64_t> x3({{-1, 5}, {5, 10}}); - const IntervalSet<int64_t> y3({{-10, 3}, {4, 95}}); - const IntervalSet<int64_t> expected_result3({{-1, 3}, {4, 10}}); - - IntervalSet<int64_t> result3 = x3; - result3.Intersection(y3); - EXPECT_EQ(result3, expected_result3); -} - -#endif // 0 - -TEST_F(IntervalSetTest, IntervalSetIntersectionIdentical) { - IntervalSet<int> copy(is); - EXPECT_TRUE(copy.Intersects(is)); - EXPECT_TRUE(is.Intersects(copy)); - is.Intersection(copy); - EXPECT_EQ(copy, is); -} - -TEST_F(IntervalSetTest, IntervalSetIntersectionSuperset) { - IntervalSet<int> mine(-1, 10000); - EXPECT_TRUE(mine.Intersects(is)); - EXPECT_TRUE(is.Intersects(mine)); - mine.Intersection(is); - EXPECT_EQ(is, mine); -} - -TEST_F(IntervalSetTest, IntervalSetIntersectionSubset) { - IntervalSet<int> copy(is); - IntervalSet<int> theirs(-1, 10000); - EXPECT_TRUE(copy.Intersects(theirs)); - EXPECT_TRUE(theirs.Intersects(copy)); - is.Intersection(theirs); - EXPECT_EQ(copy, is); -} - -TEST_F(IntervalSetTest, IntervalSetIntersectionLargeSet) { - IntervalSet<int> mine, theirs; - // mine: [0, 9), [10, 19), ..., [990, 999) - for (int i = 0; i < 1000; i += 10) { - mine.Add(i, i + 9); - } - - theirs.Add(500, 520); - theirs.Add(535, 545); - theirs.Add(801, 809); - EXPECT_TRUE(mine.Intersects(theirs)); - EXPECT_TRUE(theirs.Intersects(mine)); - mine.Intersection(theirs); - EXPECT_TRUE(Check(mine, 5, 500, 509, 510, 519, 535, 539, 540, 545, 801, 809)); - EXPECT_TRUE(mine.Intersects(theirs)); - EXPECT_TRUE(theirs.Intersects(mine)); -} - -TEST_F(IntervalSetTest, IntervalSetDifference) { - is.Difference(other); - EXPECT_TRUE(Check(is, 10, 100, 200, 300, 350, 360, 370, 380, 400, 530, 600, - 700, 770, 900, 1000, 1100, 1200, 1900, 2000, 2100, 2200)); - IntervalSet<int> copy = is; - is.Difference(copy); - EXPECT_TRUE(is.Empty()); -} - -TEST_F(IntervalSetTest, IntervalSetDifferenceSingleBounds) { - std::vector<Interval<int>> ivals; - other.Get(&ivals); - for (size_t i = 0; i < ivals.size(); ++i) { - is.Difference(ivals[i].min(), ivals[i].max()); - } - EXPECT_TRUE(Check(is, 10, 100, 200, 300, 350, 360, 370, 380, 400, 530, 600, - 700, 770, 900, 1000, 1100, 1200, 1900, 2000, 2100, 2200)); -} - -TEST_F(IntervalSetTest, IntervalSetDifferenceSingleInterval) { - std::vector<Interval<int>> ivals; - other.Get(&ivals); - for (size_t i = 0; i < ivals.size(); ++i) { - is.Difference(ivals[i]); - } - EXPECT_TRUE(Check(is, 10, 100, 200, 300, 350, 360, 370, 380, 400, 530, 600, - 700, 770, 900, 1000, 1100, 1200, 1900, 2000, 2100, 2200)); -} - -TEST_F(IntervalSetTest, IntervalSetDifferenceAlternatingIntervals) { - IntervalSet<int> mine, theirs; - mine.Add(10, 20); - mine.Add(40, 50); - mine.Add(60, 70); - theirs.Add(25, 39); - theirs.Add(55, 59); - theirs.Add(75, 79); - - mine.Difference(theirs); - EXPECT_TRUE(Check(mine, 3, 10, 20, 40, 50, 60, 70)); -} - -TEST_F(IntervalSetTest, IntervalSetDifferenceEmptyMine) { - IntervalSet<string> mine, theirs; - theirs.Add("a", "b"); - - mine.Difference(theirs); - EXPECT_TRUE(mine.Empty()); -} - -TEST_F(IntervalSetTest, IntervalSetDifferenceEmptyTheirs) { - IntervalSet<string> mine, theirs; - mine.Add("a", "b"); - - mine.Difference(theirs); - EXPECT_EQ(1u, mine.Size()); - EXPECT_EQ("a", mine.begin()->min()); - EXPECT_EQ("b", mine.begin()->max()); -} - -TEST_F(IntervalSetTest, IntervalSetDifferenceTheirsBeforeMine) { - IntervalSet<string> mine, theirs; - mine.Add("y", "z"); - theirs.Add("a", "b"); - - mine.Difference(theirs); - EXPECT_EQ(1u, mine.Size()); - EXPECT_EQ("y", mine.begin()->min()); - EXPECT_EQ("z", mine.begin()->max()); -} - -TEST_F(IntervalSetTest, IntervalSetDifferenceMineBeforeTheirs) { - IntervalSet<string> mine, theirs; - mine.Add("a", "b"); - theirs.Add("y", "z"); - - mine.Difference(theirs); - EXPECT_EQ(1u, mine.Size()); - EXPECT_EQ("a", mine.begin()->min()); - EXPECT_EQ("b", mine.begin()->max()); -} - -TEST_F(IntervalSetTest, IntervalSetDifferenceIdentical) { - IntervalSet<string> mine; - mine.Add("a", "b"); - mine.Add("c", "d"); - IntervalSet<string> theirs(mine); - - mine.Difference(theirs); - EXPECT_TRUE(mine.Empty()); -} - -TEST_F(IntervalSetTest, EmptyComplement) { - // The complement of an empty set is the input interval: - IntervalSet<int> iset; - iset.Complement(100, 200); - EXPECT_TRUE(Check(iset, 1, 100, 200)); -} - -TEST(IntervalSetMultipleCompactionTest, OuterCovering) { - IntervalSet<int> iset; - // First add a bunch of disjoint ranges - iset.Add(100, 150); - iset.Add(200, 250); - iset.Add(300, 350); - iset.Add(400, 450); - EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450)); - // Now add a big range that covers all of these ranges - iset.Add(0, 500); - EXPECT_TRUE(Check(iset, 1, 0, 500)); -} - -TEST(IntervalSetMultipleCompactionTest, InnerCovering) { - IntervalSet<int> iset; - // First add a bunch of disjoint ranges - iset.Add(100, 150); - iset.Add(200, 250); - iset.Add(300, 350); - iset.Add(400, 450); - EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450)); - // Now add a big range that partially covers the left and right most ranges. - iset.Add(125, 425); - EXPECT_TRUE(Check(iset, 1, 100, 450)); -} - -TEST(IntervalSetMultipleCompactionTest, LeftCovering) { - IntervalSet<int> iset; - // First add a bunch of disjoint ranges - iset.Add(100, 150); - iset.Add(200, 250); - iset.Add(300, 350); - iset.Add(400, 450); - EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450)); - // Now add a big range that partially covers the left most range. - iset.Add(125, 500); - EXPECT_TRUE(Check(iset, 1, 100, 500)); -} - -TEST(IntervalSetMultipleCompactionTest, RightCovering) { - IntervalSet<int> iset; - // First add a bunch of disjoint ranges - iset.Add(100, 150); - iset.Add(200, 250); - iset.Add(300, 350); - iset.Add(400, 450); - EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450)); - // Now add a big range that partially covers the right most range. - iset.Add(0, 425); - EXPECT_TRUE(Check(iset, 1, 0, 450)); -} - -// Helper method for testing and verifying the results of a one-interval -// completement case. -static bool CheckOneComplement(int add_min, - int add_max, - int comp_min, - int comp_max, - int count, - ...) { - IntervalSet<int> iset; - iset.Add(add_min, add_max); - iset.Complement(comp_min, comp_max); - bool result = true; - va_list ap; - va_start(ap, count); - if (!VA_Check(iset, count, ap)) { - result = false; - } - va_end(ap); - return result; -} - -TEST_F(IntervalSetTest, SingleIntervalComplement) { - // Verify the complement of a set with one interval (i): - // |----- i -----| - // |----- args -----| - EXPECT_TRUE(CheckOneComplement(0, 10, 50, 150, 1, 50, 150)); - - // |----- i -----| - // |----- args -----| - EXPECT_TRUE(CheckOneComplement(50, 150, 0, 100, 1, 0, 50)); - - // |----- i -----| - // |----- args -----| - EXPECT_TRUE(CheckOneComplement(50, 150, 50, 150, 0)); - - // |---------- i ----------| - // |----- args -----| - EXPECT_TRUE(CheckOneComplement(50, 500, 100, 300, 0)); - - // |----- i -----| - // |---------- args ----------| - EXPECT_TRUE(CheckOneComplement(50, 500, 0, 800, 2, 0, 50, 500, 800)); - - // |----- i -----| - // |----- args -----| - EXPECT_TRUE(CheckOneComplement(50, 150, 100, 300, 1, 150, 300)); - - // |----- i -----| - // |----- args -----| - EXPECT_TRUE(CheckOneComplement(50, 150, 200, 300, 1, 200, 300)); -} - -// Helper method that copies <iset> and takes its complement, -// returning false if Check succeeds. -static bool CheckComplement(const IntervalSet<int>& iset, - int comp_min, - int comp_max, - int count, - ...) { - IntervalSet<int> iset_copy = iset; - iset_copy.Complement(comp_min, comp_max); - bool result = true; - va_list ap; - va_start(ap, count); - if (!VA_Check(iset_copy, count, ap)) { - result = false; - } - va_end(ap); - return result; -} - -TEST_F(IntervalSetTest, MultiIntervalComplement) { - // Initialize a small test set: - IntervalSet<int> iset; - iset.Add(100, 200); - iset.Add(300, 400); - iset.Add(500, 600); - - // |----- i -----| - // |----- comp -----| - EXPECT_TRUE(CheckComplement(iset, 0, 50, 1, 0, 50)); - - // |----- i -----| - // |----- comp -----| - EXPECT_TRUE(CheckComplement(iset, 0, 200, 1, 0, 100)); - EXPECT_TRUE(CheckComplement(iset, 0, 220, 2, 0, 100, 200, 220)); - - // |----- i -----| - // |----- comp -----| - EXPECT_TRUE(CheckComplement(iset, 100, 600, 2, 200, 300, 400, 500)); - - // |---------- i ----------| - // |----- comp -----| - EXPECT_TRUE(CheckComplement(iset, 300, 400, 0)); - EXPECT_TRUE(CheckComplement(iset, 250, 400, 1, 250, 300)); - EXPECT_TRUE(CheckComplement(iset, 300, 450, 1, 400, 450)); - EXPECT_TRUE(CheckComplement(iset, 250, 450, 2, 250, 300, 400, 450)); - - // |----- i -----| - // |---------- comp ----------| - EXPECT_TRUE( - CheckComplement(iset, 0, 700, 4, 0, 100, 200, 300, 400, 500, 600, 700)); - - // |----- i -----| - // |----- comp -----| - EXPECT_TRUE(CheckComplement(iset, 400, 700, 2, 400, 500, 600, 700)); - EXPECT_TRUE(CheckComplement(iset, 350, 700, 2, 400, 500, 600, 700)); - - // |----- i -----| - // |----- comp -----| - EXPECT_TRUE(CheckComplement(iset, 700, 800, 1, 700, 800)); -} - -// Verifies ToString, operator<< don't assert. -// TODO(rtenneti): Implement ToString() method of IntervalSet. -TEST_F(IntervalSetTest, DISABLED_ToString) { - IntervalSet<int> iset; - iset.Add(300, 400); - iset.Add(100, 200); - iset.Add(500, 600); - EXPECT_TRUE(!iset.ToString().empty()); - VLOG(2) << iset.ToString(); - // Order and format of ToString() output is guaranteed. - EXPECT_EQ("[100, 200) [300, 400) [500, 600)", iset.ToString()); - EXPECT_EQ("[1, 2)", IntervalSet<int>(1, 2).ToString()); - EXPECT_EQ("", IntervalSet<int>().ToString()); -} - -TEST_F(IntervalSetTest, ConstructionDiscardsEmptyInterval) { - EXPECT_TRUE(IntervalSet<int>(Interval<int>(2, 2)).Empty()); - EXPECT_TRUE(IntervalSet<int>(2, 2).Empty()); - EXPECT_FALSE(IntervalSet<int>(Interval<int>(2, 3)).Empty()); - EXPECT_FALSE(IntervalSet<int>(2, 3).Empty()); -} - -TEST_F(IntervalSetTest, Swap) { - IntervalSet<int> a, b; - a.Add(300, 400); - b.Add(100, 200); - b.Add(500, 600); - a.Swap(&b); - EXPECT_TRUE(Check(a, 2, 100, 200, 500, 600)); - EXPECT_TRUE(Check(b, 1, 300, 400)); - swap(a, b); - EXPECT_TRUE(Check(a, 1, 300, 400)); - EXPECT_TRUE(Check(b, 2, 100, 200, 500, 600)); -} - -// TODO(rtenneti): Enabled these tests. -#if 0 -static void BM_Difference(int iters) { - // StopBenchmarkTiming(); - IntervalSet<int> difference_set; - int start = 10; - for (int i = 0; i < 1000000; ++i) { - difference_set.Add(start, start+5); - start += 7; - } - - // Create an interval somewhere in the middle of the difference set. - // StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { - IntervalSet<int> initial(1000000, 1000020); - initial.Difference(difference_set); - } -} - -BENCHMARK(BM_Difference); - -static void BM_IntersectionSmallAndLarge(int iters, int size) { - // Intersects constant size 'mine' with large 'theirs'. - StopBenchmarkTiming(); - IntervalSet<int> theirs; - for (int i = 0; i < size; ++i) { - theirs.Add(2 * i, 2 * i + 1); - } - - StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { - // 'mine' starts in the middle of 'theirs'. - IntervalSet<int> mine(size, size + 10); - mine.Intersection(theirs); - } -} - -BENCHMARK_RANGE(BM_IntersectionSmallAndLarge, 0, 1 << 23); - -static void BM_IntersectionIdentical(int iters, int size) { - // Intersects identical 'mine' and 'theirs'. - StopBenchmarkTiming(); - IntervalSet<int> mine; - for (int i = 0; i < size; ++i) { - mine.Add(2 * i, 2 * i + 1); - } - IntervalSet<int> theirs(mine); - - StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { - mine.Intersection(theirs); - } -} - -BENCHMARK_RANGE(BM_IntersectionIdentical, 0, 1 << 23); - -class IntervalSetInitTest : public testing::Test { - protected: - const std::vector<Interval<int>> intervals_{{0, 1}, {2, 4}}; -}; - -TEST_F(IntervalSetInitTest, DirectInit) { - std::initializer_list<Interval<int>> il = {{0, 1}, {2, 3}, {3, 4}}; - IntervalSet<int> s(il); - EXPECT_THAT(s, ElementsAreArray(intervals_)); -} - -TEST_F(IntervalSetInitTest, CopyInit) { - std::initializer_list<Interval<int>> il = {{0, 1}, {2, 3}, {3, 4}}; - IntervalSet<int> s = il; - EXPECT_THAT(s, ElementsAreArray(intervals_)); -} - -TEST_F(IntervalSetInitTest, AssignIterPair) { - IntervalSet<int> s(0, 1000); // Make sure assign clears. - s.assign(intervals_.begin(), intervals_.end()); - EXPECT_THAT(s, ElementsAreArray(intervals_)); -} - -TEST_F(IntervalSetInitTest, AssignInitList) { - IntervalSet<int> s(0, 1000); // Make sure assign clears. - s.assign({{0, 1}, {2, 3}, {3, 4}}); - EXPECT_THAT(s, ElementsAreArray(intervals_)); -} - -TEST_F(IntervalSetInitTest, AssignmentInitList) { - std::initializer_list<Interval<int>> il = {{0, 1}, {2, 3}, {3, 4}}; - IntervalSet<int> s; - s = il; - EXPECT_THAT(s, ElementsAreArray(intervals_)); -} - -TEST_F(IntervalSetInitTest, BracedInitThenBracedAssign) { - IntervalSet<int> s{{0, 1}, {2, 3}, {3, 4}}; - s = {{0, 1}, {2, 4}}; - EXPECT_THAT(s, ElementsAreArray(intervals_)); -} - -#endif // 0 - -} // namespace -} // namespace test -} // namespace net diff --git a/chromium/net/quic/core/interval_test.cc b/chromium/net/quic/core/interval_test.cc deleted file mode 100644 index da8643aae1f..00000000000 --- a/chromium/net/quic/core/interval_test.cc +++ /dev/null @@ -1,281 +0,0 @@ -// Copyright 2015 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. -// -// ---------------------------------------------------------------------- -// -// Unittest for the Interval class. -// -// Author: Will Neveitt (wneveitt@google.com) -// ---------------------------------------------------------------------- - -#include "net/quic/core/interval.h" - -#include "base/logging.h" -#include "net/test/gtest_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -using std::string; - -namespace net { -namespace test { -namespace { - -class IntervalTest : public ::testing::Test { - protected: - // Test intersection between the two intervals i1 and i2. Tries - // i1.IntersectWith(i2) and vice versa. The intersection should change i1 iff - // changes_i1 is true, and the same for changes_i2. The resulting - // intersection should be result. - void TestIntersect(const Interval<int64_t>& i1, - const Interval<int64_t>& i2, - bool changes_i1, - bool changes_i2, - const Interval<int64_t>& result) { - Interval<int64_t> i; - i.CopyFrom(i1); - EXPECT_TRUE(i.IntersectWith(i2) == changes_i1 && i.Equals(result)); - i.CopyFrom(i2); - EXPECT_TRUE(i.IntersectWith(i1) == changes_i2 && i.Equals(result)); - } -}; - -TEST_F(IntervalTest, ConstructorsCopyAndClear) { - Interval<int32_t> empty; - EXPECT_TRUE(empty.Empty()); - - Interval<int32_t> d2(0, 100); - EXPECT_EQ(0, d2.min()); - EXPECT_EQ(100, d2.max()); - EXPECT_EQ(Interval<int32_t>(0, 100), d2); - EXPECT_NE(Interval<int32_t>(0, 99), d2); - - empty.CopyFrom(d2); - EXPECT_EQ(0, d2.min()); - EXPECT_EQ(100, d2.max()); - EXPECT_TRUE(empty.Equals(d2)); - EXPECT_EQ(empty, d2); - EXPECT_TRUE(d2.Equals(empty)); - EXPECT_EQ(d2, empty); - - Interval<int32_t> max_less_than_min(40, 20); - EXPECT_TRUE(max_less_than_min.Empty()); - EXPECT_EQ(40, max_less_than_min.min()); - EXPECT_EQ(20, max_less_than_min.max()); - - Interval<int> d3(10, 20); - d3.Clear(); - EXPECT_TRUE(d3.Empty()); -} - -TEST_F(IntervalTest, GettersSetters) { - Interval<int32_t> d1(100, 200); - - // SetMin: - d1.SetMin(30); - EXPECT_EQ(30, d1.min()); - EXPECT_EQ(200, d1.max()); - - // SetMax: - d1.SetMax(220); - EXPECT_EQ(30, d1.min()); - EXPECT_EQ(220, d1.max()); - - // Set: - d1.Clear(); - d1.Set(30, 220); - EXPECT_EQ(30, d1.min()); - EXPECT_EQ(220, d1.max()); - - // SpanningUnion: - Interval<int32_t> d2; - EXPECT_TRUE(!d1.SpanningUnion(d2)); - EXPECT_EQ(30, d1.min()); - EXPECT_EQ(220, d1.max()); - - EXPECT_TRUE(d2.SpanningUnion(d1)); - EXPECT_EQ(30, d2.min()); - EXPECT_EQ(220, d2.max()); - - d2.SetMin(40); - d2.SetMax(100); - EXPECT_TRUE(!d1.SpanningUnion(d2)); - EXPECT_EQ(30, d1.min()); - EXPECT_EQ(220, d1.max()); - - d2.SetMin(20); - d2.SetMax(100); - EXPECT_TRUE(d1.SpanningUnion(d2)); - EXPECT_EQ(20, d1.min()); - EXPECT_EQ(220, d1.max()); - - d2.SetMin(50); - d2.SetMax(300); - EXPECT_TRUE(d1.SpanningUnion(d2)); - EXPECT_EQ(20, d1.min()); - EXPECT_EQ(300, d1.max()); - - d2.SetMin(0); - d2.SetMax(500); - EXPECT_TRUE(d1.SpanningUnion(d2)); - EXPECT_EQ(0, d1.min()); - EXPECT_EQ(500, d1.max()); - - d2.SetMin(100); - d2.SetMax(0); - EXPECT_TRUE(!d1.SpanningUnion(d2)); - EXPECT_EQ(0, d1.min()); - EXPECT_EQ(500, d1.max()); - EXPECT_TRUE(d2.SpanningUnion(d1)); - EXPECT_EQ(0, d2.min()); - EXPECT_EQ(500, d2.max()); -} - -TEST_F(IntervalTest, CoveringOps) { - const Interval<int64_t> empty; - const Interval<int64_t> d(100, 200); - const Interval<int64_t> d1(0, 50); - const Interval<int64_t> d2(50, 110); - const Interval<int64_t> d3(110, 180); - const Interval<int64_t> d4(180, 220); - const Interval<int64_t> d5(220, 300); - const Interval<int64_t> d6(100, 150); - const Interval<int64_t> d7(150, 200); - const Interval<int64_t> d8(0, 300); - - // Intersection: - EXPECT_TRUE(d.Intersects(d)); - EXPECT_TRUE(!empty.Intersects(d) && !d.Intersects(empty)); - EXPECT_TRUE(!d.Intersects(d1) && !d1.Intersects(d)); - EXPECT_TRUE(d.Intersects(d2) && d2.Intersects(d)); - EXPECT_TRUE(d.Intersects(d3) && d3.Intersects(d)); - EXPECT_TRUE(d.Intersects(d4) && d4.Intersects(d)); - EXPECT_TRUE(!d.Intersects(d5) && !d5.Intersects(d)); - EXPECT_TRUE(d.Intersects(d6) && d6.Intersects(d)); - EXPECT_TRUE(d.Intersects(d7) && d7.Intersects(d)); - EXPECT_TRUE(d.Intersects(d8) && d8.Intersects(d)); - - Interval<int64_t> i; - EXPECT_TRUE(d.Intersects(d, &i) && d.Equals(i)); - EXPECT_TRUE(!empty.Intersects(d, NULL) && !d.Intersects(empty, NULL)); - EXPECT_TRUE(!d.Intersects(d1, NULL) && !d1.Intersects(d, NULL)); - EXPECT_TRUE(d.Intersects(d2, &i) && i.Equals(Interval<int64_t>(100, 110))); - EXPECT_TRUE(d2.Intersects(d, &i) && i.Equals(Interval<int64_t>(100, 110))); - EXPECT_TRUE(d.Intersects(d3, &i) && i.Equals(d3)); - EXPECT_TRUE(d3.Intersects(d, &i) && i.Equals(d3)); - EXPECT_TRUE(d.Intersects(d4, &i) && i.Equals(Interval<int64_t>(180, 200))); - EXPECT_TRUE(d4.Intersects(d, &i) && i.Equals(Interval<int64_t>(180, 200))); - EXPECT_TRUE(!d.Intersects(d5, NULL) && !d5.Intersects(d, NULL)); - EXPECT_TRUE(d.Intersects(d6, &i) && i.Equals(d6)); - EXPECT_TRUE(d6.Intersects(d, &i) && i.Equals(d6)); - EXPECT_TRUE(d.Intersects(d7, &i) && i.Equals(d7)); - EXPECT_TRUE(d7.Intersects(d, &i) && i.Equals(d7)); - EXPECT_TRUE(d.Intersects(d8, &i) && i.Equals(d)); - EXPECT_TRUE(d8.Intersects(d, &i) && i.Equals(d)); - - // Test IntersectsWith(). - // Arguments are TestIntersect(i1, i2, changes_i1, changes_i2, result). - TestIntersect(empty, d, false, true, empty); - TestIntersect(d, d1, true, true, empty); - TestIntersect(d1, d2, true, true, empty); - TestIntersect(d, d2, true, true, Interval<int64_t>(100, 110)); - TestIntersect(d8, d, true, false, d); - TestIntersect(d8, d1, true, false, d1); - TestIntersect(d8, d5, true, false, d5); - - // Contains: - EXPECT_TRUE(!empty.Contains(d) && !d.Contains(empty)); - EXPECT_TRUE(d.Contains(d)); - EXPECT_TRUE(!d.Contains(d1) && !d1.Contains(d)); - EXPECT_TRUE(!d.Contains(d2) && !d2.Contains(d)); - EXPECT_TRUE(d.Contains(d3) && !d3.Contains(d)); - EXPECT_TRUE(!d.Contains(d4) && !d4.Contains(d)); - EXPECT_TRUE(!d.Contains(d5) && !d5.Contains(d)); - EXPECT_TRUE(d.Contains(d6) && !d6.Contains(d)); - EXPECT_TRUE(d.Contains(d7) && !d7.Contains(d)); - EXPECT_TRUE(!d.Contains(d8) && d8.Contains(d)); - - EXPECT_TRUE(d.Contains(100)); - EXPECT_TRUE(!d.Contains(200)); - EXPECT_TRUE(d.Contains(150)); - EXPECT_TRUE(!d.Contains(99)); - EXPECT_TRUE(!d.Contains(201)); - - // Difference: - Interval<int64_t> lo; - Interval<int64_t> hi; - - EXPECT_TRUE(d.Difference(d2, &lo, &hi)); - EXPECT_TRUE(lo.Empty()); - EXPECT_EQ(110u, hi.min()); - EXPECT_EQ(200u, hi.max()); - - EXPECT_TRUE(d.Difference(d3, &lo, &hi)); - EXPECT_EQ(100u, lo.min()); - EXPECT_EQ(110u, lo.max()); - EXPECT_EQ(180u, hi.min()); - EXPECT_EQ(200u, hi.max()); - - EXPECT_TRUE(d.Difference(d4, &lo, &hi)); - EXPECT_EQ(100u, lo.min()); - EXPECT_EQ(180u, lo.max()); - EXPECT_TRUE(hi.Empty()); - - EXPECT_FALSE(d.Difference(d5, &lo, &hi)); - EXPECT_EQ(100u, lo.min()); - EXPECT_EQ(200u, lo.max()); - EXPECT_TRUE(hi.Empty()); - - EXPECT_TRUE(d.Difference(d6, &lo, &hi)); - EXPECT_TRUE(lo.Empty()); - EXPECT_EQ(150u, hi.min()); - EXPECT_EQ(200u, hi.max()); - - EXPECT_TRUE(d.Difference(d7, &lo, &hi)); - EXPECT_EQ(100u, lo.min()); - EXPECT_EQ(150u, lo.max()); - EXPECT_TRUE(hi.Empty()); - - EXPECT_TRUE(d.Difference(d8, &lo, &hi)); - EXPECT_TRUE(lo.Empty()); - EXPECT_TRUE(hi.Empty()); -} - -TEST_F(IntervalTest, Length) { - const Interval<int> empty1; - const Interval<int> empty2(1, 1); - const Interval<int> empty3(1, 0); - const Interval<base::TimeDelta> empty4( - base::TimeDelta() + base::TimeDelta::FromSeconds(1), base::TimeDelta()); - const Interval<int> d1(1, 2); - const Interval<int> d2(0, 50); - const Interval<base::TimeDelta> d3( - base::TimeDelta(), base::TimeDelta() + base::TimeDelta::FromSeconds(1)); - const Interval<base::TimeDelta> d4( - base::TimeDelta() + base::TimeDelta::FromHours(1), - base::TimeDelta() + base::TimeDelta::FromMinutes(90)); - - EXPECT_EQ(0, empty1.Length()); - EXPECT_EQ(0, empty2.Length()); - EXPECT_EQ(0, empty3.Length()); - EXPECT_EQ(base::TimeDelta(), empty4.Length()); - EXPECT_EQ(1, d1.Length()); - EXPECT_EQ(50, d2.Length()); - EXPECT_EQ(base::TimeDelta::FromSeconds(1), d3.Length()); - EXPECT_EQ(base::TimeDelta::FromMinutes(30), d4.Length()); -} - -TEST_F(IntervalTest, IntervalOfTypeWithNoOperatorMinus) { - // Interval<T> should work even if T does not support operator-(). We just - // can't call Interval<T>::Length() for such types. - const Interval<string> d1("a", "b"); - const Interval<std::pair<int, int>> d2({1, 2}, {4, 3}); - EXPECT_EQ("a", d1.min()); - EXPECT_EQ("b", d1.max()); - EXPECT_EQ(std::make_pair(1, 2), d2.min()); - EXPECT_EQ(std::make_pair(4, 3), d2.max()); -} - -} // unnamed namespace -} // namespace test -} // namespace net diff --git a/chromium/net/quic/core/quic_bandwidth.cc b/chromium/net/quic/core/quic_bandwidth.cc index 3dce6de237c..86f06642468 100644 --- a/chromium/net/quic/core/quic_bandwidth.cc +++ b/chromium/net/quic/core/quic_bandwidth.cc @@ -7,13 +7,11 @@ #include <cinttypes> #include <limits> -#include "base/strings/stringprintf.h" #include "net/quic/core/quic_constants.h" #include "net/quic/core/quic_time.h" #include "net/quic/core/quic_types.h" #include "net/quic/platform/api/quic_bug_tracker.h" - -using base::StringPrintf; +#include "net/quic/platform/api/quic_str_cat.h" namespace net { @@ -114,8 +112,8 @@ QuicTime::Delta QuicBandwidth::TransferTime(QuicByteCount bytes) const { std::string QuicBandwidth::ToDebugValue() const { if (bits_per_second_ < 80000) { - return StringPrintf("%" PRId64 " bits/s (%" PRId64 " bytes/s)", - bits_per_second_, bits_per_second_ / 8); + return QuicStringPrintf("%" PRId64 " bits/s (%" PRId64 " bytes/s)", + bits_per_second_, bits_per_second_ / 8); } double divisor; @@ -133,9 +131,9 @@ std::string QuicBandwidth::ToDebugValue() const { double bits_per_second_with_unit = bits_per_second_ / divisor; double bytes_per_second_with_unit = bits_per_second_with_unit / 8; - return StringPrintf("%.2f %cbits/s (%.2f %cbytes/s)", - bits_per_second_with_unit, unit, - bytes_per_second_with_unit, unit); + return QuicStringPrintf("%.2f %cbits/s (%.2f %cbytes/s)", + bits_per_second_with_unit, unit, + bytes_per_second_with_unit, unit); } } // namespace net diff --git a/chromium/net/quic/core/quic_blocked_writer_interface.h b/chromium/net/quic/core/quic_blocked_writer_interface.h index ea6bd474e70..2da2eb4718c 100644 --- a/chromium/net/quic/core/quic_blocked_writer_interface.h +++ b/chromium/net/quic/core/quic_blocked_writer_interface.h @@ -9,8 +9,6 @@ #ifndef NET_QUIC_CORE_QUIC_BLOCKED_WRITER_INTERFACE_H_ #define NET_QUIC_CORE_QUIC_BLOCKED_WRITER_INTERFACE_H_ -#include <cstddef> - #include "net/quic/platform/api/quic_export.h" namespace net { @@ -24,15 +22,6 @@ class QUIC_EXPORT_PRIVATE QuicBlockedWriterInterface { virtual void OnCanWrite() = 0; }; -// Hash pointers as if they were int's, but bring more entropy to the lower -// bits. -struct QuicBlockedWriterInterfacePtrHash { - std::size_t operator()(const net::QuicBlockedWriterInterface* ptr) const { - size_t k = reinterpret_cast<size_t>(ptr); - return k + (k >> 6); - } -}; - } // namespace net #endif // NET_QUIC_CORE_QUIC_BLOCKED_WRITER_INTERFACE_H_ diff --git a/chromium/net/quic/core/quic_buffered_packet_store.cc b/chromium/net/quic/core/quic_buffered_packet_store.cc index f51b8c836d7..8c4ac46add6 100644 --- a/chromium/net/quic/core/quic_buffered_packet_store.cc +++ b/chromium/net/quic/core/quic_buffered_packet_store.cc @@ -4,11 +4,9 @@ #include "net/quic/core/quic_buffered_packet_store.h" -#include "base/stl_util.h" #include "net/quic/core/quic_flags.h" #include "net/quic/platform/api/quic_bug_tracker.h" - -using base::ContainsKey; +#include "net/quic/platform/api/quic_map_util.h" namespace net { @@ -85,19 +83,19 @@ EnqueuePacketResult QuicBufferedPacketStore::EnqueuePacket( bool is_chlo) { QUIC_BUG_IF(!FLAGS_quic_allow_chlo_buffering) << "Shouldn't buffer packets if disabled via flag."; - QUIC_BUG_IF(is_chlo && ContainsKey(connections_with_chlo_, connection_id)) + QUIC_BUG_IF(is_chlo && QuicContainsKey(connections_with_chlo_, connection_id)) << "Shouldn't buffer duplicated CHLO on connection " << connection_id; - if (!ContainsKey(undecryptable_packets_, connection_id) && + if (!QuicContainsKey(undecryptable_packets_, connection_id) && ShouldBufferPacket(is_chlo)) { // Drop the packet if the upper limit of undecryptable packets has been // reached or the whole capacity of the store has been reached. return TOO_MANY_CONNECTIONS; - } else if (!ContainsKey(undecryptable_packets_, connection_id)) { + } else if (!QuicContainsKey(undecryptable_packets_, connection_id)) { undecryptable_packets_.emplace( std::make_pair(connection_id, BufferedPacketList())); } - CHECK(ContainsKey(undecryptable_packets_, connection_id)); + CHECK(QuicContainsKey(undecryptable_packets_, connection_id)); BufferedPacketList& queue = undecryptable_packets_.find(connection_id)->second; @@ -105,7 +103,7 @@ EnqueuePacketResult QuicBufferedPacketStore::EnqueuePacket( // If current packet is not CHLO, it might not be buffered because store // only buffers certain number of undecryptable packets per connection. size_t num_non_chlo_packets = - ContainsKey(connections_with_chlo_, connection_id) + QuicContainsKey(connections_with_chlo_, connection_id) ? (queue.buffered_packets.size() - 1) : queue.buffered_packets.size(); if (num_non_chlo_packets >= kDefaultMaxUndecryptablePackets) { @@ -138,7 +136,7 @@ EnqueuePacketResult QuicBufferedPacketStore::EnqueuePacket( bool QuicBufferedPacketStore::HasBufferedPackets( QuicConnectionId connection_id) const { - return ContainsKey(undecryptable_packets_, connection_id); + return QuicContainsKey(undecryptable_packets_, connection_id); } bool QuicBufferedPacketStore::HasChlosBuffered() const { @@ -218,7 +216,7 @@ QuicBufferedPacketStore::DeliverPacketsForNextConnection( bool QuicBufferedPacketStore::HasChloForConnection( QuicConnectionId connection_id) { - return ContainsKey(connections_with_chlo_, connection_id); + return QuicContainsKey(connections_with_chlo_, connection_id); } } // namespace net diff --git a/chromium/net/quic/core/quic_buffered_packet_store.h b/chromium/net/quic/core/quic_buffered_packet_store.h index 1319a8ef086..8c4e42d3ed4 100644 --- a/chromium/net/quic/core/quic_buffered_packet_store.h +++ b/chromium/net/quic/core/quic_buffered_packet_store.h @@ -7,12 +7,12 @@ #include <list> -#include "net/base/linked_hash_map.h" #include "net/quic/core/quic_alarm.h" #include "net/quic/core/quic_alarm_factory.h" #include "net/quic/core/quic_packets.h" #include "net/quic/core/quic_time.h" #include "net/quic/platform/api/quic_clock.h" +#include "net/quic/platform/api/quic_containers.h" #include "net/quic/platform/api/quic_export.h" #include "net/quic/platform/api/quic_socket_address.h" @@ -68,7 +68,7 @@ class QUIC_EXPORT_PRIVATE QuicBufferedPacketStore { QuicTime creation_time; }; - typedef linked_hash_map<QuicConnectionId, BufferedPacketList> + typedef QuicLinkedHashMap<QuicConnectionId, BufferedPacketList> BufferedPacketMap; class QUIC_EXPORT_PRIVATE VisitorInterface { @@ -155,7 +155,7 @@ class QUIC_EXPORT_PRIVATE QuicBufferedPacketStore { // Keeps track of connection with CHLO buffered up already and the order they // arrive. - linked_hash_map<QuicConnectionId, bool> connections_with_chlo_; + QuicLinkedHashMap<QuicConnectionId, bool> connections_with_chlo_; }; } // namespace net diff --git a/chromium/net/quic/core/quic_buffered_packet_store_test.cc b/chromium/net/quic/core/quic_buffered_packet_store_test.cc index 312f0bf3a36..698316339c8 100644 --- a/chromium/net/quic/core/quic_buffered_packet_store_test.cc +++ b/chromium/net/quic/core/quic_buffered_packet_store_test.cc @@ -7,7 +7,6 @@ #include <list> #include <string> -#include "base/stl_util.h" #include "net/quic/core/quic_flags.h" #include "net/quic/test_tools/mock_clock.h" #include "net/quic/test_tools/quic_buffered_packet_store_peer.h" diff --git a/chromium/net/quic/core/quic_client_promised_info.cc b/chromium/net/quic/core/quic_client_promised_info.cc index a08ff456065..ebc6d185057 100644 --- a/chromium/net/quic/core/quic_client_promised_info.cc +++ b/chromium/net/quic/core/quic_client_promised_info.cc @@ -7,8 +7,6 @@ #include "net/quic/core/spdy_utils.h" #include "net/quic/platform/api/quic_logging.h" -using net::SpdyHeaderBlock; -using net::kPushPromiseTimeoutSecs; using std::string; namespace net { diff --git a/chromium/net/quic/core/quic_client_promised_info_test.cc b/chromium/net/quic/core/quic_client_promised_info_test.cc index 4535720f7a9..f9503909dde 100644 --- a/chromium/net/quic/core/quic_client_promised_info_test.cc +++ b/chromium/net/quic/core/quic_client_promised_info_test.cc @@ -32,7 +32,7 @@ class MockQuicClientSession : public QuicClientSession { QuicServerId("example.com", 443, PRIVACY_MODE_DISABLED), &crypto_config_, push_promise_index), - crypto_config_(CryptoTestUtils::ProofVerifierForTesting()), + crypto_config_(crypto_test_utils::ProofVerifierForTesting()), authorized_(true) {} ~MockQuicClientSession() override {} diff --git a/chromium/net/quic/core/quic_client_push_promise_index_test.cc b/chromium/net/quic/core/quic_client_push_promise_index_test.cc index 73407c54e2b..cdc09028612 100644 --- a/chromium/net/quic/core/quic_client_push_promise_index_test.cc +++ b/chromium/net/quic/core/quic_client_push_promise_index_test.cc @@ -31,7 +31,7 @@ class MockQuicClientSession : public QuicClientSession { QuicServerId("example.com", 443, PRIVACY_MODE_DISABLED), &crypto_config_, push_promise_index), - crypto_config_(CryptoTestUtils::ProofVerifierForTesting()) {} + crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {} ~MockQuicClientSession() override {} MOCK_METHOD1(CloseStream, void(QuicStreamId stream_id)); diff --git a/chromium/net/quic/core/quic_client_session_base.cc b/chromium/net/quic/core/quic_client_session_base.cc index a3533721ed7..12f9ff75c9f 100644 --- a/chromium/net/quic/core/quic_client_session_base.cc +++ b/chromium/net/quic/core/quic_client_session_base.cc @@ -79,47 +79,50 @@ void QuicClientSessionBase::OnPromiseHeaderList( } bool QuicClientSessionBase::HandlePromised(QuicStreamId /* associated_id */, - QuicStreamId id, + QuicStreamId promised_id, const SpdyHeaderBlock& headers) { // Due to pathalogical packet re-ordering, it is possible that // frames for the promised stream have already arrived, and the // promised stream could be active or closed. - if (IsClosedStream(id)) { + if (IsClosedStream(promised_id)) { // There was a RST on the data stream already, perhaps // QUIC_REFUSED_STREAM? - QUIC_DVLOG(1) << "Promise ignored for stream " << id + QUIC_DVLOG(1) << "Promise ignored for stream " << promised_id << " that is already closed"; return false; } if (push_promise_index_->promised_by_url()->size() >= get_max_promises()) { - QUIC_DVLOG(1) << "Too many promises, rejecting promise for stream " << id; - ResetPromised(id, QUIC_REFUSED_STREAM); + QUIC_DVLOG(1) << "Too many promises, rejecting promise for stream " + << promised_id; + ResetPromised(promised_id, QUIC_REFUSED_STREAM); return false; } const string url = SpdyUtils::GetUrlFromHeaderBlock(headers); QuicClientPromisedInfo* old_promised = GetPromisedByUrl(url); if (old_promised) { - QUIC_DVLOG(1) << "Promise for stream " << id << " is duplicate URL " << url + QUIC_DVLOG(1) << "Promise for stream " << promised_id + << " is duplicate URL " << url << " of previous promise for stream " << old_promised->id(); - ResetPromised(id, QUIC_DUPLICATE_PROMISE_URL); + ResetPromised(promised_id, QUIC_DUPLICATE_PROMISE_URL); return false; } - if (GetPromisedById(id)) { + if (GetPromisedById(promised_id)) { // OnPromiseHeadersComplete() would have closed the connection if // promised id is a duplicate. - QUIC_BUG << "Duplicate promise for id " << id; + QUIC_BUG << "Duplicate promise for id " << promised_id; return false; } - QuicClientPromisedInfo* promised = new QuicClientPromisedInfo(this, id, url); + QuicClientPromisedInfo* promised = + new QuicClientPromisedInfo(this, promised_id, url); std::unique_ptr<QuicClientPromisedInfo> promised_owner(promised); promised->Init(); - QUIC_DVLOG(1) << "stream " << id << " emplace url " << url; + QUIC_DVLOG(1) << "stream " << promised_id << " emplace url " << url; (*push_promise_index_->promised_by_url())[url] = promised; - promised_by_id_[id] = std::move(promised_owner); + promised_by_id_[promised_id] = std::move(promised_owner); promised->OnPromiseHeaders(headers); return true; } diff --git a/chromium/net/quic/core/quic_client_session_base.h b/chromium/net/quic/core/quic_client_session_base.h index 76aa43744b6..7cb6610f963 100644 --- a/chromium/net/quic/core/quic_client_session_base.h +++ b/chromium/net/quic/core/quic_client_session_base.h @@ -65,15 +65,15 @@ class QUIC_EXPORT_PRIVATE QuicClientSessionBase // Called by |QuicSpdyClientStream| on receipt of PUSH_PROMISE, does // some session level validation and creates the // |QuicClientPromisedInfo| inserting into maps by (promised) id and - // url. Returns true if a new push promise is accepted. Reset the promised - // stream and returns false otherwiese. + // url. Returns true if a new push promise is accepted. Resets the promised + // stream and returns false otherwise. virtual bool HandlePromised(QuicStreamId associated_id, QuicStreamId promised_id, const SpdyHeaderBlock& headers); // For cross-origin server push, this should verify the server is // authoritative per [RFC2818], Section 3. Roughly, subjectAltName - // std::list in the certificate should contain a matching DNS name, or IP + // list in the certificate should contain a matching DNS name, or IP // address. |hostname| is derived from the ":authority" header field of // the PUSH_PROMISE frame, port if present there will be dropped. virtual bool IsAuthorized(const std::string& hostname) = 0; diff --git a/chromium/net/quic/core/quic_config.h b/chromium/net/quic/core/quic_config.h index e2388108936..286ba1c2af6 100644 --- a/chromium/net/quic/core/quic_config.h +++ b/chromium/net/quic/core/quic_config.h @@ -5,9 +5,8 @@ #ifndef NET_QUIC_CORE_QUIC_CONFIG_H_ #define NET_QUIC_CORE_QUIC_CONFIG_H_ -#include <stddef.h> -#include <stdint.h> - +#include <cstddef> +#include <cstdint> #include <string> #include "net/quic/core/quic_packets.h" diff --git a/chromium/net/quic/core/quic_config_test.cc b/chromium/net/quic/core/quic_config_test.cc index 9cf0f334df8..4445e00a9e3 100644 --- a/chromium/net/quic/core/quic_config_test.cc +++ b/chromium/net/quic/core/quic_config_test.cc @@ -6,7 +6,6 @@ #include "net/quic/core/crypto/crypto_handshake_message.h" #include "net/quic/core/crypto/crypto_protocol.h" -#include "net/quic/core/quic_flags.h" #include "net/quic/core/quic_packets.h" #include "net/quic/core/quic_time.h" #include "net/quic/core/quic_utils.h" diff --git a/chromium/net/quic/core/quic_connection.cc b/chromium/net/quic/core/quic_connection.cc index 708dc2608a5..ae9e1cde4cc 100644 --- a/chromium/net/quic/core/quic_connection.cc +++ b/chromium/net/quic/core/quic_connection.cc @@ -17,9 +17,6 @@ #include "base/format_macros.h" #include "base/macros.h" #include "base/metrics/histogram_macros.h" -#include "base/stl_util.h" -#include "net/base/address_family.h" -#include "net/base/ip_address.h" #include "net/base/net_errors.h" #include "net/quic/core/crypto/crypto_protocol.h" #include "net/quic/core/crypto/quic_decrypter.h" @@ -33,6 +30,7 @@ #include "net/quic/core/quic_utils.h" #include "net/quic/platform/api/quic_bug_tracker.h" #include "net/quic/platform/api/quic_logging.h" +#include "net/quic/platform/api/quic_map_util.h" #include "net/quic/platform/api/quic_str_cat.h" #include "net/quic/platform/api/quic_text_utils.h" @@ -249,7 +247,6 @@ QuicConnection::QuicConnection(QuicConnectionId connection_id, time_of_last_received_packet_(clock_->ApproximateNow()), time_of_last_sent_new_packet_(clock_->ApproximateNow()), last_send_for_timeout_(clock_->ApproximateNow()), - packet_number_of_last_sent_packet_(0), sent_packet_manager_(perspective, clock_, &stats_, kCubicBytes, kNack), version_negotiation_state_(START_NEGOTIATION), perspective_(perspective), @@ -267,9 +264,6 @@ QuicConnection::QuicConnection(QuicConnectionId connection_id, QUIC_DLOG(INFO) << ENDPOINT << "Created connection with connection_id: " << connection_id; framer_.set_visitor(this); - if (!FLAGS_quic_reloadable_flag_quic_receive_packet_once_decrypted) { - last_stop_waiting_frame_.least_unacked = 0; - } stats_.connection_creation_time = clock_->ApproximateNow(); // TODO(ianswett): Supply the NetworkChangeVisitor as a constructor argument // and make it required non-null, because it's always used. @@ -349,10 +343,7 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) { ack_decimation_delay_ = kShortAckDecimationDelay; } if (config.HasClientSentConnectionOption(k5RTO, perspective_)) { - if (perspective_ == Perspective::IS_CLIENT || - !FLAGS_quic_reloadable_flag_quic_only_5rto_client_side) { - close_connection_after_five_rtos_ = true; - } + close_connection_after_five_rtos_ = true; } } @@ -393,7 +384,7 @@ bool QuicConnection::SelectMutualVersion( const QuicVersionVector& supported_versions = framer_.supported_versions(); for (size_t i = 0; i < supported_versions.size(); ++i) { const QuicVersion& version = supported_versions[i]; - if (base::ContainsValue(available_versions, version)) { + if (QuicContainsValue(available_versions, version)) { framer_.set_version(version); return true; } @@ -511,7 +502,7 @@ void QuicConnection::OnVersionNegotiationPacket( return; } - if (base::ContainsValue(packet.versions, version())) { + if (QuicContainsValue(packet.versions, version())) { const string error_details = "Server already supports client's version and should have accepted the " "connection."; @@ -635,17 +626,14 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) { --stats_.packets_dropped; QUIC_DVLOG(1) << ENDPOINT << "Received packet header: " << header; last_header_ = header; - if (FLAGS_quic_reloadable_flag_quic_receive_packet_once_decrypted) { - // An ack will be sent if a missing retransmittable packet was received; - was_last_packet_missing_ = - received_packet_manager_.IsMissing(last_header_.packet_number); - - // Record received to populate ack info correctly before processing stream - // frames, since the processing may result in a response packet with a - // bundled ack. - received_packet_manager_.RecordPacketReceived( - last_header_, time_of_last_received_packet_); - } + // An ack will be sent if a missing retransmittable packet was received; + was_last_packet_missing_ = + received_packet_manager_.IsMissing(last_header_.packet_number); + + // Record packet receipt to populate ack info before processing stream + // frames, since the processing may result in sending a bundled ack. + received_packet_manager_.RecordPacketReceived(last_header_, + time_of_last_received_packet_); DCHECK(connected_); return true; } @@ -703,7 +691,13 @@ bool QuicConnection::OnAckFrame(const QuicAckFrame& incoming_ack) { if (send_alarm_->IsSet()) { send_alarm_->Cancel(); } - ProcessAckFrame(incoming_ack); + largest_seen_packet_with_ack_ = last_header_.packet_number; + sent_packet_manager_.OnIncomingAck(incoming_ack, + time_of_last_received_packet_); + // Always reset the retransmission alarm when an ack comes in, since we now + // have a better estimate of the current rtt than when it was set. + SetRetransmissionAlarm(); + // If the incoming ack's packets set expresses missing packets: peer is still // waiting for a packet lower than a packet that we are no longer planning to // send. @@ -720,21 +714,6 @@ bool QuicConnection::OnAckFrame(const QuicAckFrame& incoming_ack) { return connected_; } -void QuicConnection::ProcessAckFrame(const QuicAckFrame& incoming_ack) { - largest_seen_packet_with_ack_ = last_header_.packet_number; - sent_packet_manager_.OnIncomingAck(incoming_ack, - time_of_last_received_packet_); - // Always reset the retransmission alarm when an ack comes in, since we now - // have a better estimate of the current rtt than when it was set. - SetRetransmissionAlarm(); -} - -void QuicConnection::ProcessStopWaitingFrame( - const QuicStopWaitingFrame& stop_waiting) { - largest_seen_packet_with_stop_waiting_ = last_header_.packet_number; - received_packet_manager_.UpdatePacketInformationSentByPeer(stop_waiting); -} - bool QuicConnection::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) { DCHECK(connected_); @@ -755,11 +734,8 @@ bool QuicConnection::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) { debug_visitor_->OnStopWaitingFrame(frame); } - if (FLAGS_quic_reloadable_flag_quic_receive_packet_once_decrypted) { - ProcessStopWaitingFrame(frame); - } else { - last_stop_waiting_frame_ = frame; - } + largest_seen_packet_with_stop_waiting_ = last_header_.packet_number; + received_packet_manager_.DontWaitForPacketsBefore(frame.least_unacked); return connected_; } @@ -924,7 +900,6 @@ bool QuicConnection::OnPathCloseFrame(const QuicPathCloseFrame& frame) { } QUIC_DLOG(INFO) << ENDPOINT << "PATH_CLOSE_FRAME received for path: " << frame.path_id; - OnPathClosed(frame.path_id); return connected_; } @@ -938,37 +913,13 @@ void QuicConnection::OnPacketComplete() { QUIC_DVLOG(1) << ENDPOINT << "Got packet " << last_header_.packet_number << " for " << last_header_.public_header.connection_id; - if (FLAGS_quic_reloadable_flag_quic_receive_packet_once_decrypted) { - // An ack will be sent if a missing retransmittable packet was received; - const bool was_missing = - should_last_packet_instigate_acks_ && was_last_packet_missing_; - - // It's possible the ack frame was sent along with response data, so it - // no longer needs to be sent. - if (ack_frame_updated()) { - MaybeQueueAck(was_missing); - } - } else { - // An ack will be sent if a missing retransmittable packet was received; - const bool was_missing = - should_last_packet_instigate_acks_ && - received_packet_manager_.IsMissing(last_header_.packet_number); - - // Record received to populate ack info correctly before processing stream - // frames, since the processing may result in a response packet with a - // bundled ack. - received_packet_manager_.RecordPacketReceived( - last_header_, time_of_last_received_packet_); - - // Process stop waiting frames here, instead of inline, because the packet - // needs to be considered 'received' before the entropy can be updated. - if (last_stop_waiting_frame_.least_unacked > 0) { - ProcessStopWaitingFrame(last_stop_waiting_frame_); - if (!connected_) { - return; - } - } + // An ack will be sent if a missing retransmittable packet was received; + const bool was_missing = + should_last_packet_instigate_acks_ && was_last_packet_missing_; + // It's possible the ack frame was sent along with response data, so it + // no longer needs to be sent. + if (ack_frame_updated()) { MaybeQueueAck(was_missing); } @@ -1041,9 +992,6 @@ void QuicConnection::MaybeQueueAck(bool was_missing) { void QuicConnection::ClearLastFrames() { should_last_packet_instigate_acks_ = false; - if (!FLAGS_quic_reloadable_flag_quic_receive_packet_once_decrypted) { - last_stop_waiting_frame_.least_unacked = 0; - } } const QuicFrame QuicConnection::GetUpdatedAckFrame() { @@ -1187,7 +1135,6 @@ void QuicConnection::SendPathClose(QuicPathId path_id) { // Opportunistically bundle an ack with this outgoing packet. ScopedPacketBundler ack_bundler(this, SEND_ACK_IF_PENDING); packet_generator_.AddControlFrame(QuicFrame(new QuicPathCloseFrame(path_id))); - OnPathClosed(path_id); } const QuicConnectionStats& QuicConnection::GetStats() { @@ -1345,7 +1292,7 @@ bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) { if (!Near(header.packet_number, last_header_.packet_number)) { QUIC_DLOG(INFO) << ENDPOINT << "Packet " << header.packet_number << " out of bounds. Discarding"; - CloseConnection(QUIC_INVALID_PACKET_HEADER, "packet number out of bounds.", + CloseConnection(QUIC_INVALID_PACKET_HEADER, "Packet number out of bounds.", ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); return false; } @@ -1527,11 +1474,6 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) { } QuicPacketNumber packet_number = packet->packet_number; - // TODO(ianswett): Remove packet_number_of_last_sent_packet_ because it's - // redundant to SentPacketManager_->GetLargestPacket in most cases, and wrong - // for multipath. - DCHECK_LE(packet_number_of_last_sent_packet_, packet_number); - packet_number_of_last_sent_packet_ = packet_number; QuicPacketLength encrypted_length = packet->encrypted_length; // Termination packets are eventually owned by TimeWaitListManager. @@ -1612,8 +1554,7 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) { if (result.status != WRITE_STATUS_ERROR && debug_visitor_ != nullptr) { // Pass the write result to the visitor. - debug_visitor_->OnPacketSent(*packet, packet->original_path_id, - packet->original_packet_number, + debug_visitor_->OnPacketSent(*packet, packet->original_packet_number, packet->transmission_type, packet_send_time); } if (packet->transmission_type == NOT_RETRANSMISSION) { @@ -1628,7 +1569,7 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) { last_send_for_timeout_ = packet_send_time; } SetPingAlarm(); - MaybeSetMtuAlarm(); + MaybeSetMtuAlarm(packet_number); QUIC_DVLOG(1) << ENDPOINT << "time we began writing last sent packet: " << packet_send_time.ToDebuggingValue(); @@ -1687,7 +1628,6 @@ void QuicConnection::OnWriteError(int error_code) { const string error_details = QuicStrCat( "Write failed with error: ", error_code, " (", strerror(error_code), ")"); QUIC_LOG_FIRST_N(ERROR, 2) << ENDPOINT << error_details; - // We can't send an error as the socket is presumably borked. switch (error_code) { case kMessageTooBigErrorCode: CloseConnection( @@ -1736,8 +1676,9 @@ void QuicConnection::OnCongestionChange() { sent_packet_manager_.GetRttStats()->initial_rtt_us()); } - if (debug_visitor_) + if (debug_visitor_ != nullptr) { debug_visitor_->OnRttChanged(rtt); + } } void QuicConnection::OnPathDegrading() { @@ -2148,7 +2089,7 @@ void QuicConnection::SetRetransmissionAlarm() { QuicTime::Delta::FromMilliseconds(1)); } -void QuicConnection::MaybeSetMtuAlarm() { +void QuicConnection::MaybeSetMtuAlarm(QuicPacketNumber sent_packet_number) { // Do not set the alarm if the target size is less than the current size. // This covers the case when |mtu_discovery_target_| is at its default value, // zero. @@ -2164,7 +2105,7 @@ void QuicConnection::MaybeSetMtuAlarm() { return; } - if (packet_number_of_last_sent_packet_ >= next_mtu_probe_at_) { + if (sent_packet_number >= next_mtu_probe_at_) { // Use an alarm to send the MTU probe to ensure that no ScopedPacketBundlers // are active. mtu_discovery_alarm_->Set(clock_->ApproximateNow()); @@ -2337,8 +2278,8 @@ void QuicConnection::DiscoverMtu() { // MaybeSetMtuAlarm() will not realize that the probe has been just sent, and // will reschedule this probe again. packets_between_mtu_probes_ *= 2; - next_mtu_probe_at_ = - packet_number_of_last_sent_packet_ + packets_between_mtu_probes_ + 1; + next_mtu_probe_at_ = sent_packet_manager_.GetLargestSentPacket() + + packets_between_mtu_probes_ + 1; ++mtu_probe_count_; QUIC_DVLOG(2) << "Sending a path MTU discovery packet #" << mtu_probe_count_; @@ -2376,7 +2317,7 @@ void QuicConnection::StartPeerMigration( << ", migrating connection."; highest_packet_sent_before_peer_migration_ = - packet_number_of_last_sent_packet_; + sent_packet_manager_.GetLargestSentPacket(); peer_address_ = last_packet_source_address_; active_peer_migration_type_ = peer_migration_type; @@ -2386,11 +2327,6 @@ void QuicConnection::StartPeerMigration( sent_packet_manager_.OnConnectionMigration(peer_migration_type); } -void QuicConnection::OnPathClosed(QuicPathId path_id) { - // Stop receiving packets on this path. - framer_.OnPathClosed(path_id); -} - bool QuicConnection::ack_frame_updated() const { return received_packet_manager_.ack_frame_updated(); } diff --git a/chromium/net/quic/core/quic_connection.h b/chromium/net/quic/core/quic_connection.h index b5d34f5b081..ba3faf2f242 100644 --- a/chromium/net/quic/core/quic_connection.h +++ b/chromium/net/quic/core/quic_connection.h @@ -16,9 +16,8 @@ #ifndef NET_QUIC_CORE_QUIC_CONNECTION_H_ #define NET_QUIC_CORE_QUIC_CONNECTION_H_ -#include <stddef.h> -#include <stdint.h> - +#include <cstddef> +#include <cstdint> #include <deque> #include <list> #include <map> @@ -52,6 +51,7 @@ namespace net { class QuicClock; class QuicConfig; class QuicConnection; +class QuicDecrypter; class QuicEncrypter; class QuicRandom; @@ -166,12 +166,11 @@ class QUIC_EXPORT_PRIVATE QuicConnectionDebugVisitor // Called when a packet has been sent. virtual void OnPacketSent(const SerializedPacket& serialized_packet, - QuicPathId original_path_id, QuicPacketNumber original_packet_number, TransmissionType transmission_type, QuicTime sent_time) {} - // Called when an PING frame has been sent. + // Called when a PING frame has been sent. virtual void OnPingSent() {} // Called when a packet has been received, but before it is @@ -484,7 +483,10 @@ class QUIC_EXPORT_PRIVATE QuicConnection debug_visitor_ = debug_visitor; sent_packet_manager_.SetDebugDelegate(debug_visitor); } + // Used in Chromium, but not internally. + // Must only be called before ping_alarm_ is set. void set_ping_timeout(QuicTime::Delta ping_timeout) { + DCHECK(!ping_alarm_->IsSet()); ping_timeout_ = ping_timeout; } const QuicTime::Delta ping_timeout() { return ping_timeout_; } @@ -646,10 +648,6 @@ class QUIC_EXPORT_PRIVATE QuicConnection const bool already_delayed_; }; - QuicPacketNumber packet_number_of_last_sent_packet() const { - return packet_number_of_last_sent_packet_; - } - QuicPacketWriter* writer() { return writer_; } const QuicPacketWriter* writer() const { return writer_; } @@ -765,12 +763,11 @@ class QUIC_EXPORT_PRIVATE QuicConnection bool WritePacket(SerializedPacket* packet); // Make sure an ack we got from our peer is sane. - // Returns nullptr for valid acks or an error std::string if it was invalid. + // Returns nullptr for valid acks or an error string if it was invalid. const char* ValidateAckFrame(const QuicAckFrame& incoming_ack); // Make sure a stop waiting we got from our peer is sane. - // Returns nullptr if the frame is valid or an error std::string if it was - // invalid. + // Returns nullptr if the frame is valid or an error string if it was invalid. const char* ValidateStopWaitingFrame( const QuicStopWaitingFrame& stop_waiting); @@ -797,10 +794,6 @@ class QUIC_EXPORT_PRIVATE QuicConnection // Attempts to process any queued undecryptable packets. void MaybeProcessUndecryptablePackets(); - void ProcessAckFrame(const QuicAckFrame& incoming_ack); - - void ProcessStopWaitingFrame(const QuicStopWaitingFrame& stop_waiting); - // Sends any packets which are a response to the last packet, including both // acks and pending writes if an ack opened the congestion window. void MaybeSendInResponseToPacket(); @@ -823,7 +816,8 @@ class QUIC_EXPORT_PRIVATE QuicConnection void SetRetransmissionAlarm(); // Sets the MTU discovery alarm if necessary. - void MaybeSetMtuAlarm(); + // |sent_packet_number| is the recently sent packet number. + void MaybeSetMtuAlarm(QuicPacketNumber sent_packet_number); HasRetransmittableData IsRetransmittable(const SerializedPacket& packet); bool IsTerminationPacket(const SerializedPacket& packet); @@ -836,15 +830,6 @@ class QUIC_EXPORT_PRIVATE QuicConnection QuicByteCount GetLimitedMaxPacketSize( QuicByteCount suggested_max_packet_size); - // Called when |path_id| is considered as closed because either a PATH_CLOSE - // frame is sent or received. Stops receiving packets on closed path. Drops - // receive side of a closed path, and packets with retransmittable frames on a - // closed path are marked as retransmissions which will be transmitted on - // other paths. - // TODO(fayang): complete OnPathClosed once QuicMultipathSentPacketManager and - // QuicMultipathReceivedPacketManager are landed in QuicConnection. - void OnPathClosed(QuicPathId path_id); - // Do any work which logically would be done in OnPacket but can not be // safely done until the packet is validated. Returns true if packet can be // handled, false otherwise. @@ -893,10 +878,6 @@ class QUIC_EXPORT_PRIVATE QuicConnection // parsed or nullptr. EncryptionLevel last_decrypted_packet_level_; QuicPacketHeader last_header_; - // TODO(ianswett): Remove last_stop_waiting_frame_ once - // FLAGS_quic_reloadable_flag_quic_receive_packet_once_decrypted is - // deprecated. - QuicStopWaitingFrame last_stop_waiting_frame_; bool should_last_packet_instigate_acks_; // Whether the most recent packet was missing before it was received. bool was_last_packet_missing_; @@ -922,7 +903,7 @@ class QUIC_EXPORT_PRIVATE QuicConnection bool pending_version_negotiation_packet_; // When packets could not be sent because the socket was not writable, - // they are added to this std::list. All corresponding frames are in + // they are added to this list. All corresponding frames are in // unacked_packets_ if they are to be retransmitted. Packets encrypted_buffer // fields are owned by the QueuedPacketList, in order to ensure they outlast // the original scope of the SerializedPacket. @@ -989,7 +970,7 @@ class QUIC_EXPORT_PRIVATE QuicConnection // An alarm that is scheduled when the connection can still write and there // may be more data to send. // TODO(ianswett): Remove resume_writes_alarm when deprecating - // FLAGS_quic_only_one_sending_alarm + // FLAGS_quic_reloadable_flag_quic_only_one_sending_alarm QuicArenaScopedPtr<QuicAlarm> resume_writes_alarm_; // An alarm that fires when the connection may have timed out. QuicArenaScopedPtr<QuicAlarm> timeout_alarm_; @@ -1024,10 +1005,6 @@ class QUIC_EXPORT_PRIVATE QuicConnection // |time_of_last_received_packet_|. QuicTime last_send_for_timeout_; - // packet number of the last sent packet. Packets are guaranteed to be sent - // in packet number order. - QuicPacketNumber packet_number_of_last_sent_packet_; - // Sent packet manager which tracks the status of packets sent by this // connection and contains the send and receive algorithms to determine when // to send packets. diff --git a/chromium/net/quic/core/quic_connection_test.cc b/chromium/net/quic/core/quic_connection_test.cc index 5b351b39bb5..c607cc26736 100644 --- a/chromium/net/quic/core/quic_connection_test.cc +++ b/chromium/net/quic/core/quic_connection_test.cc @@ -11,7 +11,6 @@ #include "base/bind.h" #include "base/macros.h" -#include "base/stl_util.h" #include "net/base/net_errors.h" #include "net/quic/core/congestion_control/loss_detection_interface.h" #include "net/quic/core/congestion_control/send_algorithm_interface.h" @@ -91,7 +90,6 @@ class TaggingEncrypter : public QuicEncrypter { bool SetNoncePrefix(StringPiece nonce_prefix) override { return true; } bool EncryptPacket(QuicVersion /*version*/, - QuicPathId path_id, QuicPacketNumber packet_number, StringPiece associated_data, StringPiece plaintext, @@ -156,7 +154,6 @@ class TaggingDecrypter : public QuicDecrypter { } bool DecryptPacket(QuicVersion /*version*/, - QuicPathId path_id, QuicPacketNumber packet_number, StringPiece associated_data, StringPiece ciphertext, @@ -500,8 +497,7 @@ class TestConnection : public QuicConnection { char buffer[kMaxPacketSize]; size_t encrypted_length = QuicConnectionPeer::GetFramer(this)->EncryptPayload( - ENCRYPTION_NONE, path_id, packet_number, *packet, buffer, - kMaxPacketSize); + ENCRYPTION_NONE, packet_number, *packet, buffer, kMaxPacketSize); delete packet; SerializedPacket serialized_packet( kDefaultPathId, packet_number, PACKET_6BYTE_PACKET_NUMBER, buffer, @@ -840,8 +836,8 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> { std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames)); char buffer[kMaxPacketSize]; - size_t encrypted_length = framer_.EncryptPayload( - level, path_id, number, *packet, buffer, kMaxPacketSize); + size_t encrypted_length = + framer_.EncryptPayload(level, number, *packet, buffer, kMaxPacketSize); connection_.ProcessUdpPacket( kSelfAddress, kPeerAddress, QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false)); @@ -860,7 +856,7 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> { ConstructDataPacket(path_id, number, has_stop_waiting)); char buffer[kMaxPacketSize]; size_t encrypted_length = peer_framer_.EncryptPayload( - level, path_id, number, *packet, buffer, kMaxPacketSize); + level, number, *packet, buffer, kMaxPacketSize); connection_.ProcessUdpPacket( kSelfAddress, kPeerAddress, QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false)); @@ -874,7 +870,7 @@ class QuicConnectionTest : public ::testing::TestWithParam<TestParams> { std::unique_ptr<QuicPacket> packet(ConstructClosePacket(number)); char buffer[kMaxPacketSize]; size_t encrypted_length = peer_framer_.EncryptPayload( - ENCRYPTION_NONE, path_id, number, *packet, buffer, kMaxPacketSize); + ENCRYPTION_NONE, number, *packet, buffer, kMaxPacketSize); connection_.ProcessUdpPacket( kSelfAddress, kPeerAddress, QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false)); @@ -1217,7 +1213,7 @@ TEST_P(QuicConnectionTest, IncreaseServerMaxPacketSize) { std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames)); char buffer[kMaxPacketSize]; size_t encrypted_length = peer_framer_.EncryptPayload( - ENCRYPTION_NONE, kDefaultPathId, 12, *packet, buffer, kMaxPacketSize); + ENCRYPTION_NONE, 12, *packet, buffer, kMaxPacketSize); EXPECT_EQ(kMaxPacketSize, encrypted_length); framer_.set_version(version()); @@ -1251,7 +1247,7 @@ TEST_P(QuicConnectionTest, IncreaseServerMaxPacketSizeWhileWriterLimited) { std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames)); char buffer[kMaxPacketSize]; size_t encrypted_length = peer_framer_.EncryptPayload( - ENCRYPTION_NONE, kDefaultPathId, 12, *packet, buffer, kMaxPacketSize); + ENCRYPTION_NONE, 12, *packet, buffer, kMaxPacketSize); EXPECT_EQ(kMaxPacketSize, encrypted_length); framer_.set_version(version()); @@ -2043,7 +2039,6 @@ TEST_P(QuicConnectionTest, DoNotRetransmitForResetStreamOnRTO) { // Ensure that if the only data in flight is non-retransmittable, the // retransmission alarm is not set. TEST_P(QuicConnectionTest, CancelRetransmissionAlarmAfterResetStream) { - FLAGS_quic_reloadable_flag_quic_more_conservative_retransmission_alarm = true; QuicStreamId stream_id = 2; QuicPacketNumber last_data_packet; SendStreamDataToPeer(stream_id, "foo", 0, !kFin, &last_data_packet); @@ -2288,9 +2283,7 @@ TEST_P(QuicConnectionTest, RetransmitWriteBlockedAckedOriginalThenSent) { writer_->SetWritable(); connection_.OnCanWrite(); // There is now a pending packet, but with no retransmittable frames. - EXPECT_EQ( - FLAGS_quic_reloadable_flag_quic_more_conservative_retransmission_alarm, - !connection_.GetRetransmissionAlarm()->IsSet()); + EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet()); EXPECT_FALSE(QuicConnectionPeer::HasRetransmittableFrames(&connection_, ack.path_id, 2)); } @@ -3502,42 +3495,6 @@ TEST_P(QuicConnectionTest, TimeoutAfter5ClientRTOs) { EXPECT_FALSE(connection_.connected()); } -TEST_P(QuicConnectionTest, TimeoutAfter5ServerRTOs) { - FLAGS_quic_reloadable_flag_quic_only_5rto_client_side = true; - connection_.SetMaxTailLossProbes(2); - set_perspective(Perspective::IS_SERVER); - QuicFramerPeer::SetPerspective(QuicConnectionPeer::GetFramer(&connection_), - Perspective::IS_SERVER); - creator_->StopSendingVersion(); - EXPECT_TRUE(connection_.connected()); - EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); - QuicConfig config; - QuicTagVector connection_options; - connection_options.push_back(k5RTO); - config.SetConnectionOptionsToSend(connection_options); - connection_.SetFromConfig(config); - - // Send stream data. - SendStreamDataToPeer(kClientDataStreamId1, "foo", 0, kFin, nullptr); - - EXPECT_CALL(visitor_, OnPathDegrading()); - // Fire the retransmission alarm 6 times, twice for TLP and 4 times for RTO. - for (int i = 0; i < 6; ++i) { - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); - connection_.GetRetransmissionAlarm()->Fire(); - EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet()); - EXPECT_TRUE(connection_.connected()); - } - - EXPECT_EQ(2u, connection_.sent_packet_manager().GetConsecutiveTlpCount()); - EXPECT_EQ(4u, connection_.sent_packet_manager().GetConsecutiveRtoCount()); - // The 5th RTO should not time out server side. - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); - connection_.GetRetransmissionAlarm()->Fire(); - EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet()); - EXPECT_TRUE(connection_.connected()); -} - TEST_P(QuicConnectionTest, SendScheduler) { // Test that if we send a packet without delay, it is not queued. QuicPacket* packet = ConstructDataPacket(kDefaultPathId, 1, !kHasStopWaiting); @@ -3570,9 +3527,8 @@ TEST_P(QuicConnectionTest, TestQueueLimitsOnSendStreamData) { // All packets carry version info till version is negotiated. size_t payload_length; size_t length = GetPacketLengthForOneStream( - connection_.version(), kIncludeVersion, !kIncludePathId, - !kIncludeDiversificationNonce, PACKET_8BYTE_CONNECTION_ID, - PACKET_1BYTE_PACKET_NUMBER, &payload_length); + connection_.version(), kIncludeVersion, !kIncludeDiversificationNonce, + PACKET_8BYTE_CONNECTION_ID, PACKET_1BYTE_PACKET_NUMBER, &payload_length); connection_.SetMaxPacketLength(length); // Queue the first packet. @@ -3595,7 +3551,7 @@ TEST_P(QuicConnectionTest, LoopThroughSendingPackets) { // stream frames with non-zero offets will fit within the packet length. size_t length = 2 + GetPacketLengthForOneStream( - connection_.version(), kIncludeVersion, !kIncludePathId, + connection_.version(), kIncludeVersion, !kIncludeDiversificationNonce, PACKET_8BYTE_CONNECTION_ID, PACKET_1BYTE_PACKET_NUMBER, &payload_length); connection_.SetMaxPacketLength(length); @@ -4150,7 +4106,6 @@ TEST_P(QuicConnectionTest, BundleAckForSecondCHLO) { } TEST_P(QuicConnectionTest, BundleAckForSecondCHLOTwoPacketReject) { - FLAGS_quic_reloadable_flag_quic_receive_packet_once_decrypted = true; EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); EXPECT_FALSE(connection_.GetAckAlarm()->IsSet()); @@ -4294,15 +4249,6 @@ TEST_P(QuicConnectionTest, Blocked) { EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent); } -TEST_P(QuicConnectionTest, PathClose) { - EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); - - QuicPathCloseFrame path_close = QuicPathCloseFrame(1); - ProcessPathClosePacket(&path_close); - EXPECT_TRUE(QuicFramerPeer::IsPathClosed( - QuicConnectionPeer::GetFramer(&connection_), 1)); -} - TEST_P(QuicConnectionTest, ZeroBytePacket) { // Don't close the connection for zero byte packets. EXPECT_CALL(visitor_, OnConnectionClosed(_, _, _)).Times(0); @@ -4334,8 +4280,8 @@ TEST_P(QuicConnectionTest, ServerSendsVersionNegotiationPacket) { frames.push_back(QuicFrame(&frame1_)); std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames)); char buffer[kMaxPacketSize]; - size_t encrypted_length = framer_.EncryptPayload( - ENCRYPTION_NONE, kDefaultPathId, 12, *packet, buffer, kMaxPacketSize); + size_t encrypted_length = framer_.EncryptPayload(ENCRYPTION_NONE, 12, *packet, + buffer, kMaxPacketSize); framer_.set_version(version()); connection_.ProcessUdpPacket( @@ -4369,8 +4315,8 @@ TEST_P(QuicConnectionTest, ServerSendsVersionNegotiationPacketSocketBlocked) { frames.push_back(QuicFrame(&frame1_)); std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames)); char buffer[kMaxPacketSize]; - size_t encrypted_length = framer_.EncryptPayload( - ENCRYPTION_NONE, kDefaultPathId, 12, *packet, buffer, kMaxPacketSize); + size_t encrypted_length = framer_.EncryptPayload(ENCRYPTION_NONE, 12, *packet, + buffer, kMaxPacketSize); framer_.set_version(version()); BlockOnNextWrite(); @@ -4411,8 +4357,8 @@ TEST_P(QuicConnectionTest, frames.push_back(QuicFrame(&frame1_)); std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames)); char buffer[kMaxPacketSize]; - size_t encryped_length = framer_.EncryptPayload( - ENCRYPTION_NONE, kDefaultPathId, 12, *packet, buffer, kMaxPacketSize); + size_t encryped_length = framer_.EncryptPayload(ENCRYPTION_NONE, 12, *packet, + buffer, kMaxPacketSize); framer_.set_version(version()); set_perspective(Perspective::IS_SERVER); @@ -4450,7 +4396,7 @@ TEST_P(QuicConnectionTest, ClientHandlesVersionNegotiation) { std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames)); char buffer[kMaxPacketSize]; size_t encrypted_length = peer_framer_.EncryptPayload( - ENCRYPTION_NONE, kDefaultPathId, 12, *packet, buffer, kMaxPacketSize); + ENCRYPTION_NONE, 12, *packet, buffer, kMaxPacketSize); ASSERT_NE(0u, encrypted_length); EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1); EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); @@ -4539,7 +4485,7 @@ TEST_P(QuicConnectionTest, ProcessFramesIfPacketClosedConnection) { EXPECT_TRUE(nullptr != packet.get()); char buffer[kMaxPacketSize]; size_t encrypted_length = peer_framer_.EncryptPayload( - ENCRYPTION_NONE, kDefaultPathId, 1, *packet, buffer, kMaxPacketSize); + ENCRYPTION_NONE, 1, *packet, buffer, kMaxPacketSize); EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_PEER_GOING_AWAY, _, ConnectionCloseSource::FROM_PEER)); @@ -4883,7 +4829,7 @@ TEST_P(QuicConnectionTest, SendPingImmediately) { CongestionBlockWrites(); EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1); - EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _)).Times(1); + EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _)).Times(1); EXPECT_CALL(debug_visitor, OnPingSent()).Times(1); connection_.SendPing(); EXPECT_FALSE(connection_.HasQueuedData()); @@ -4894,7 +4840,7 @@ TEST_P(QuicConnectionTest, SendBlockedImmediately) { connection_.set_debug_visitor(&debug_visitor); EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1); - EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _)).Times(1); + EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _)).Times(1); EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent); connection_.SendBlocked(3); EXPECT_EQ(1u, connection_.GetStats().blocked_frames_sent); @@ -4938,28 +4884,6 @@ TEST_P(QuicConnectionTest, EnableMultipathNegotiation) { EXPECT_TRUE(QuicConnectionPeer::IsMultipathEnabled(&connection_)); } -TEST_P(QuicConnectionTest, ClosePath) { - QuicPathId kTestPathId = 1; - connection_.SendPathClose(kTestPathId); - EXPECT_TRUE(QuicFramerPeer::IsPathClosed( - QuicConnectionPeer::GetFramer(&connection_), kTestPathId)); -} - -TEST_P(QuicConnectionTest, BadMultipathFlag) { - EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_BAD_MULTIPATH_FLAG, _, - ConnectionCloseSource::FROM_SELF)); - - // Receieve a packet with multipath flag on when multipath is not enabled. - EXPECT_TRUE(connection_.connected()); - EXPECT_FALSE(QuicConnectionPeer::IsMultipathEnabled(&connection_)); - peer_creator_.SetCurrentPath(/*path_id=*/1u, 1u, 10u); - QuicStreamFrame stream_frame(1u, false, 0u, StringPiece()); - EXPECT_QUIC_BUG( - ProcessFramePacket(QuicFrame(&stream_frame)), - "Received a packet with multipath flag but multipath is not enabled."); - EXPECT_FALSE(connection_.connected()); -} - TEST_P(QuicConnectionTest, OnPathDegrading) { QuicByteCount packet_size; const size_t kMinTimeoutsBeforePathDegrading = 2; diff --git a/chromium/net/quic/core/quic_constants.h b/chromium/net/quic/core/quic_constants.h index 9783db0691e..8560e9014bb 100644 --- a/chromium/net/quic/core/quic_constants.h +++ b/chromium/net/quic/core/quic_constants.h @@ -27,6 +27,7 @@ const uint64_t kNumMicrosPerSecond = 1000 * 1000; // Default initial maximum size in bytes of a QUIC packet. const QuicByteCount kDefaultMaxPacketSize = 1350; +// Default initial maximum size in bytes of a QUIC packet for servers. const QuicByteCount kDefaultServerMaxPacketSize = 1000; // The maximum packet size of any QUIC packet, based on ethernet's max size, // minus the IP and UDP headers. IPv6 has a 40 byte header, UDP adds an diff --git a/chromium/net/quic/core/quic_crypto_client_stream.cc b/chromium/net/quic/core/quic_crypto_client_stream.cc index e6d86638359..f7fba7600bd 100644 --- a/chromium/net/quic/core/quic_crypto_client_stream.cc +++ b/chromium/net/quic/core/quic_crypto_client_stream.cc @@ -5,7 +5,6 @@ #include "net/quic/core/quic_crypto_client_stream.h" #include <memory> -#include <vector> #include "base/metrics/histogram_macros.h" #include "base/metrics/sparse_histogram.h" @@ -101,6 +100,7 @@ QuicCryptoClientStream::QuicCryptoClientStream( verify_context_(verify_context), proof_verify_callback_(nullptr), proof_handler_(proof_handler), + verify_ok_(false), stateless_reject_received_(false), num_scup_messages_received_(0) { DCHECK_EQ(Perspective::IS_CLIENT, session->connection()->perspective()); @@ -234,7 +234,7 @@ void QuicCryptoClientStream::DoHandshakeLoop(const CryptoHandshakeMessage* in) { DoInitializeServerConfigUpdate(cached); break; case STATE_NONE: - NOTREACHED(); + QUIC_NOTREACHED(); return; // We are done. } } while (rv != QUIC_PENDING && next_state_ != STATE_NONE); @@ -318,7 +318,7 @@ void QuicCryptoClientStream::DoSendCHLO( return; } // TODO(rch): Remove this when we remove: - // FLAGS_quic_use_chlo_packet_size + // FLAGS_quic_reloadable_flag_quic_use_chlo_packet_size out.set_minimum_size( static_cast<size_t>(max_packet_size - kFramingOverhead)); next_state_ = STATE_RECV_REJ; diff --git a/chromium/net/quic/core/quic_crypto_client_stream.h b/chromium/net/quic/core/quic_crypto_client_stream.h index cc937f09393..7327f311b72 100644 --- a/chromium/net/quic/core/quic_crypto_client_stream.h +++ b/chromium/net/quic/core/quic_crypto_client_stream.h @@ -21,7 +21,6 @@ namespace net { namespace test { -class CryptoTestUtils; class QuicChromiumClientSessionPeer; } // namespace test @@ -142,7 +141,6 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientStream QuicCryptoClientStream* stream_; }; - friend class test::CryptoTestUtils; friend class test::QuicChromiumClientSessionPeer; enum State { @@ -267,6 +265,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientStream // STATE_VERIFY_PROOF*, and subsequent STATE_SEND_CHLO state. bool stateless_reject_received_; + // Only used in chromium, not internally. base::TimeTicks proof_verify_start_time_; int num_scup_messages_received_; diff --git a/chromium/net/quic/core/quic_crypto_client_stream_test.cc b/chromium/net/quic/core/quic_crypto_client_stream_test.cc index bbc2f37217a..571ca249c74 100644 --- a/chromium/net/quic/core/quic_crypto_client_stream_test.cc +++ b/chromium/net/quic/core/quic_crypto_client_stream_test.cc @@ -36,7 +36,7 @@ class QuicCryptoClientStreamTest : public ::testing::Test { public: QuicCryptoClientStreamTest() : server_id_(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED), - crypto_config_(CryptoTestUtils::ProofVerifierForTesting()) { + crypto_config_(crypto_test_utils::ProofVerifierForTesting()) { CreateConnection(); } @@ -53,9 +53,9 @@ class QuicCryptoClientStreamTest : public ::testing::Test { void CompleteCryptoHandshake() { stream()->CryptoConnect(); QuicConfig config; - CryptoTestUtils::HandshakeWithFakeServer(&config, &server_helper_, - &alarm_factory_, connection_, - stream(), server_options_); + crypto_test_utils::HandshakeWithFakeServer(&config, &server_helper_, + &alarm_factory_, connection_, + stream(), server_options_); } void ConstructHandshakeMessage() { @@ -74,7 +74,7 @@ class QuicCryptoClientStreamTest : public ::testing::Test { CryptoHandshakeMessage message_; std::unique_ptr<QuicData> message_data_; QuicCryptoClientConfig crypto_config_; - CryptoTestUtils::FakeServerOptions server_options_; + crypto_test_utils::FakeServerOptions server_options_; }; TEST_F(QuicCryptoClientStreamTest, NotInitiallyConected) { @@ -244,20 +244,40 @@ TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateWithCert) { // Build a server config update message with certificates QuicCryptoServerConfig crypto_config( QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(), - CryptoTestUtils::ProofSourceForTesting()); - CryptoTestUtils::FakeServerOptions options; - CryptoTestUtils::SetupCryptoServerConfigForTest( + crypto_test_utils::ProofSourceForTesting()); + crypto_test_utils::FakeServerOptions options; + crypto_test_utils::SetupCryptoServerConfigForTest( connection_->clock(), QuicRandom::GetInstance(), &crypto_config, options); SourceAddressTokens tokens; QuicCompressedCertsCache cache(1); CachedNetworkParameters network_params; CryptoHandshakeMessage server_config_update; - EXPECT_TRUE(crypto_config.BuildServerConfigUpdateMessage( + + class Callback : public BuildServerConfigUpdateMessageResultCallback { + public: + Callback(bool* ok, CryptoHandshakeMessage* message) + : ok_(ok), message_(message) {} + void Run(bool ok, const CryptoHandshakeMessage& message) override { + *ok_ = ok; + *message_ = message; + } + + private: + bool* ok_; + CryptoHandshakeMessage* message_; + }; + + // Note: relies on the callback being invoked synchronously + bool ok = false; + crypto_config.BuildServerConfigUpdateMessage( session_->connection()->version(), stream()->chlo_hash(), tokens, QuicSocketAddress(QuicIpAddress::Loopback6(), 1234), QuicIpAddress::Loopback6(), connection_->clock(), QuicRandom::GetInstance(), &cache, stream()->crypto_negotiated_params(), - &network_params, QuicTagVector(), &server_config_update)); + &network_params, QuicTagVector(), + std::unique_ptr<BuildServerConfigUpdateMessageResultCallback>( + new Callback(&ok, &server_config_update))); + EXPECT_TRUE(ok); std::unique_ptr<QuicData> data( CryptoFramer::ConstructHandshakeMessage(server_config_update)); @@ -334,10 +354,10 @@ TEST_F(QuicCryptoClientStreamTest, NoTokenBindingInPrivacyMode) { class QuicCryptoClientStreamStatelessTest : public ::testing::Test { public: QuicCryptoClientStreamStatelessTest() - : client_crypto_config_(CryptoTestUtils::ProofVerifierForTesting()), + : client_crypto_config_(crypto_test_utils::ProofVerifierForTesting()), server_crypto_config_(QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(), - CryptoTestUtils::ProofSourceForTesting()), + crypto_test_utils::ProofSourceForTesting()), server_compressed_certs_cache_( QuicCompressedCertsCache::kQuicCompressedCertsCacheSize), server_id_(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED) { @@ -358,9 +378,9 @@ class QuicCryptoClientStreamStatelessTest : public ::testing::Test { void AdvanceHandshakeWithFakeServer() { client_session_->GetCryptoStream()->CryptoConnect(); - CryptoTestUtils::AdvanceHandshake(client_connection_, - client_session_->GetCryptoStream(), 0, - server_connection_, server_stream(), 0); + crypto_test_utils::AdvanceHandshake(client_connection_, + client_session_->GetCryptoStream(), 0, + server_connection_, server_stream(), 0); } // Initializes the server_stream_ for stateless rejects. @@ -373,8 +393,8 @@ class QuicCryptoClientStreamStatelessTest : public ::testing::Test { &server_connection_, &server_session); CHECK(server_session); server_session_.reset(server_session); - CryptoTestUtils::FakeServerOptions options; - CryptoTestUtils::SetupCryptoServerConfigForTest( + crypto_test_utils::FakeServerOptions options; + crypto_test_utils::SetupCryptoServerConfigForTest( server_connection_->clock(), server_connection_->random_generator(), &server_crypto_config_, options); FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support = true; diff --git a/chromium/net/quic/core/quic_crypto_server_stream.cc b/chromium/net/quic/core/quic_crypto_server_stream.cc index e08827bdd79..613692a7650 100644 --- a/chromium/net/quic/core/quic_crypto_server_stream.cc +++ b/chromium/net/quic/core/quic_crypto_server_stream.cc @@ -6,7 +6,6 @@ #include <memory> -#include "crypto/secure_hash.h" #include "net/quic/core/crypto/crypto_protocol.h" #include "net/quic/core/crypto/crypto_utils.h" #include "net/quic/core/crypto/quic_crypto_server_config.h" @@ -18,6 +17,7 @@ #include "net/quic/core/quic_session.h" #include "net/quic/platform/api/quic_logging.h" #include "net/quic/platform/api/quic_text_utils.h" +#include "third_party/boringssl/src/include/openssl/sha.h" using base::StringPiece; using std::string; @@ -284,55 +284,27 @@ void QuicCryptoServerStream::SendServerConfigUpdate( return; } - if (FLAGS_quic_reloadable_flag_enable_async_get_proof) { - if (send_server_config_update_cb_ != nullptr) { - QUIC_DVLOG(1) - << "Skipped server config update since one is already in progress"; - return; - } - - std::unique_ptr<SendServerConfigUpdateCallback> cb( - new SendServerConfigUpdateCallback(this)); - send_server_config_update_cb_ = cb.get(); - - crypto_config_->BuildServerConfigUpdateMessage( - session()->connection()->version(), chlo_hash_, - previous_source_address_tokens_, - session()->connection()->self_address(), - session()->connection()->peer_address().host(), - session()->connection()->clock(), - session()->connection()->random_generator(), compressed_certs_cache_, - *crypto_negotiated_params_, cached_network_params, - (session()->config()->HasReceivedConnectionOptions() - ? session()->config()->ReceivedConnectionOptions() - : QuicTagVector()), - std::move(cb)); - return; - } - - CryptoHandshakeMessage server_config_update_message; - if (!crypto_config_->BuildServerConfigUpdateMessage( - session()->connection()->version(), chlo_hash_, - previous_source_address_tokens_, - session()->connection()->self_address(), - session()->connection()->peer_address().host(), - session()->connection()->clock(), - session()->connection()->random_generator(), compressed_certs_cache_, - *crypto_negotiated_params_, cached_network_params, - (session()->config()->HasReceivedConnectionOptions() - ? session()->config()->ReceivedConnectionOptions() - : QuicTagVector()), - &server_config_update_message)) { - QUIC_DVLOG(1) << "Server: Failed to build server config update (SCUP)!"; + if (send_server_config_update_cb_ != nullptr) { + QUIC_DVLOG(1) + << "Skipped server config update since one is already in progress"; return; } - QUIC_DVLOG(1) << "Server: Sending server config update: " - << server_config_update_message.DebugString(); - const QuicData& data = server_config_update_message.GetSerialized(); - WriteOrBufferData(StringPiece(data.data(), data.length()), false, nullptr); - - ++num_server_config_update_messages_sent_; + std::unique_ptr<SendServerConfigUpdateCallback> cb( + new SendServerConfigUpdateCallback(this)); + send_server_config_update_cb_ = cb.get(); + + crypto_config_->BuildServerConfigUpdateMessage( + session()->connection()->version(), chlo_hash_, + previous_source_address_tokens_, session()->connection()->self_address(), + session()->connection()->peer_address().host(), + session()->connection()->clock(), + session()->connection()->random_generator(), compressed_certs_cache_, + *crypto_negotiated_params_, cached_network_params, + (session()->config()->HasReceivedConnectionOptions() + ? session()->config()->ReceivedConnectionOptions() + : QuicTagVector()), + std::move(cb)); } QuicCryptoServerStream::SendServerConfigUpdateCallback:: @@ -417,11 +389,9 @@ bool QuicCryptoServerStream::GetBase64SHA256ClientChannelID( } const string& channel_id(crypto_negotiated_params_->channel_id); - std::unique_ptr<crypto::SecureHash> hash( - crypto::SecureHash::Create(crypto::SecureHash::SHA256)); - hash->Update(channel_id.data(), channel_id.size()); - uint8_t digest[32]; - hash->Finish(digest, sizeof(digest)); + uint8_t digest[SHA256_DIGEST_LENGTH]; + SHA256(reinterpret_cast<const uint8_t*>(channel_id.data()), channel_id.size(), + digest); QuicTextUtils::Base64Encode(digest, arraysize(digest), output); return true; diff --git a/chromium/net/quic/core/quic_crypto_server_stream.h b/chromium/net/quic/core/quic_crypto_server_stream.h index 721a2763a22..893fbe976f9 100644 --- a/chromium/net/quic/core/quic_crypto_server_stream.h +++ b/chromium/net/quic/core/quic_crypto_server_stream.h @@ -26,7 +26,6 @@ class QuicCryptoServerConfig; class QuicCryptoServerStreamBase; namespace test { -class CryptoTestUtils; class QuicCryptoServerStreamPeer; } // namespace test @@ -139,7 +138,6 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerStream virtual void OverrideQuicConfigDefaults(QuicConfig* config); private: - friend class test::CryptoTestUtils; friend class test::QuicCryptoServerStreamPeer; class ValidateCallback : public ValidateClientHelloResultCallback { diff --git a/chromium/net/quic/core/quic_crypto_server_stream_test.cc b/chromium/net/quic/core/quic_crypto_server_stream_test.cc index bba6bda2fda..d7330b0806c 100644 --- a/chromium/net/quic/core/quic_crypto_server_stream_test.cc +++ b/chromium/net/quic/core/quic_crypto_server_stream_test.cc @@ -59,7 +59,8 @@ const uint16_t kServerPort = 443; class QuicCryptoServerStreamTest : public ::testing::TestWithParam<bool> { public: QuicCryptoServerStreamTest() - : QuicCryptoServerStreamTest(CryptoTestUtils::ProofSourceForTesting()) {} + : QuicCryptoServerStreamTest(crypto_test_utils::ProofSourceForTesting()) { + } explicit QuicCryptoServerStreamTest(std::unique_ptr<ProofSource> proof_source) : server_crypto_config_(QuicCryptoServerConfig::TESTING, @@ -68,7 +69,7 @@ class QuicCryptoServerStreamTest : public ::testing::TestWithParam<bool> { server_compressed_certs_cache_( QuicCompressedCertsCache::kQuicCompressedCertsCacheSize), server_id_(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED), - client_crypto_config_(CryptoTestUtils::ProofVerifierForTesting()) { + client_crypto_config_(crypto_test_utils::ProofVerifierForTesting()) { FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support = false; } @@ -96,9 +97,9 @@ class QuicCryptoServerStreamTest : public ::testing::TestWithParam<bool> { &server_connection_, &server_session); CHECK(server_session); server_session_.reset(server_session); - CryptoTestUtils::FakeServerOptions options; + crypto_test_utils::FakeServerOptions options; options.token_binding_params = QuicTagVector{kTB10}; - CryptoTestUtils::SetupCryptoServerConfigForTest( + crypto_test_utils::SetupCryptoServerConfigForTest( server_connection_->clock(), server_connection_->random_generator(), &server_crypto_config_, options); } @@ -134,7 +135,7 @@ class QuicCryptoServerStreamTest : public ::testing::TestWithParam<bool> { int CompleteCryptoHandshake() { CHECK(server_connection_); CHECK(server_session_ != nullptr); - return CryptoTestUtils::HandshakeWithFakeClient( + return crypto_test_utils::HandshakeWithFakeClient( helpers_.back().get(), alarm_factories_.back().get(), server_connection_, server_stream(), server_id_, client_options_); } @@ -147,8 +148,8 @@ class QuicCryptoServerStreamTest : public ::testing::TestWithParam<bool> { EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber()); client_stream()->CryptoConnect(); - CryptoTestUtils::AdvanceHandshake(client_connection_, client_stream(), 0, - server_connection_, server_stream(), 0); + crypto_test_utils::AdvanceHandshake(client_connection_, client_stream(), 0, + server_connection_, server_stream(), 0); } protected: @@ -174,7 +175,7 @@ class QuicCryptoServerStreamTest : public ::testing::TestWithParam<bool> { CryptoHandshakeMessage message_; std::unique_ptr<QuicData> message_data_; - CryptoTestUtils::FakeClientOptions client_options_; + crypto_test_utils::FakeClientOptions client_options_; // Which QUIC versions the client and server support. QuicVersionVector supported_versions_ = AllSupportedVersions(); @@ -228,7 +229,6 @@ TEST_P(QuicCryptoServerStreamTest, ForwardSecureAfterCHLO) { TEST_P(QuicCryptoServerStreamTest, StatelessRejectAfterCHLO) { FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support = true; - Initialize(); EXPECT_CALL(*server_connection_, @@ -262,7 +262,6 @@ TEST_P(QuicCryptoServerStreamTest, StatelessRejectAfterCHLO) { TEST_P(QuicCryptoServerStreamTest, ConnectedAfterStatelessHandshake) { FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support = true; - Initialize(); InitializeFakeClient(/* supports_stateless_rejects= */ true); @@ -306,7 +305,6 @@ TEST_P(QuicCryptoServerStreamTest, ConnectedAfterStatelessHandshake) { TEST_P(QuicCryptoServerStreamTest, NoStatelessRejectIfNoClientSupport) { FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support = true; - Initialize(); // The server is configured to use stateless rejects, but the client does not @@ -342,7 +340,7 @@ TEST_P(QuicCryptoServerStreamTest, ZeroRTT) { client_stream()->CryptoConnect(); - CryptoTestUtils::CommunicateHandshakeMessages( + crypto_test_utils::CommunicateHandshakeMessages( client_connection_, client_stream(), server_connection_, server_stream()); EXPECT_EQ(1, client_stream()->num_sent_client_hellos()); @@ -420,7 +418,7 @@ TEST_P(QuicCryptoServerStreamTest, OnlySendSCUPAfterHandshakeComplete) { TEST_P(QuicCryptoServerStreamTest, SendSCUPAfterHandshakeComplete) { // Do not send MAX_HEADER_LIST_SIZE SETTING frame. // TODO(fayang): This SETTING frame cannot be decrypted and - // CryptoTestUtils::MovePackets stops processing parsing following packets. + // crypto_test_utils::MovePackets stops processing parsing following packets. // Actually, crypto stream test should use QuicSession instead of // QuicSpdySession (b/32366134). FLAGS_quic_reloadable_flag_quic_send_max_header_list_size = false; @@ -440,8 +438,8 @@ TEST_P(QuicCryptoServerStreamTest, SendSCUPAfterHandshakeComplete) { // Send a SCUP message and ensure that the client was able to verify it. EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0); server_stream()->SendServerConfigUpdate(nullptr); - CryptoTestUtils::AdvanceHandshake(client_connection_, client_stream(), 1, - server_connection_, server_stream(), 1); + crypto_test_utils::AdvanceHandshake(client_connection_, client_stream(), 1, + server_connection_, server_stream(), 1); EXPECT_EQ(1, server_stream()->NumServerConfigUpdateMessagesSent()); EXPECT_EQ(1, client_stream()->num_scup_messages_received()); @@ -508,6 +506,5 @@ TEST_P(QuicCryptoServerStreamTestWithFailingProofSource, Test) { } } // namespace - } // namespace test } // namespace net diff --git a/chromium/net/quic/core/quic_crypto_stream.cc b/chromium/net/quic/core/quic_crypto_stream.cc index 814b2683a0c..645d389e9f9 100644 --- a/chromium/net/quic/core/quic_crypto_stream.cc +++ b/chromium/net/quic/core/quic_crypto_stream.cc @@ -17,7 +17,6 @@ using std::string; using base::StringPiece; -using net::SpdyPriority; namespace net { @@ -43,7 +42,6 @@ QuicByteCount QuicCryptoStream::CryptoMessageFramingOverhead( return QuicPacketCreator::StreamFramePacketOverhead( version, PACKET_8BYTE_CONNECTION_ID, /*include_version=*/true, - /*include_path_id=*/true, /*include_diversification_nonce=*/true, PACKET_1BYTE_PACKET_NUMBER, /*offset=*/0); } diff --git a/chromium/net/quic/core/quic_crypto_stream.h b/chromium/net/quic/core/quic_crypto_stream.h index 05aa23c5933..32ed81a9326 100644 --- a/chromium/net/quic/core/quic_crypto_stream.h +++ b/chromium/net/quic/core/quic_crypto_stream.h @@ -5,7 +5,7 @@ #ifndef NET_QUIC_CORE_QUIC_CRYPTO_STREAM_H_ #define NET_QUIC_CORE_QUIC_CRYPTO_STREAM_H_ -#include <stddef.h> +#include <cstddef> #include "base/macros.h" #include "net/quic/core/crypto/crypto_framer.h" diff --git a/chromium/net/quic/core/quic_crypto_stream_test.cc b/chromium/net/quic/core/quic_crypto_stream_test.cc index 5ef4aa965b1..16c6d84e08e 100644 --- a/chromium/net/quic/core/quic_crypto_stream_test.cc +++ b/chromium/net/quic/core/quic_crypto_stream_test.cc @@ -87,8 +87,8 @@ TEST_F(QuicCryptoStreamTest, ProcessRawData) { const CryptoHandshakeMessage& message = (*stream_.messages())[0]; EXPECT_EQ(kSHLO, message.tag()); EXPECT_EQ(2u, message.tag_value_map().size()); - EXPECT_EQ("abc", CryptoTestUtils::GetValueForTag(message, 1)); - EXPECT_EQ("def", CryptoTestUtils::GetValueForTag(message, 2)); + EXPECT_EQ("abc", crypto_test_utils::GetValueForTag(message, 1)); + EXPECT_EQ("def", crypto_test_utils::GetValueForTag(message, 2)); } TEST_F(QuicCryptoStreamTest, ProcessBadData) { diff --git a/chromium/net/quic/core/quic_error_codes.h b/chromium/net/quic/core/quic_error_codes.h index 7e341f186db..05124be0064 100644 --- a/chromium/net/quic/core/quic_error_codes.h +++ b/chromium/net/quic/core/quic_error_codes.h @@ -270,7 +270,6 @@ enum QuicErrorCode { QUIC_STREAM_SEQUENCER_INVALID_STATE = 95, // Connection closed because of server hits max number of sessions allowed. - // TODO(fayang): Add monitoring for QUIC_TOO_MANY_SESSIONS_ON_SERVER. QUIC_TOO_MANY_SESSIONS_ON_SERVER = 96, // No error. Used as bound while iterating. diff --git a/chromium/net/quic/core/quic_flags_list.h b/chromium/net/quic/core/quic_flags_list.h index 3941adc596d..8d28400385c 100644 --- a/chromium/net/quic/core/quic_flags_list.h +++ b/chromium/net/quic/core/quic_flags_list.h @@ -31,9 +31,6 @@ QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support, true) -// This flag is not in use, just to keep consistency for shared code. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_always_log_bugs_for_tests, true) - // If true, multipath is enabled for the connection. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_multipath, false) @@ -68,19 +65,12 @@ QUIC_FLAG(bool, // If true, re-enables QUIC_VERSION_36. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_version_36_v3, true) -// If true, use async codepaths to invoke ProofSource::GetProof. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_enable_async_get_proof, false) - // If true, only open limited number of quic sessions per epoll event. Leave the // rest to next event. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_limit_num_new_sessions_per_epoll_loop, true) -// Only close the connection on the 5th RTO client side when the 5RTO option -// is enabled. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_only_5rto_client_side, false) - // If true, QUIC server push will enabled by default. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_server_push_by_default, @@ -89,12 +79,6 @@ QUIC_FLAG(bool, // Allow large send deltas to be used as RTT samples. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_allow_large_send_deltas, true) -// Engage early retransmit anytime the largest acked is greater than -// or equal to the largest retransmittable packet. -QUIC_FLAG(bool, - FLAGS_quic_reloadable_flag_quic_largest_sent_retransmittable, - true) - // If true, release QuicCryptoStream\'s read buffer when stream are less // frequently used. QUIC_FLAG(bool, @@ -113,15 +97,8 @@ QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_buffer_packets_after_chlo, false) -// Previously QUIC didn't register a packet as received until it was fully -// processed, but now that flow control is implemented, it can be received once -// decrypted. -QUIC_FLAG(bool, - FLAGS_quic_reloadable_flag_quic_receive_packet_once_decrypted, - false) - // If true, enable the Lazy FACK style loss detection in QUIC. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_lazy_fack, false) +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_lazy_fack, true) // If true, do not override a connection in global map if exists. Only create // QUIC session if it is successfully inserted to the global map. Toss the @@ -152,13 +129,6 @@ QUIC_FLAG( FLAGS_quic_reloadable_flag_quic_headers_stream_release_sequencer_buffer, true) -// Set the retransmission alarm only when there are unacked -// retransmittable packets. -QUIC_FLAG( - bool, - FLAGS_quic_reloadable_flag_quic_more_conservative_retransmission_alarm, - true) - // Enable QUIC force HOL blocking experiment. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_force_hol_blocking, true) @@ -166,10 +136,6 @@ QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_force_hol_blocking, true) // allow CHLO packets to be buffered until next iteration of the event loop. QUIC_FLAG(bool, FLAGS_quic_allow_chlo_buffering, true) -// If true, fix version manager bug, in which version flag does not really -// help. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fix_version_manager, false) - // Add a new client connection options field to QuicOptions which is only used // to configure client side features, such as congestion control. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_client_connection_options, true) @@ -178,9 +144,6 @@ QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_client_connection_options, true) // "convex" increases. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fix_cubic_convex_mode, false) -// Ensure that BBR startup pacing rate does not drop below the initial one. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_bbr_faster_startup, true) - // If true, GFE sends SETTINGS_MAX_HEADER_LIST_SIZE to the client at the // beginning of a connection. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_send_max_header_list_size, true) @@ -192,7 +155,7 @@ QUIC_FLAG(bool, // If true, QUIC cubic code will use the event time when adjusting CWND after an // ACK instead of the clock\'s current approximate time. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_use_event_time, false) +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_use_event_time, true) // If true, lazy allocate and early release memeory used in // QuicStreamSequencerBuffer to buffer incoming data. @@ -203,16 +166,35 @@ QUIC_FLAG( // If true, Makes GFE respect the connection options for initial flow control // window larger than 32 KB. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_large_ifw_options, false) +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_large_ifw_options, true) // If true, fix Cubic\'s use of kBetaLastMax for n-connection emulation. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fix_beta_last_max, false) // If true, enable QUIC v37. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_version_37, false) +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_version_37, true) // If true, disables QUIC v34. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_34, false) +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_34, true) // Allow quic to properly support proxying 100 Continue responses. QUIC_FLAG(bool, FLAGS_quic_restart_flag_quic_supports_100_continue, false) + +// If true, enable quic version 38 +QUIC_FLAG(bool, FLAGS_quic_enable_version_38, false) + +// When true, ensures the session's flow control window is always at least 1.5x +// larger than the largest stream flow control window. +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_flow_control_invariant, false) + +// If greater than zero, mean RTT variation is multiplied by the specified +// factor and added to the congestion window limit. +QUIC_FLAG(double, FLAGS_quic_bbr_rtt_variation_weight, 0.0f) + +// Congestion window gain for QUIC BBR during PROBE_BW phase. +QUIC_FLAG(double, FLAGS_quic_bbr_cwnd_gain, 2.0f) + +// If true, bidi streaming is always enabled in QUIC. +QUIC_FLAG(bool, + FLAGS_quic_reloadable_flag_quic_always_enable_bidi_streaming, + false) diff --git a/chromium/net/quic/core/quic_flow_controller.cc b/chromium/net/quic/core/quic_flow_controller.cc index 976c0ff1d92..d519032aa22 100644 --- a/chromium/net/quic/core/quic_flow_controller.cc +++ b/chromium/net/quic/core/quic_flow_controller.cc @@ -17,12 +17,14 @@ namespace net { #define ENDPOINT \ (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ") -QuicFlowController::QuicFlowController(QuicConnection* connection, - QuicStreamId id, - Perspective perspective, - QuicStreamOffset send_window_offset, - QuicStreamOffset receive_window_offset, - bool should_auto_tune_receive_window) +QuicFlowController::QuicFlowController( + QuicConnection* connection, + QuicStreamId id, + Perspective perspective, + QuicStreamOffset send_window_offset, + QuicStreamOffset receive_window_offset, + bool should_auto_tune_receive_window, + QuicFlowControllerInterface* session_flow_controller) : connection_(connection), id_(id), perspective_(perspective), @@ -33,6 +35,7 @@ QuicFlowController::QuicFlowController(QuicConnection* connection, receive_window_offset_(receive_window_offset), receive_window_size_(receive_window_offset), auto_tune_receive_window_(should_auto_tune_receive_window), + session_flow_controller_(session_flow_controller), last_blocked_send_window_offset_(0), prev_window_update_time_(QuicTime::Zero()) { receive_window_size_limit_ = (id_ == kConnectionLevelId) @@ -51,8 +54,8 @@ QuicFlowController::QuicFlowController(QuicConnection* connection, void QuicFlowController::AddBytesConsumed(QuicByteCount bytes_consumed) { bytes_consumed_ += bytes_consumed; - QUIC_DVLOG(1) << ENDPOINT << "Stream " << id_ - << " consumed: " << bytes_consumed_; + QUIC_DVLOG(1) << ENDPOINT << "Stream " << id_ << " consumed " + << bytes_consumed_ << " bytes."; MaybeSendWindowUpdate(); } @@ -65,7 +68,7 @@ bool QuicFlowController::UpdateHighestReceivedOffset( } QUIC_DVLOG(1) << ENDPOINT << "Stream " << id_ - << " highest byte offset increased from: " + << " highest byte offset increased from " << highest_received_byte_offset_ << " to " << new_offset; highest_received_byte_offset_ = new_offset; return true; @@ -88,7 +91,8 @@ void QuicFlowController::AddBytesSent(QuicByteCount bytes_sent) { } bytes_sent_ += bytes_sent; - QUIC_DVLOG(1) << ENDPOINT << "Stream " << id_ << " sent: " << bytes_sent_; + QUIC_DVLOG(1) << ENDPOINT << "Stream " << id_ << " sent " << bytes_sent_ + << " bytes."; } bool QuicFlowController::FlowControlViolation() { @@ -141,17 +145,18 @@ void QuicFlowController::MaybeIncreaseMaxWindowSize() { // is no need to increase receive_window_size_. return; } - QuicByteCount old_window = receive_window_size_; - receive_window_size_ *= 2; - receive_window_size_ = - std::min(receive_window_size_, receive_window_size_limit_); + IncreaseWindowSize(); if (receive_window_size_ > old_window) { QUIC_DVLOG(1) << ENDPOINT << "New max window increase for stream " << id_ << " after " << since_last.ToMicroseconds() << " us, and RTT is " << rtt.ToMicroseconds() << "us. max wndw: " << receive_window_size_; + if (session_flow_controller_ != nullptr) { + session_flow_controller_->EnsureWindowAtLeast( + kSessionFlowControlMultiplier * receive_window_size_); + } } else { // TODO(ckrasic) - add a varz to track this (?). QUIC_LOG_FIRST_N(INFO, 1) << ENDPOINT << "Max window at limit for stream " @@ -161,6 +166,12 @@ void QuicFlowController::MaybeIncreaseMaxWindowSize() { } } +void QuicFlowController::IncreaseWindowSize() { + receive_window_size_ *= 2; + receive_window_size_ = + std::min(receive_window_size_, receive_window_size_limit_); +} + QuicByteCount QuicFlowController::WindowUpdateThreshold() { return receive_window_size_ / 2; } @@ -181,14 +192,17 @@ void QuicFlowController::MaybeSendWindowUpdate() { } MaybeIncreaseMaxWindowSize(); + SendWindowUpdate(available_window); +} +void QuicFlowController::SendWindowUpdate(QuicStreamOffset available_window) { // Update our receive window. receive_window_offset_ += (receive_window_size_ - available_window); QUIC_DVLOG(1) << ENDPOINT << "Sending WindowUpdate frame for stream " << id_ << ", consumed bytes: " << bytes_consumed_ << ", available window: " << available_window - << ", and threshold: " << threshold + << ", and threshold: " << WindowUpdateThreshold() << ", and receive window size: " << receive_window_size_ << ". New receive window offset is: " << receive_window_offset_; @@ -231,6 +245,16 @@ bool QuicFlowController::UpdateSendWindowOffset( return blocked; } +void QuicFlowController::EnsureWindowAtLeast(QuicByteCount window_size) { + if (receive_window_size_limit_ >= window_size) { + return; + } + + QuicStreamOffset available_window = receive_window_offset_ - bytes_consumed_; + IncreaseWindowSize(); + SendWindowUpdate(available_window); +} + bool QuicFlowController::IsBlocked() const { return SendWindowSize() == 0; } diff --git a/chromium/net/quic/core/quic_flow_controller.h b/chromium/net/quic/core/quic_flow_controller.h index 94225636c28..b955da15302 100644 --- a/chromium/net/quic/core/quic_flow_controller.h +++ b/chromium/net/quic/core/quic_flow_controller.h @@ -19,20 +19,35 @@ class QuicConnection; const QuicStreamId kConnectionLevelId = 0; +// How much larger the session flow control window needs to be relative to any +// stream's flow control window. +const float kSessionFlowControlMultiplier = 1.5; + +class QUIC_EXPORT_PRIVATE QuicFlowControllerInterface { + public: + virtual ~QuicFlowControllerInterface() {} + + // Ensures the flow control window is at least |window_size| and send out an + // update frame if it is increased. + virtual void EnsureWindowAtLeast(QuicByteCount window_size) = 0; +}; + // QuicFlowController allows a QUIC stream or connection to perform flow // control. The stream/connection owns a QuicFlowController which keeps track of // bytes sent/received, can tell the owner if it is flow control blocked, and // can send WINDOW_UPDATE or BLOCKED frames when needed. -class QUIC_EXPORT_PRIVATE QuicFlowController { +class QUIC_EXPORT_PRIVATE QuicFlowController + : public QuicFlowControllerInterface { public: QuicFlowController(QuicConnection* connection, QuicStreamId id, Perspective perspective, - QuicStreamOffset send_window_offset, - QuicStreamOffset receive_window_offset, - bool should_auto_tune_receive_window); + QuicStreamOffset send_window_size, + QuicStreamOffset receive_window_size, + bool should_auto_tune_receive_window, + QuicFlowControllerInterface* session_flow_controller); - ~QuicFlowController() {} + ~QuicFlowController() override {} // Called when we see a new highest received byte offset from the peer, either // via a data frame or a RST. @@ -51,6 +66,9 @@ class QUIC_EXPORT_PRIVATE QuicFlowController { // Returns true if this increases send_window_offset_ and is now blocked. bool UpdateSendWindowOffset(QuicStreamOffset new_send_window_offset); + // QuicFlowControllerInterface. + void EnsureWindowAtLeast(QuicByteCount window_size) override; + // Returns the current available send window. QuicByteCount SendWindowSize() const; @@ -92,6 +110,12 @@ class QUIC_EXPORT_PRIVATE QuicFlowController { // Auto-tune the max receive window size. void MaybeIncreaseMaxWindowSize(); + // Updates the current offset and sends a window update frame. + void SendWindowUpdate(QuicStreamOffset available_window); + + // Double the window size as long as we haven't hit the max window size. + void IncreaseWindowSize(); + // The parent connection, used to send connection close on flow control // violation, and WINDOW_UPDATE and BLOCKED frames when appropriate. // Not owned. @@ -152,6 +176,11 @@ class QUIC_EXPORT_PRIVATE QuicFlowController { // Used to dynamically enable receive window auto-tuning. bool auto_tune_receive_window_; + // The session's flow controller. null if this is stream id 0 or + // FLAGS_quic_reloadable_flag_quic_flow_control_invariant is false. + // Not owned. + QuicFlowControllerInterface* session_flow_controller_; + // Send window update when receive window size drops below this. QuicByteCount WindowUpdateThreshold(); diff --git a/chromium/net/quic/core/quic_flow_controller_test.cc b/chromium/net/quic/core/quic_flow_controller_test.cc index 93a07a58175..9e8eb45b36f 100644 --- a/chromium/net/quic/core/quic_flow_controller_test.cc +++ b/chromium/net/quic/core/quic_flow_controller_test.cc @@ -6,7 +6,6 @@ #include <memory> -#include "base/format_macros.h" #include "net/quic/platform/api/quic_str_cat.h" #include "net/quic/test_tools/quic_connection_peer.h" #include "net/quic/test_tools/quic_flow_controller_peer.h" @@ -22,6 +21,17 @@ namespace test { // Receive window auto-tuning uses RTT in its logic. const int64_t kRtt = 100; +class MockFlowController : public QuicFlowControllerInterface { + public: + MockFlowController() {} + ~MockFlowController() override {} + + MOCK_METHOD1(EnsureWindowAtLeast, void(QuicByteCount)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockFlowController); +}; + class QuicFlowControllerTest : public ::testing::Test { public: QuicFlowControllerTest() @@ -31,9 +41,9 @@ class QuicFlowControllerTest : public ::testing::Test { connection_(&helper_, &alarm_factory_, Perspective::IS_CLIENT) {} void Initialize() { - flow_controller_.reset( - new QuicFlowController(&connection_, stream_id_, Perspective::IS_CLIENT, - send_window_, receive_window_, false)); + flow_controller_.reset(new QuicFlowController( + &connection_, stream_id_, Perspective::IS_CLIENT, send_window_, + receive_window_, false, &session_flow_controller_)); } protected: @@ -44,6 +54,7 @@ class QuicFlowControllerTest : public ::testing::Test { MockQuicConnectionHelper helper_; MockAlarmFactory alarm_factory_; MockQuicConnection connection_; + MockFlowController session_flow_controller_; }; TEST_F(QuicFlowControllerTest, SendingBytes) { @@ -195,6 +206,10 @@ TEST_F(QuicFlowControllerTest, ReceivingBytesFastIncreasesFlowWindow) { // Move time forward, but by less than two RTTs. Then receive and consume // some more, forcing a second WINDOW_UPDATE with an increased max window // size. + EXPECT_CALL( + session_flow_controller_, + EnsureWindowAtLeast(kInitialSessionFlowControlWindowForTest * 2 * 1.5)); + connection_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt - 1)); receive_offset += threshold + 1; EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset)); diff --git a/chromium/net/quic/core/quic_framer.cc b/chromium/net/quic/core/quic_framer.cc index 99c23b97d57..e32db271348 100644 --- a/chromium/net/quic/core/quic_framer.cc +++ b/chromium/net/quic/core/quic_framer.cc @@ -8,7 +8,6 @@ #include <memory> #include "base/compiler_specific.h" -#include "base/stl_util.h" #include "net/quic/core/crypto/crypto_framer.h" #include "net/quic/core/crypto/crypto_handshake_message.h" #include "net/quic/core/crypto/crypto_protocol.h" @@ -24,12 +23,11 @@ #include "net/quic/platform/api/quic_aligned.h" #include "net/quic/platform/api/quic_bug_tracker.h" #include "net/quic/platform/api/quic_logging.h" +#include "net/quic/platform/api/quic_map_util.h" #include "net/quic/platform/api/quic_ptr_util.h" -using base::ContainsKey; using base::StringPiece; using std::string; -#define PREDICT_FALSE(x) (x) namespace net { @@ -138,8 +136,8 @@ QuicFramer::QuicFramer(const QuicVersionVector& supported_versions, error_(QUIC_NO_ERROR), last_packet_number_(0), largest_packet_number_(0), - last_path_id_(kInvalidPathId), last_serialized_connection_id_(0), + last_version_tag_(0), supported_versions_(supported_versions), decrypter_level_(ENCRYPTION_NONE), alternative_decrypter_level_(ENCRYPTION_NONE), @@ -698,7 +696,9 @@ bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header, if (header.public_header.version_flag) { DCHECK_EQ(Perspective::IS_CLIENT, perspective_); QuicTag tag = QuicVersionToQuicTag(quic_version_); - writer->WriteUInt32(tag); + if (!writer->WriteUInt32(tag)) { + return false; + } QUIC_DVLOG(1) << ENDPOINT << "version = " << quic_version_ << ", tag = '" << QuicTagToString(tag) << "'"; } @@ -745,46 +745,12 @@ const QuicTime::Delta QuicFramer::CalculateTimestampFromWire( return QuicTime::Delta::FromMicroseconds(time); } -bool QuicFramer::IsValidPath(QuicPathId path_id, - QuicPacketNumber* base_packet_number) { - if (ContainsKey(closed_paths_, path_id)) { - // Path is closed. - return false; - } - - if (path_id == last_path_id_) { - *base_packet_number = largest_packet_number_; - return true; - } - - if (ContainsKey(largest_packet_numbers_, path_id)) { - *base_packet_number = largest_packet_numbers_[path_id]; - } else { - *base_packet_number = 0; - } - - return true; -} - void QuicFramer::SetLastPacketNumber(const QuicPacketHeader& header) { - if (header.public_header.multipath_flag && header.path_id != last_path_id_) { - if (last_path_id_ != kInvalidPathId) { - // Save current last packet number before changing path. - largest_packet_numbers_[last_path_id_] = largest_packet_number_; - } - // Change path. - last_path_id_ = header.path_id; - } last_packet_number_ = header.packet_number; largest_packet_number_ = std::max(header.packet_number, largest_packet_number_); } -void QuicFramer::OnPathClosed(QuicPathId path_id) { - closed_paths_.insert(path_id); - largest_packet_numbers_.erase(path_id); -} - QuicPacketNumber QuicFramer::CalculatePacketNumberFromWire( QuicPacketNumberLength packet_number_length, QuicPacketNumber base_packet_number, @@ -966,12 +932,6 @@ bool QuicFramer::ProcessUnauthenticatedHeader(QuicDataReader* encrypted_reader, } QuicPacketNumber base_packet_number = largest_packet_number_; - if (header->public_header.multipath_flag && - !IsValidPath(header->path_id, &base_packet_number)) { - // Stop processing because path is closed. - set_detailed_error("Path is closed."); - return false; - } if (!ProcessPacketSequenceNumber( encrypted_reader, header->public_header.packet_number_length, @@ -1526,15 +1486,13 @@ StringPiece QuicFramer::GetAssociatedDataFromEncryptedPacket( const QuicEncryptedPacket& encrypted, QuicConnectionIdLength connection_id_length, bool includes_version, - bool includes_path_id, bool includes_diversification_nonce, QuicPacketNumberLength packet_number_length) { // TODO(ianswett): This is identical to QuicData::AssociatedData. - return StringPiece( - encrypted.data(), - GetStartOfEncryptedData(version, connection_id_length, includes_version, - includes_path_id, includes_diversification_nonce, - packet_number_length)); + return StringPiece(encrypted.data(), + GetStartOfEncryptedData( + version, connection_id_length, includes_version, + includes_diversification_nonce, packet_number_length)); } void QuicFramer::SetDecrypter(EncryptionLevel level, QuicDecrypter* decrypter) { @@ -1575,7 +1533,7 @@ size_t QuicFramer::EncryptInPlace(EncryptionLevel level, char* buffer) { size_t output_length = 0; if (!encrypter_[level]->EncryptPacket( - quic_version_, path_id, packet_number, + quic_version_, packet_number, StringPiece(buffer, ad_len), // Associated data StringPiece(buffer + ad_len, total_len - ad_len), // Plaintext buffer + ad_len, // Destination buffer @@ -1588,7 +1546,6 @@ size_t QuicFramer::EncryptInPlace(EncryptionLevel level, } size_t QuicFramer::EncryptPayload(EncryptionLevel level, - QuicPathId path_id, QuicPacketNumber packet_number, const QuicPacket& packet, char* buffer, @@ -1603,7 +1560,7 @@ size_t QuicFramer::EncryptPayload(EncryptionLevel level, // Encrypt the plaintext into the buffer. size_t output_length = 0; if (!encrypter_[level]->EncryptPacket( - quic_version_, path_id, packet_number, associated_data, + quic_version_, packet_number, associated_data, packet.Plaintext(quic_version_), buffer + ad_len, &output_length, buffer_len - ad_len)) { RaiseError(QUIC_ENCRYPTION_FAILURE); @@ -1640,13 +1597,12 @@ bool QuicFramer::DecryptPayload(QuicDataReader* encrypted_reader, DCHECK(decrypter_.get() != nullptr); StringPiece associated_data = GetAssociatedDataFromEncryptedPacket( quic_version_, packet, header.public_header.connection_id_length, - header.public_header.version_flag, header.public_header.multipath_flag, - header.public_header.nonce != nullptr, + header.public_header.version_flag, header.public_header.nonce != nullptr, header.public_header.packet_number_length); bool success = decrypter_->DecryptPacket( - quic_version_, header.path_id, header.packet_number, associated_data, - encrypted, decrypted_buffer, decrypted_length, buffer_length); + quic_version_, header.packet_number, associated_data, encrypted, + decrypted_buffer, decrypted_length, buffer_length); if (success) { visitor_->OnDecryptedPacket(decrypter_level_); } else if (alternative_decrypter_.get() != nullptr) { @@ -1669,8 +1625,8 @@ bool QuicFramer::DecryptPayload(QuicDataReader* encrypted_reader, if (try_alternative_decryption) { success = alternative_decrypter_->DecryptPacket( - quic_version_, header.path_id, header.packet_number, associated_data, - encrypted, decrypted_buffer, decrypted_length, buffer_length); + quic_version_, header.packet_number, associated_data, encrypted, + decrypted_buffer, decrypted_length, buffer_length); } if (success) { visitor_->OnDecryptedPacket(alternative_decrypter_level_); @@ -2000,7 +1956,7 @@ bool QuicFramer::AppendAckFrameAndTypeByte(const QuicAckFrame& frame, ++num_ack_blocks_written; } if (num_ack_blocks_written >= num_ack_blocks) { - if (PREDICT_FALSE(num_ack_blocks_written != num_ack_blocks)) { + if (QUIC_PREDICT_FALSE(num_ack_blocks_written != num_ack_blocks)) { QUIC_BUG << "Wrote " << num_ack_blocks_written << ", expected to write " << num_ack_blocks; } diff --git a/chromium/net/quic/core/quic_framer.h b/chromium/net/quic/core/quic_framer.h index a40b211690f..23d3c3ce6ba 100644 --- a/chromium/net/quic/core/quic_framer.h +++ b/chromium/net/quic/core/quic_framer.h @@ -9,8 +9,6 @@ #include <cstdint> #include <memory> #include <string> -#include <unordered_map> -#include <unordered_set> #include "base/macros.h" #include "base/strings/string_piece.h" @@ -238,7 +236,6 @@ class QUIC_EXPORT_PRIVATE QuicFramer { const QuicEncryptedPacket& encrypted, QuicConnectionIdLength connection_id_length, bool includes_version, - bool includes_path_id, bool includes_diversification_nonce, QuicPacketNumberLength packet_number_length); @@ -309,7 +306,6 @@ class QUIC_EXPORT_PRIVATE QuicFramer { // Returns the length of the data encrypted into |buffer| if |buffer_len| is // long enough, and otherwise 0. size_t EncryptPayload(EncryptionLevel level, - QuicPathId path_id, QuicPacketNumber packet_number, const QuicPacket& packet, char* buffer, @@ -334,9 +330,6 @@ class QUIC_EXPORT_PRIVATE QuicFramer { Perspective perspective() const { return perspective_; } - // Called when a PATH_CLOSED frame has been sent/received on |path_id|. - void OnPathClosed(QuicPathId path_id); - QuicTag last_version_tag() { return last_version_tag_; } private: @@ -409,12 +402,6 @@ class QUIC_EXPORT_PRIVATE QuicFramer { size_t buffer_length, size_t* decrypted_length); - // Checks if |path_id| is a viable path to receive packets on. Returns true - // and sets |base_packet_number| to the packet number to calculate the - // incoming packet number from if the path is not closed. Returns false - // otherwise. - bool IsValidPath(QuicPathId path_id, QuicPacketNumber* base_packet_number); - // Sets last_packet_number_. This can only be called after the packet is // successfully decrypted. void SetLastPacketNumber(const QuicPacketHeader& header); @@ -493,20 +480,10 @@ class QUIC_EXPORT_PRIVATE QuicFramer { std::string detailed_error_; QuicFramerVisitorInterface* visitor_; QuicErrorCode error_; - // Set of closed paths. A path is considered as closed if a PATH_CLOSED frame - // has been sent/received. - // TODO(fayang): this set is never cleaned up. A possible improvement is to - // use intervals. - std::unordered_set<QuicPathId> closed_paths_; // Updated by ProcessPacketHeader when it succeeds. QuicPacketNumber last_packet_number_; - // Map mapping path id to packet number of largest successfully decrypted - // received packet. - std::unordered_map<QuicPathId, QuicPacketNumber> largest_packet_numbers_; // Updated by ProcessPacketHeader when it succeeds decrypting a larger packet. QuicPacketNumber largest_packet_number_; - // The path on which last successfully decrypted packet was received. - QuicPathId last_path_id_; // Updated by WritePacketHeader. QuicConnectionId last_serialized_connection_id_; // The last QUIC version tag received. diff --git a/chromium/net/quic/core/quic_framer_test.cc b/chromium/net/quic/core/quic_framer_test.cc index 645c2c6d9db..01a201df711 100644 --- a/chromium/net/quic/core/quic_framer_test.cc +++ b/chromium/net/quic/core/quic_framer_test.cc @@ -39,7 +39,6 @@ const QuicPacketNumber kMask = kEpoch - 1; // Use fields in which each byte is distinct to ensure that every byte is // framed correctly. The values are otherwise arbitrary. const QuicConnectionId kConnectionId = UINT64_C(0xFEDCBA9876543210); -const QuicPathId kPathId = 0x42; const QuicPacketNumber kPacketNumber = UINT64_C(0x123456789ABC); const QuicPacketNumber kSmallLargestObserved = UINT16_C(0x1234); const QuicPacketNumber kSmallMissingPacket = UINT16_C(0x1233); @@ -113,7 +112,6 @@ class TestEncrypter : public QuicEncrypter { bool SetKey(StringPiece key) override { return true; } bool SetNoncePrefix(StringPiece nonce_prefix) override { return true; } bool EncryptPacket(QuicVersion version, - QuicPathId path_id, QuicPacketNumber packet_number, StringPiece associated_data, StringPiece plaintext, @@ -121,7 +119,6 @@ class TestEncrypter : public QuicEncrypter { size_t* output_length, size_t max_output_length) override { version_ = version; - path_id_ = path_id; packet_number_ = packet_number; associated_data_ = associated_data.as_string(); plaintext_ = plaintext.as_string(); @@ -142,7 +139,6 @@ class TestEncrypter : public QuicEncrypter { QuicVersion version_; Perspective perspective_; - QuicPathId path_id_; QuicPacketNumber packet_number_; string associated_data_; string plaintext_; @@ -161,7 +157,6 @@ class TestDecrypter : public QuicDecrypter { return true; } bool DecryptPacket(QuicVersion version, - QuicPathId path_id, QuicPacketNumber packet_number, StringPiece associated_data, StringPiece ciphertext, @@ -169,7 +164,6 @@ class TestDecrypter : public QuicDecrypter { size_t* output_length, size_t max_output_length) override { version_ = version; - path_id_ = path_id; packet_number_ = packet_number; associated_data_ = associated_data.as_string(); ciphertext_ = ciphertext.as_string(); @@ -184,7 +178,6 @@ class TestDecrypter : public QuicDecrypter { uint32_t cipher_id() const override { return 0xFFFFFFF2; } QuicVersion version_; Perspective perspective_; - QuicPathId path_id_; QuicPacketNumber packet_number_; string associated_data_; string ciphertext_; @@ -390,7 +383,6 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> { bool CheckDecryption(const QuicEncryptedPacket& encrypted, bool includes_version, - bool includes_path_id, bool includes_diversification_nonce) { EXPECT_EQ(version_, decrypter_->version_); if (visitor_.header_->packet_number != decrypter_->packet_number_) { @@ -401,13 +393,13 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> { } if (QuicFramer::GetAssociatedDataFromEncryptedPacket( framer_.version(), encrypted, PACKET_8BYTE_CONNECTION_ID, - includes_version, includes_path_id, includes_diversification_nonce, + includes_version, includes_diversification_nonce, PACKET_6BYTE_PACKET_NUMBER) != decrypter_->associated_data_) { QUIC_LOG(ERROR) << "Decrypted incorrect associated data. expected " << QuicFramer::GetAssociatedDataFromEncryptedPacket( framer_.version(), encrypted, PACKET_8BYTE_CONNECTION_ID, includes_version, - includes_path_id, includes_diversification_nonce, + includes_diversification_nonce, PACKET_6BYTE_PACKET_NUMBER) << " actual: " << decrypter_->associated_data_; return false; @@ -415,8 +407,7 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> { StringPiece ciphertext( encrypted.AsStringPiece().substr(GetStartOfEncryptedData( framer_.version(), PACKET_8BYTE_CONNECTION_ID, includes_version, - includes_path_id, includes_diversification_nonce, - PACKET_6BYTE_PACKET_NUMBER))); + includes_diversification_nonce, PACKET_6BYTE_PACKET_NUMBER))); if (ciphertext != decrypter_->ciphertext_) { QUIC_LOG(ERROR) << "Decrypted incorrect ciphertext data. expected " << ciphertext << " actual: " << decrypter_->ciphertext_; @@ -457,11 +448,10 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> { expected_error = "Unable to read frame data."; } CheckProcessingFails( - packet, - i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, - include_version, !kIncludePathId, - !kIncludeDiversificationNonce, - PACKET_6BYTE_PACKET_NUMBER), + packet, i + GetPacketHeaderSize( + framer_.version(), PACKET_8BYTE_CONNECTION_ID, + include_version, !kIncludeDiversificationNonce, + PACKET_6BYTE_PACKET_NUMBER), expected_error, QUIC_INVALID_STREAM_DATA); } } @@ -628,8 +618,7 @@ TEST_P(QuicFramerTest, LargePacket) { const size_t header_size = GetPacketHeaderSize( framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, - !kIncludePathId, !kIncludeDiversificationNonce, - PACKET_6BYTE_PACKET_NUMBER); + !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER); memset(packet + header_size, 0, kMaxPacketSize - header_size); @@ -668,8 +657,7 @@ TEST_P(QuicFramerTest, PacketHeader) { // Now test framing boundaries. for (size_t i = 0; i < GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, !kIncludePathId, - !kIncludeDiversificationNonce, + !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER); ++i) { string expected_error; @@ -711,8 +699,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) { // Now test framing boundaries. for (size_t i = 0; i < GetPacketHeaderSize(framer_.version(), PACKET_0BYTE_CONNECTION_ID, - !kIncludeVersion, !kIncludePathId, - !kIncludeDiversificationNonce, + !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER); ++i) { string expected_error; @@ -756,8 +743,7 @@ TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) { // Now test framing boundaries. for (size_t i = 0; i < GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, - kIncludeVersion, !kIncludePathId, - !kIncludeDiversificationNonce, + kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER); ++i) { string expected_error; @@ -774,210 +760,6 @@ TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) { } } -TEST_P(QuicFramerTest, PacketHeaderWithMultipathFlag) { - // clang-format off - unsigned char packet[] = { - // public flags (version) - 0x78, - // connection_id - 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, - // path_id - 0x42, - // packet number - 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, - }; - // clang-format on - - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); - EXPECT_FALSE(framer_.ProcessPacket(encrypted)); - EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); - ASSERT_TRUE(visitor_.header_.get()); - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, kIncludePathId, - !kIncludeDiversificationNonce)); - EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id); - EXPECT_TRUE(visitor_.header_->public_header.multipath_flag); - EXPECT_FALSE(visitor_.header_->public_header.reset_flag); - EXPECT_FALSE(visitor_.header_->public_header.version_flag); - EXPECT_EQ(kPathId, visitor_.header_->path_id); - EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number); - - // Now test framing boundaries. - for (size_t i = 0; - i < GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, kIncludePathId, - !kIncludeDiversificationNonce, - PACKET_6BYTE_PACKET_NUMBER); - ++i) { - string expected_error; - if (i < kConnectionIdOffset) { - expected_error = "Unable to read public flags."; - } else if (i < - GetPathIdOffset(PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion)) { - expected_error = "Unable to read ConnectionId."; - } else if (i < GetPacketNumberOffset(!kIncludeVersion, kIncludePathId)) { - expected_error = "Unable to read path id."; - } else { - expected_error = "Unable to read packet number."; - } - CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER); - } -} - -TEST_P(QuicFramerTest, PacketHeaderWithBothVersionFlagAndMultipathFlag) { - // clang-format off - unsigned char packet[] = { - // public flags (version) - 0x79, - // connection_id - 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, - // version tag - 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(), - // path_id - 0x42, - // packet number - 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, - }; - // clang-format on - - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); - EXPECT_FALSE(framer_.ProcessPacket(encrypted)); - EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); - ASSERT_TRUE(visitor_.header_.get()); - EXPECT_TRUE(CheckDecryption(encrypted, kIncludeVersion, kIncludePathId, - !kIncludeDiversificationNonce)); - EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id); - EXPECT_TRUE(visitor_.header_->public_header.multipath_flag); - EXPECT_FALSE(visitor_.header_->public_header.reset_flag); - EXPECT_TRUE(visitor_.header_->public_header.version_flag); - EXPECT_EQ(GetParam(), visitor_.header_->public_header.versions[0]); - EXPECT_EQ(kPathId, visitor_.header_->path_id); - EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number); - - // Now test framing boundaries. - for (size_t i = 0; - i < GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, kIncludePathId, - !kIncludeDiversificationNonce, - PACKET_6BYTE_PACKET_NUMBER); - ++i) { - string expected_error; - if (i < kConnectionIdOffset) { - expected_error = "Unable to read public flags."; - } else if (i < kVersionOffset) { - expected_error = "Unable to read ConnectionId."; - } else if (i < - GetPathIdOffset(PACKET_8BYTE_CONNECTION_ID, kIncludeVersion)) { - expected_error = "Unable to read protocol version."; - } else if (i < GetPacketNumberOffset(kIncludeVersion, kIncludePathId)) { - expected_error = "Unable to read path id."; - } else { - expected_error = "Unable to read packet number."; - } - CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_PACKET_HEADER); - } -} - -TEST_P(QuicFramerTest, PacketHeaderWithPathChange) { - // Packet 1 from path 0x42. - // clang-format off - unsigned char packet1[] = { - // public flags (version) - 0x78, - // connection_id - 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, - // path_id - 0x42, - // packet number - 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, - }; - // clang-format on - - EXPECT_EQ(0u, QuicFramerPeer::GetLastPacketNumber(&framer_)); - EXPECT_EQ(kInvalidPathId, QuicFramerPeer::GetLastPathId(&framer_)); - QuicEncryptedPacket encrypted1(AsChars(packet1), arraysize(packet1), false); - EXPECT_FALSE(framer_.ProcessPacket(encrypted1)); - EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); - ASSERT_TRUE(visitor_.header_.get()); - EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id); - EXPECT_EQ(kPathId, visitor_.header_->path_id); - EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number); - EXPECT_EQ(kPacketNumber, QuicFramerPeer::GetLastPacketNumber(&framer_)); - EXPECT_EQ(kPathId, QuicFramerPeer::GetLastPathId(&framer_)); - - // Packet 2 from default path. - // clang-format off - unsigned char packet2[] = { - // public flags (version) - 0x78, - // connection_id - 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, - // path_id - 0x00, - // packet number - 0xCC, 0x9A, 0x78, 0x56, 0x34, 0x12, - }; - // clang-format on - - QuicEncryptedPacket encrypted2(AsChars(packet2), arraysize(packet2), false); - EXPECT_FALSE(framer_.ProcessPacket(encrypted2)); - EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); - ASSERT_TRUE(visitor_.header_.get()); - EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id); - EXPECT_EQ(kDefaultPathId, visitor_.header_->path_id); - EXPECT_EQ(kPacketNumber + 16, visitor_.header_->packet_number); - EXPECT_EQ(kPacketNumber + 16, QuicFramerPeer::GetLastPacketNumber(&framer_)); - EXPECT_EQ(kDefaultPathId, QuicFramerPeer::GetLastPathId(&framer_)); - - // Packet 3 from path 0x42. - // clang-format off - unsigned char packet3[] = { - // public flags (version) - 0x78, - // connection_id - 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, - // path_id - 0x42, - // packet number - 0xBD, 0x9A, 0x78, 0x56, 0x34, 0x12, - }; - // clang-format on - - QuicEncryptedPacket encrypted3(AsChars(packet3), arraysize(packet3), false); - EXPECT_FALSE(framer_.ProcessPacket(encrypted3)); - EXPECT_EQ(QUIC_MISSING_PAYLOAD, framer_.error()); - ASSERT_TRUE(visitor_.header_.get()); - EXPECT_EQ(kConnectionId, visitor_.header_->public_header.connection_id); - EXPECT_EQ(kPathId, visitor_.header_->path_id); - EXPECT_EQ(kPacketNumber + 1, visitor_.header_->packet_number); - EXPECT_EQ(kPacketNumber + 1, QuicFramerPeer::GetLastPacketNumber(&framer_)); - EXPECT_EQ(kPathId, QuicFramerPeer::GetLastPathId(&framer_)); -} - -TEST_P(QuicFramerTest, ReceivedPacketOnClosedPath) { - // Packet 1 from path 0x42. - // clang-format off - unsigned char packet[] = { - // public flags (version) - 0x78, - // connection_id - 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, - // path_id - 0x42, - // packet number - 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, - // private flags - 0x00, - }; - // clang-format on - - framer_.OnPathClosed(kPathId); - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); - EXPECT_FALSE(framer_.ProcessPacket(encrypted)); - EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); - EXPECT_EQ(0u, QuicFramerPeer::GetLastPacketNumber(&framer_)); - EXPECT_EQ(kInvalidPathId, QuicFramerPeer::GetLastPathId(&framer_)); -} - TEST_P(QuicFramerTest, PacketHeaderWith4BytePacketNumber) { QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2); @@ -1005,8 +787,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith4BytePacketNumber) { // Now test framing boundaries. for (size_t i = 0; i < GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, !kIncludePathId, - !kIncludeDiversificationNonce, + !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER); ++i) { string expected_error; @@ -1050,8 +831,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith2BytePacketNumber) { // Now test framing boundaries. for (size_t i = 0; i < GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, !kIncludePathId, - !kIncludeDiversificationNonce, + !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_2BYTE_PACKET_NUMBER); ++i) { string expected_error; @@ -1095,8 +875,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith1BytePacketNumber) { // Now test framing boundaries. for (size_t i = 0; i < GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, !kIncludePathId, - !kIncludeDiversificationNonce, + !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_1BYTE_PACKET_NUMBER); ++i) { string expected_error; @@ -1261,17 +1040,17 @@ TEST_P(QuicFramerTest, PaddingFrame) { EXPECT_TRUE(framer_.ProcessPacket(encrypted)); EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); ASSERT_TRUE(visitor_.header_.get()); - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, + EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludeDiversificationNonce)); ASSERT_EQ(0u, visitor_.stream_frames_.size()); EXPECT_EQ(0u, visitor_.ack_frames_.size()); // A packet with no frames is not acceptable. CheckProcessingFails( - packet, GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, !kIncludePathId, - !kIncludeDiversificationNonce, - PACKET_6BYTE_PACKET_NUMBER), + packet, + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, + !kIncludeVersion, !kIncludeDiversificationNonce, + PACKET_6BYTE_PACKET_NUMBER), "Packet has no frames.", QUIC_MISSING_PAYLOAD); } @@ -1308,7 +1087,7 @@ TEST_P(QuicFramerTest, StreamFrame) { EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); ASSERT_TRUE(visitor_.header_.get()); - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, + EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludeDiversificationNonce)); ASSERT_EQ(1u, visitor_.stream_frames_.size()); @@ -1394,7 +1173,7 @@ TEST_P(QuicFramerTest, StreamFrame3ByteStreamId) { EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); ASSERT_TRUE(visitor_.header_.get()); - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, + EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludeDiversificationNonce)); ASSERT_EQ(1u, visitor_.stream_frames_.size()); @@ -1443,7 +1222,7 @@ TEST_P(QuicFramerTest, StreamFrame2ByteStreamId) { EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); ASSERT_TRUE(visitor_.header_.get()); - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, + EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludeDiversificationNonce)); ASSERT_EQ(1u, visitor_.stream_frames_.size()); @@ -1492,7 +1271,7 @@ TEST_P(QuicFramerTest, StreamFrame1ByteStreamId) { EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); ASSERT_TRUE(visitor_.header_.get()); - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, + EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludeDiversificationNonce)); ASSERT_EQ(1u, visitor_.stream_frames_.size()); @@ -1545,7 +1324,7 @@ TEST_P(QuicFramerTest, StreamFrameWithVersion) { ASSERT_TRUE(visitor_.header_.get()); EXPECT_TRUE(visitor_.header_->public_header.version_flag); EXPECT_EQ(GetParam(), visitor_.header_->public_header.versions[0]); - EXPECT_TRUE(CheckDecryption(encrypted, kIncludeVersion, !kIncludePathId, + EXPECT_TRUE(CheckDecryption(encrypted, kIncludeVersion, !kIncludeDiversificationNonce)); ASSERT_EQ(1u, visitor_.stream_frames_.size()); @@ -1594,7 +1373,7 @@ TEST_P(QuicFramerTest, RejectPacket) { EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); ASSERT_TRUE(visitor_.header_.get()); - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, + EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludeDiversificationNonce)); ASSERT_EQ(0u, visitor_.stream_frames_.size()); @@ -1651,7 +1430,7 @@ TEST_P(QuicFramerTest, AckFrameOneAckBlock) { EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); ASSERT_TRUE(visitor_.header_.get()); - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, + EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludeDiversificationNonce)); EXPECT_EQ(0u, visitor_.stream_frames_.size()); @@ -1684,8 +1463,7 @@ TEST_P(QuicFramerTest, AckFrameOneAckBlock) { CheckProcessingFails( packet, i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, !kIncludePathId, - !kIncludeDiversificationNonce, + !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER), expected_error, QUIC_INVALID_ACK_DATA); } @@ -1746,7 +1524,7 @@ TEST_P(QuicFramerTest, AckFrameTwoTimeStampsMultipleAckBlocks) { EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); ASSERT_TRUE(visitor_.header_.get()); - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, + EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludeDiversificationNonce)); EXPECT_EQ(0u, visitor_.stream_frames_.size()); @@ -1830,8 +1608,7 @@ TEST_P(QuicFramerTest, AckFrameTwoTimeStampsMultipleAckBlocks) { CheckProcessingFails( packet, i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, !kIncludePathId, - !kIncludeDiversificationNonce, + !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER), expected_error, QUIC_INVALID_ACK_DATA); } @@ -1861,7 +1638,7 @@ TEST_P(QuicFramerTest, NewStopWaitingFrame) { EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); ASSERT_TRUE(visitor_.header_.get()); - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, + EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludeDiversificationNonce)); EXPECT_EQ(0u, visitor_.stream_frames_.size()); @@ -1876,8 +1653,7 @@ TEST_P(QuicFramerTest, NewStopWaitingFrame) { CheckProcessingFails( packet, i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, !kIncludePathId, - !kIncludeDiversificationNonce, + !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER), expected_error, QUIC_INVALID_STOP_WAITING_DATA); } @@ -1914,7 +1690,7 @@ TEST_P(QuicFramerTest, RstStreamFrameQuic) { EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); ASSERT_TRUE(visitor_.header_.get()); - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, + EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludeDiversificationNonce)); EXPECT_EQ(kStreamId, visitor_.rst_stream_frame_.stream_id); @@ -1937,8 +1713,7 @@ TEST_P(QuicFramerTest, RstStreamFrameQuic) { CheckProcessingFails( packet, i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, !kIncludePathId, - !kIncludeDiversificationNonce, + !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER), expected_error, QUIC_INVALID_RST_STREAM_DATA); } @@ -1976,7 +1751,7 @@ TEST_P(QuicFramerTest, ConnectionCloseFrame) { EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); ASSERT_TRUE(visitor_.header_.get()); - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, + EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludeDiversificationNonce)); EXPECT_EQ(0u, visitor_.stream_frames_.size()); @@ -1998,8 +1773,7 @@ TEST_P(QuicFramerTest, ConnectionCloseFrame) { CheckProcessingFails( packet, i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, !kIncludePathId, - !kIncludeDiversificationNonce, + !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER), expected_error, QUIC_INVALID_CONNECTION_CLOSE_DATA); } @@ -2038,7 +1812,7 @@ TEST_P(QuicFramerTest, GoAwayFrame) { EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); ASSERT_TRUE(visitor_.header_.get()); - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, + EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludeDiversificationNonce)); EXPECT_EQ(kStreamId, visitor_.goaway_frame_.last_good_stream_id); @@ -2061,8 +1835,7 @@ TEST_P(QuicFramerTest, GoAwayFrame) { CheckProcessingFails( packet, i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, !kIncludePathId, - !kIncludeDiversificationNonce, + !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER), expected_error, QUIC_INVALID_GOAWAY_DATA); } @@ -2095,7 +1868,7 @@ TEST_P(QuicFramerTest, WindowUpdateFrame) { EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); ASSERT_TRUE(visitor_.header_.get()); - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, + EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludeDiversificationNonce)); EXPECT_EQ(kStreamId, visitor_.window_update_frame_.stream_id); @@ -2113,8 +1886,7 @@ TEST_P(QuicFramerTest, WindowUpdateFrame) { CheckProcessingFails( packet, i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, !kIncludePathId, - !kIncludeDiversificationNonce, + !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER), expected_error, QUIC_INVALID_WINDOW_UPDATE_DATA); } @@ -2144,7 +1916,7 @@ TEST_P(QuicFramerTest, BlockedFrame) { EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); ASSERT_TRUE(visitor_.header_.get()); - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, + EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludeDiversificationNonce)); EXPECT_EQ(kStreamId, visitor_.blocked_frame_.stream_id); @@ -2156,8 +1928,7 @@ TEST_P(QuicFramerTest, BlockedFrame) { CheckProcessingFails( packet, i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, !kIncludePathId, - !kIncludeDiversificationNonce, + !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER), expected_error, QUIC_INVALID_BLOCKED_DATA); } @@ -2185,7 +1956,7 @@ TEST_P(QuicFramerTest, PingFrame) { EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); ASSERT_TRUE(visitor_.header_.get()); - EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludePathId, + EXPECT_TRUE(CheckDecryption(encrypted, !kIncludeVersion, !kIncludeDiversificationNonce)); EXPECT_EQ(1u, visitor_.ping_frames_.size()); @@ -2193,50 +1964,6 @@ TEST_P(QuicFramerTest, PingFrame) { // No need to check the PING frame boundaries because it has no payload. } -TEST_P(QuicFramerTest, PathCloseFrame) { - // clang-format off - unsigned char packet[] = { - // public flags (version) - 0x78, - // connection_id - 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, - // path_id - 0x00, - // packet number - 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, - - // frame type (path_close_frame) - 0x08, - // path id - 0x42, - }; - // clang-format on - - QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false); - EXPECT_TRUE(framer_.ProcessPacket(encrypted)); - - EXPECT_EQ(QUIC_NO_ERROR, framer_.error()); - ASSERT_TRUE(visitor_.header_.get()); - // TODO(fayang): CheckDecryption after cl/110553865 is landed. - EXPECT_EQ(kPathId, visitor_.path_close_frame_.path_id); - - // Now test framing boundaries. - for (size_t i = kQuicFrameTypeSize; i < QuicFramer::GetPathCloseFrameSize(); - ++i) { - string expected_error; - if (i < kQuicFrameTypeSize + kQuicPathIdSize) { - expected_error = "Unable to read path_id."; - } - CheckProcessingFails( - packet, - i + GetPacketHeaderSize(framer_.version(), PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, kIncludePathId, - !kIncludeDiversificationNonce, - PACKET_6BYTE_PACKET_NUMBER), - expected_error, QUIC_INVALID_PATH_CLOSE_DATA); - } -} - TEST_P(QuicFramerTest, PublicResetPacketV33) { // clang-format off unsigned char packet[] = { @@ -2576,8 +2303,7 @@ TEST_P(QuicFramerTest, BuildPaddingFramePacket) { uint64_t header_size = GetPacketHeaderSize( framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, - !kIncludePathId, !kIncludeDiversificationNonce, - PACKET_6BYTE_PACKET_NUMBER); + !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER); memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1); std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); @@ -2616,8 +2342,7 @@ TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) { uint64_t header_size = GetPacketHeaderSize( framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, - !kIncludePathId, !kIncludeDiversificationNonce, - PACKET_4BYTE_PACKET_NUMBER); + !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER); memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1); std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); @@ -2656,8 +2381,7 @@ TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) { uint64_t header_size = GetPacketHeaderSize( framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, - !kIncludePathId, !kIncludeDiversificationNonce, - PACKET_2BYTE_PACKET_NUMBER); + !kIncludeDiversificationNonce, PACKET_2BYTE_PACKET_NUMBER); memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1); std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); @@ -2696,8 +2420,7 @@ TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) { uint64_t header_size = GetPacketHeaderSize( framer_.version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion, - !kIncludePathId, !kIncludeDiversificationNonce, - PACKET_1BYTE_PACKET_NUMBER); + !kIncludeDiversificationNonce, PACKET_1BYTE_PACKET_NUMBER); memset(packet + header_size + 1, 0x00, kMaxPacketSize - header_size - 1); std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); @@ -2796,106 +2519,6 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) { arraysize(packet)); } -TEST_P(QuicFramerTest, BuildStreamFramePacketWithMultipathFlag) { - QuicPacketHeader header; - header.public_header.connection_id = kConnectionId; - header.public_header.multipath_flag = true; - header.public_header.reset_flag = false; - header.public_header.version_flag = false; - header.path_id = kPathId; - header.packet_number = kPacketNumber; - - QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset, - StringPiece("hello world!")); - QuicFrames frames = {QuicFrame(&stream_frame)}; - - // clang-format off - unsigned char packet[] = { - // public flags (8 byte connection_id) - 0x78, - // connection_id - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // path_id - 0x42, - // packet number - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - - // frame type (stream frame with fin and no length) - 0xDF, - // stream id - 0x04, 0x03, 0x02, 0x01, - // offset - 0x54, 0x76, 0x10, 0x32, - 0xDC, 0xFE, 0x98, 0xBA, - // data - 'h', 'e', 'l', 'l', - 'o', ' ', 'w', 'o', - 'r', 'l', 'd', '!', - }; - // clang-format on - - std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); - ASSERT_TRUE(data != nullptr); - - test::CompareCharArraysWithHexError("constructed packet", data->data(), - data->length(), AsChars(packet), - arraysize(packet)); -} - -TEST_P(QuicFramerTest, BuildStreamFramePacketWithBothVersionAndMultipathFlag) { - QuicPacketHeader header; - header.public_header.connection_id = kConnectionId; - header.public_header.multipath_flag = true; - header.public_header.reset_flag = false; - header.public_header.version_flag = true; - header.path_id = kPathId; - header.packet_number = kPacketNumber; - - QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset, - StringPiece("hello world!")); - QuicFrames frames = {QuicFrame(&stream_frame)}; - - // clang-format off - unsigned char packet[] = { - // public flags (8 byte connection_id) - static_cast<unsigned char>( - FLAGS_quic_reloadable_flag_quic_remove_v33_hacks2 ? 0x79 : 0x7D), - // connection_id - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // version tag - 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(), - // path_id - 0x42, - // packet number - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - - // frame type (stream frame with fin and no length) - 0xDF, - // stream id - 0x04, 0x03, 0x02, 0x01, - // offset - 0x54, 0x76, 0x10, 0x32, - 0xDC, 0xFE, 0x98, 0xBA, - // data - 'h', 'e', 'l', 'l', - 'o', ' ', 'w', 'o', - 'r', 'l', 'd', '!', - }; - // clang-format on - - QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT); - std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); - ASSERT_TRUE(data != nullptr); - - test::CompareCharArraysWithHexError("constructed packet", data->data(), - data->length(), AsChars(packet), - arraysize(packet)); -} - TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) { // clang-format off unsigned char packet[] = { @@ -3442,46 +3065,6 @@ TEST_P(QuicFramerTest, BuildPingPacket) { arraysize(packet)); } -TEST_P(QuicFramerTest, BuildPathClosePacket) { - QuicPacketHeader header; - header.public_header.connection_id = kConnectionId; - header.public_header.multipath_flag = true; - header.public_header.reset_flag = false; - header.public_header.version_flag = false; - header.path_id = kDefaultPathId; - header.packet_number = kPacketNumber; - - QuicPathCloseFrame path_close; - path_close.path_id = kPathId; - QuicFrames frames; - frames.push_back(QuicFrame(&path_close)); - - // clang-format off - unsigned char packet[] = { - // public flags (version) - 0x78, - // connection_id - 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, - // path_id - 0x00, - // packet number - 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12, - - // frame type (path_close_frame) - 0x08, - // path id - 0x42, - }; - // clang-format on - - std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames)); - ASSERT_TRUE(data != nullptr); - - test::CompareCharArraysWithHexError("constructed packet", data->data(), - data->length(), AsChars(packet), - arraysize(packet)); -} - // Test that the MTU discovery packet is serialized correctly as a PING packet. TEST_P(QuicFramerTest, BuildMtuDiscoveryPacket) { QuicPacketHeader header; @@ -3769,12 +3352,11 @@ TEST_P(QuicFramerTest, EncryptPacket) { std::unique_ptr<QuicPacket> raw(new QuicPacket( AsChars(packet), arraysize(packet), false, PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, !kIncludePathId, !kIncludeDiversificationNonce, + !kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER)); char buffer[kMaxPacketSize]; - size_t encrypted_length = - framer_.EncryptPayload(ENCRYPTION_NONE, kDefaultPathId, packet_number, - *raw, buffer, kMaxPacketSize); + size_t encrypted_length = framer_.EncryptPayload( + ENCRYPTION_NONE, packet_number, *raw, buffer, kMaxPacketSize); ASSERT_NE(0u, encrypted_length); EXPECT_TRUE(CheckEncryption(kDefaultPathId, packet_number, raw.get())); @@ -3805,87 +3387,14 @@ TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) { std::unique_ptr<QuicPacket> raw(new QuicPacket( AsChars(packet), arraysize(packet), false, PACKET_8BYTE_CONNECTION_ID, - kIncludeVersion, !kIncludePathId, !kIncludeDiversificationNonce, - PACKET_6BYTE_PACKET_NUMBER)); - char buffer[kMaxPacketSize]; - size_t encrypted_length = - framer_.EncryptPayload(ENCRYPTION_NONE, kDefaultPathId, packet_number, - *raw, buffer, kMaxPacketSize); - - ASSERT_NE(0u, encrypted_length); - EXPECT_TRUE(CheckEncryption(kDefaultPathId, packet_number, raw.get())); -} - -TEST_P(QuicFramerTest, EncryptPacketWithMultipathFlag) { - QuicPacketNumber packet_number = kPacketNumber; - // clang-format off - unsigned char packet[] = { - // public flags (version, 8 byte connection_id) - 0x78, - // connection_id - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // path_id - 0x42, - // packet number - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - - // redundancy - 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', - 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', - }; - // clang-format on - - std::unique_ptr<QuicPacket> raw(new QuicPacket( - AsChars(packet), arraysize(packet), false, PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, kIncludePathId, !kIncludeDiversificationNonce, - PACKET_6BYTE_PACKET_NUMBER)); - char buffer[kMaxPacketSize]; - size_t encrypted_length = framer_.EncryptPayload( - ENCRYPTION_NONE, kPathId, packet_number, *raw, buffer, kMaxPacketSize); - - ASSERT_NE(0u, encrypted_length); - EXPECT_TRUE(CheckEncryption(kPathId, packet_number, raw.get())); -} - -TEST_P(QuicFramerTest, EncryptPacketWithBothVersionFlagAndMultipathFlag) { - QuicPacketNumber packet_number = kPacketNumber; - // clang-format off - unsigned char packet[] = { - // public flags (version, 8 byte connection_id) - 0x79, - // connection_id - 0x10, 0x32, 0x54, 0x76, - 0x98, 0xBA, 0xDC, 0xFE, - // version tag - 'Q', '.', '1', '0', - // path_id - 0x42, - // packet number - 0xBC, 0x9A, 0x78, 0x56, - 0x34, 0x12, - - // redundancy - 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', - 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', - }; - // clang-format on - - std::unique_ptr<QuicPacket> raw(new QuicPacket( - AsChars(packet), arraysize(packet), false, PACKET_8BYTE_CONNECTION_ID, - kIncludeVersion, kIncludePathId, !kIncludeDiversificationNonce, + kIncludeVersion, !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER)); char buffer[kMaxPacketSize]; size_t encrypted_length = framer_.EncryptPayload( - ENCRYPTION_NONE, kPathId, packet_number, *raw, buffer, kMaxPacketSize); + ENCRYPTION_NONE, packet_number, *raw, buffer, kMaxPacketSize); ASSERT_NE(0u, encrypted_length); - EXPECT_TRUE(CheckEncryption(kPathId, packet_number, raw.get())); + EXPECT_TRUE(CheckEncryption(kDefaultPathId, packet_number, raw.get())); } TEST_P(QuicFramerTest, AckTruncationLargePacket) { @@ -3904,9 +3413,9 @@ TEST_P(QuicFramerTest, AckTruncationLargePacket) { std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames)); ASSERT_TRUE(raw_ack_packet != nullptr); char buffer[kMaxPacketSize]; - size_t encrypted_length = framer_.EncryptPayload( - ENCRYPTION_NONE, kDefaultPathId, header.packet_number, *raw_ack_packet, - buffer, kMaxPacketSize); + size_t encrypted_length = + framer_.EncryptPayload(ENCRYPTION_NONE, header.packet_number, + *raw_ack_packet, buffer, kMaxPacketSize); ASSERT_NE(0u, encrypted_length); // Now make sure we can turn our ack packet back into an ack frame. ASSERT_TRUE(framer_.ProcessPacket( @@ -3936,9 +3445,9 @@ TEST_P(QuicFramerTest, AckTruncationSmallPacket) { BuildDataPacket(header, frames, 500)); ASSERT_TRUE(raw_ack_packet != nullptr); char buffer[kMaxPacketSize]; - size_t encrypted_length = framer_.EncryptPayload( - ENCRYPTION_NONE, kDefaultPathId, header.packet_number, *raw_ack_packet, - buffer, kMaxPacketSize); + size_t encrypted_length = + framer_.EncryptPayload(ENCRYPTION_NONE, header.packet_number, + *raw_ack_packet, buffer, kMaxPacketSize); ASSERT_NE(0u, encrypted_length); // Now make sure we can turn our ack packet back into an ack frame. ASSERT_TRUE(framer_.ProcessPacket( @@ -3969,9 +3478,9 @@ TEST_P(QuicFramerTest, CleanTruncation) { ASSERT_TRUE(raw_ack_packet != nullptr); char buffer[kMaxPacketSize]; - size_t encrypted_length = framer_.EncryptPayload( - ENCRYPTION_NONE, kDefaultPathId, header.packet_number, *raw_ack_packet, - buffer, kMaxPacketSize); + size_t encrypted_length = + framer_.EncryptPayload(ENCRYPTION_NONE, header.packet_number, + *raw_ack_packet, buffer, kMaxPacketSize); ASSERT_NE(0u, encrypted_length); // Now make sure we can turn our ack packet back into an ack frame. @@ -4106,7 +3615,7 @@ TEST_P(QuicFramerTest, ConstructMisFramedEncryptedPacket) { QuicVersionVector versions; versions.push_back(framer_.version()); std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket( - 42, false, false, false, kDefaultPathId, kTestQuicStreamId, kTestString, + 42, false, false, kDefaultPathId, kTestQuicStreamId, kTestString, PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, &versions, Perspective::IS_CLIENT)); diff --git a/chromium/net/quic/core/quic_headers_stream_test.cc b/chromium/net/quic/core/quic_headers_stream_test.cc index d4fb9d5c2da..8e1c56495da 100644 --- a/chromium/net/quic/core/quic_headers_stream_test.cc +++ b/chromium/net/quic/core/quic_headers_stream_test.cc @@ -15,6 +15,7 @@ #include "net/quic/core/spdy_utils.h" #include "net/quic/platform/api/quic_bug_tracker.h" #include "net/quic/platform/api/quic_logging.h" +#include "net/quic/platform/api/quic_ptr_util.h" #include "net/quic/platform/api/quic_str_cat.h" #include "net/quic/test_tools/quic_connection_peer.h" #include "net/quic/test_tools/quic_spdy_session_peer.h" @@ -38,10 +39,6 @@ using testing::Return; using testing::StrictMock; using testing::WithArgs; -// TODO(bnc): Merge these correctly. -bool FLAGS_use_http2_frame_decoder_adapter; -bool FLAGS_spdy_framer_use_new_methods4; - namespace net { namespace test { @@ -77,7 +74,7 @@ class MockVisitor : public SpdyFramerVisitorInterface { const char* header_data, size_t len)); MOCK_METHOD2(OnRstStream, - void(SpdyStreamId stream_id, SpdyRstStreamStatus status)); + void(SpdyStreamId stream_id, SpdyErrorCode error_code)); MOCK_METHOD1(OnSettings, void(bool clear_persisted)); MOCK_METHOD2(OnSetting, void(SpdySettingsIds id, uint32_t value)); MOCK_METHOD0(OnSettingsAck, void()); @@ -85,7 +82,7 @@ class MockVisitor : public SpdyFramerVisitorInterface { MOCK_METHOD2(OnPing, void(SpdyPingId unique_id, bool is_ack)); MOCK_METHOD2(OnGoAway, void(SpdyStreamId last_accepted_stream_id, - SpdyGoAwayStatus status)); + SpdyErrorCode error_code)); MOCK_METHOD7(OnHeaders, void(SpdyStreamId stream_id, bool has_priority, @@ -112,7 +109,8 @@ class MockVisitor : public SpdyFramerVisitorInterface { SpdyStreamId parent_stream_id, int weight, bool exclusive)); - MOCK_METHOD2(OnUnknownFrame, bool(SpdyStreamId stream_id, int frame_type)); + MOCK_METHOD2(OnUnknownFrame, + bool(SpdyStreamId stream_id, uint8_t frame_type)); }; class ForceHolAckListener : public QuicAckListenerInterface { @@ -178,18 +176,17 @@ struct TestParams { switch (http2_decoder) { case HTTP2_DECODER_SPDY: FLAGS_use_nested_spdy_framer_decoder = false; - FLAGS_use_http2_frame_decoder_adapter = false; + FLAGS_chromium_http2_flag_spdy_use_http2_frame_decoder_adapter = false; break; case HTTP2_DECODER_NESTED_SPDY: FLAGS_use_nested_spdy_framer_decoder = true; - FLAGS_use_http2_frame_decoder_adapter = false; + FLAGS_chromium_http2_flag_spdy_use_http2_frame_decoder_adapter = false; break; case HTTP2_DECODER_NEW: FLAGS_use_nested_spdy_framer_decoder = false; - FLAGS_use_http2_frame_decoder_adapter = true; + FLAGS_chromium_http2_flag_spdy_use_http2_frame_decoder_adapter = true; // Http2FrameDecoderAdapter needs the new header methods, else // --use_http2_frame_decoder_adapter=true will be ignored. - FLAGS_spdy_framer_use_new_methods4 = true; break; } switch (hpack_decoder) { @@ -233,8 +230,6 @@ class QuicHeadersStreamTest : public ::testing::TestWithParam<TestParamsTuple> { session_(connection_), headers_stream_(QuicSpdySessionPeer::GetHeadersStream(&session_)), body_("hello world"), - hpack_encoder_visitor_(new StrictMock<MockQuicHpackDebugVisitor>), - hpack_decoder_visitor_(new StrictMock<MockQuicHpackDebugVisitor>), stream_frame_(kHeadersStreamId, /*fin=*/false, /*offset=*/0, ""), next_promised_stream_id_(2) { headers_[":version"] = "HTTP/1.1"; @@ -358,7 +353,7 @@ class QuicHeadersStreamTest : public ::testing::TestWithParam<TestParamsTuple> { } framer_->ProcessInput(saved_data_.data(), saved_data_.length()); EXPECT_FALSE(framer_->HasError()) - << SpdyFramer::ErrorCodeToString(framer_->error_code()); + << SpdyFramer::SpdyFramerErrorToString(framer_->spdy_framer_error()); CheckHeaders(); saved_data_.clear(); @@ -403,8 +398,6 @@ class QuicHeadersStreamTest : public ::testing::TestWithParam<TestParamsTuple> { string saved_payloads_; std::unique_ptr<SpdyFramer> framer_; StrictMock<MockVisitor> visitor_; - std::unique_ptr<StrictMock<MockQuicHpackDebugVisitor>> hpack_encoder_visitor_; - std::unique_ptr<StrictMock<MockQuicHpackDebugVisitor>> hpack_decoder_visitor_; QuicStreamFrame stream_frame_; QuicStreamId next_promised_stream_id_; }; @@ -463,7 +456,7 @@ TEST_P(QuicHeadersStreamTest, WritePushPromises) { EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id, true)).Times(1); framer_->ProcessInput(saved_data_.data(), saved_data_.length()); EXPECT_FALSE(framer_->HasError()) - << SpdyFramer::ErrorCodeToString(framer_->error_code()); + << SpdyFramer::SpdyFramerErrorToString(framer_->spdy_framer_error()); CheckHeaders(); saved_data_.clear(); } else { @@ -723,7 +716,7 @@ TEST_P(QuicHeadersStreamTest, ProcessSpdyDataFrameEmptyWithFin) { } TEST_P(QuicHeadersStreamTest, ProcessSpdyRstStreamFrame) { - SpdyRstStreamIR data(2, RST_STREAM_PROTOCOL_ERROR); + SpdyRstStreamIR data(2, ERROR_CODE_PROTOCOL_ERROR); SpdySerializedFrame frame(framer_->SerializeFrame(data)); EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, @@ -824,7 +817,7 @@ TEST_P(QuicHeadersStreamTest, ProcessSpdyPingFrame) { } TEST_P(QuicHeadersStreamTest, ProcessSpdyGoAwayFrame) { - SpdyGoAwayIR data(1, GOAWAY_PROTOCOL_ERROR, "go away"); + SpdyGoAwayIR data(1, ERROR_CODE_PROTOCOL_ERROR, "go away"); SpdySerializedFrame frame(framer_->SerializeFrame(data)); EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, "SPDY GOAWAY frame received.", _)) @@ -854,20 +847,8 @@ TEST_P(QuicHeadersStreamTest, NoConnectionLevelFlowControl) { } TEST_P(QuicHeadersStreamTest, HpackDecoderDebugVisitor) { - if (test_params_.hpack_decoder == HPACK_DECODER3) { - return; - } - - StrictMock<MockQuicHpackDebugVisitor>* hpack_decoder_visitor = - hpack_decoder_visitor_.get(); - QuicSpdySessionPeer::SetHpackDecoderDebugVisitor( - &session_, std::move(hpack_decoder_visitor_)); - - // Create some headers we expect to generate entries in HPACK's - // dynamic table, in addition to content-length. - headers_["key0"] = string(1 << 1, '.'); - headers_["key1"] = string(1 << 2, '.'); - headers_["key2"] = string(1 << 3, '.'); + auto hpack_decoder_visitor = + QuicMakeUnique<StrictMock<MockQuicHpackDebugVisitor>>(); { InSequence seq; // Number of indexed representations generated in headers below. @@ -877,6 +858,14 @@ TEST_P(QuicHeadersStreamTest, HpackDecoderDebugVisitor) { .Times(4); } } + QuicSpdySessionPeer::SetHpackDecoderDebugVisitor( + &session_, std::move(hpack_decoder_visitor)); + + // Create some headers we expect to generate entries in HPACK's + // dynamic table, in addition to content-length. + headers_["key0"] = string(1 << 1, '.'); + headers_["key1"] = string(1 << 2, '.'); + headers_["key2"] = string(1 << 3, '.'); for (QuicStreamId stream_id = kClientDataStreamId1; stream_id < kClientDataStreamId3; stream_id += 2) { for (bool fin : {false, true}) { @@ -910,11 +899,8 @@ TEST_P(QuicHeadersStreamTest, HpackDecoderDebugVisitor) { } TEST_P(QuicHeadersStreamTest, HpackEncoderDebugVisitor) { - StrictMock<MockQuicHpackDebugVisitor>* hpack_encoder_visitor = - hpack_encoder_visitor_.get(); - QuicSpdySessionPeer::SetHpackEncoderDebugVisitor( - &session_, std::move(hpack_encoder_visitor_)); - + auto hpack_encoder_visitor = + QuicMakeUnique<StrictMock<MockQuicHpackDebugVisitor>>(); if (perspective() == Perspective::IS_SERVER) { InSequence seq; for (int i = 1; i < 4; i++) { @@ -928,6 +914,9 @@ TEST_P(QuicHeadersStreamTest, HpackEncoderDebugVisitor) { OnUseEntry(QuicTime::Delta::FromMilliseconds(i))); } } + QuicSpdySessionPeer::SetHpackEncoderDebugVisitor( + &session_, std::move(hpack_encoder_visitor)); + for (QuicStreamId stream_id = kClientDataStreamId1; stream_id < kClientDataStreamId3; stream_id += 2) { for (bool fin : {false, true}) { @@ -953,8 +942,7 @@ TEST_P(QuicHeadersStreamTest, WritevStreamData) { // This test will issue a write that will require fragmenting into // multiple HTTP/2 DATA frames. const int kMinDataFrames = 4; - const size_t data_len = - kSpdyInitialFrameSizeLimit * kMinDataFrames + 1024; + const size_t data_len = kSpdyInitialFrameSizeLimit * kMinDataFrames + 1024; // Set headers stream send window large enough for data written below. headers_stream_->flow_controller()->UpdateSendWindowOffset(data_len * 2 * 4); string data(data_len, 'a'); diff --git a/chromium/net/quic/core/quic_iovector.h b/chromium/net/quic/core/quic_iovector.h index 6e893e97e3b..b163fee57d6 100644 --- a/chromium/net/quic/core/quic_iovector.h +++ b/chromium/net/quic/core/quic_iovector.h @@ -5,7 +5,7 @@ #ifndef NET_QUIC_CORE_QUIC_IOVECTOR_H_ #define NET_QUIC_CORE_QUIC_IOVECTOR_H_ -#include <stddef.h> +#include <cstddef> #include "net/base/iovec.h" #include "net/quic/platform/api/quic_export.h" diff --git a/chromium/net/quic/core/quic_multipath_received_packet_manager.cc b/chromium/net/quic/core/quic_multipath_received_packet_manager.cc index 3bf497bf810..c7931cf0baa 100644 --- a/chromium/net/quic/core/quic_multipath_received_packet_manager.cc +++ b/chromium/net/quic/core/quic_multipath_received_packet_manager.cc @@ -85,7 +85,7 @@ void QuicMultipathReceivedPacketManager::UpdatePacketInformationSentByPeer( QuicReceivedPacketManager* manager = path_managers_[stop_waiting.path_id].get(); if (manager != nullptr) { - manager->UpdatePacketInformationSentByPeer(stop_waiting); + manager->DontWaitForPacketsBefore(stop_waiting.least_unacked); } } } diff --git a/chromium/net/quic/core/quic_multipath_received_packet_manager_test.cc b/chromium/net/quic/core/quic_multipath_received_packet_manager_test.cc index d8e948d5de3..afedaa39c47 100644 --- a/chromium/net/quic/core/quic_multipath_received_packet_manager_test.cc +++ b/chromium/net/quic/core/quic_multipath_received_packet_manager_test.cc @@ -124,23 +124,6 @@ TEST_F(QuicMultipathReceivedPacketManagerTest, IsAwaitingPacket) { "Check whether a packet is awaited on a non-existent path"); } -TEST_F(QuicMultipathReceivedPacketManagerTest, - UpdatePacketInformationSentByPeer) { - std::vector<QuicStopWaitingFrame> stop_waitings; - QuicStopWaitingFrame stop_waiting_0; - QuicStopWaitingFrame stop_waiting_1; - QuicStopWaitingFrame stop_waiting_2; - stop_waiting_0.path_id = kDefaultPathId; - stop_waiting_1.path_id = kPathId1; - stop_waiting_2.path_id = kPathId2; - stop_waitings.push_back(stop_waiting_0); - stop_waitings.push_back(stop_waiting_1); - stop_waitings.push_back(stop_waiting_2); - EXPECT_CALL(*manager_0_, UpdatePacketInformationSentByPeer(_)).Times(1); - EXPECT_CALL(*manager_1_, UpdatePacketInformationSentByPeer(_)).Times(1); - multipath_manager_.UpdatePacketInformationSentByPeer(stop_waitings); -} - TEST_F(QuicMultipathReceivedPacketManagerTest, HasNewMissingPackets) { EXPECT_CALL(*manager_0_, HasNewMissingPackets()).WillOnce(Return(true)); EXPECT_CALL(*manager_1_, HasNewMissingPackets()).WillOnce(Return(false)); diff --git a/chromium/net/quic/core/quic_one_block_arena.h b/chromium/net/quic/core/quic_one_block_arena.h index 022918b4fe8..bf9cef44de1 100644 --- a/chromium/net/quic/core/quic_one_block_arena.h +++ b/chromium/net/quic/core/quic_one_block_arena.h @@ -12,11 +12,11 @@ #include <cstdint> +#include "base/macros.h" #include "net/quic/core/quic_arena_scoped_ptr.h" #include "net/quic/core/quic_types.h" #include "net/quic/platform/api/quic_bug_tracker.h" - -#define PREDICT_FALSE(x) x +#include "net/quic/platform/api/quic_logging.h" namespace net { @@ -60,7 +60,7 @@ QuicArenaScopedPtr<T> QuicOneBlockArena<ArenaSize>::New(Args&&... args) { << "Object is too large for the arena."; static_assert(QUIC_ALIGN_OF(T) > 1, "Objects added to the arena must be at least 2B aligned."); - if (PREDICT_FALSE(offset_ > ArenaSize - AlignedSize<T>())) { + if (QUIC_PREDICT_FALSE(offset_ > ArenaSize - AlignedSize<T>())) { QUIC_BUG << "Ran out of space in QuicOneBlockArena at " << this << ", max size was " << ArenaSize << ", failing request was " << AlignedSize<T>() << ", end of arena was " << offset_; diff --git a/chromium/net/quic/core/quic_one_block_arena_test.cc b/chromium/net/quic/core/quic_one_block_arena_test.cc index 2f060252e30..2a81c219b96 100644 --- a/chromium/net/quic/core/quic_one_block_arena_test.cc +++ b/chromium/net/quic/core/quic_one_block_arena_test.cc @@ -6,7 +6,7 @@ #include <cstdint> -#include "net/quic/core/interval_set.h" +#include "net/quic/platform/api/quic_containers.h" #include "net/quic/test_tools/quic_test_utils.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -41,7 +41,7 @@ TEST(QuicOneBlockArenaTest, Exhaust) { TEST(QuicOneBlockArenaTest, NoOverlaps) { QuicOneBlockArena<1024> arena; std::vector<QuicArenaScopedPtr<TestObject>> objects; - IntervalSet<uintptr_t> used; + QuicIntervalSet<uintptr_t> used; for (size_t i = 0; i < 1024 / kMaxAlign; ++i) { QuicArenaScopedPtr<TestObject> ptr = arena.New<TestObject>(); EXPECT_TRUE(ptr.is_from_arena()); diff --git a/chromium/net/quic/core/quic_packet_creator.cc b/chromium/net/quic/core/quic_packet_creator.cc index b0c47fd409b..5c4f4f823ac 100644 --- a/chromium/net/quic/core/quic_packet_creator.cc +++ b/chromium/net/quic/core/quic_packet_creator.cc @@ -33,7 +33,6 @@ QuicPacketCreator::QuicPacketCreator(QuicConnectionId connection_id, framer_(framer), buffer_allocator_(buffer_allocator), send_version_in_packet_(framer->perspective() == Perspective::IS_CLIENT), - send_path_id_in_packet_(false), next_packet_number_length_(PACKET_1BYTE_PACKET_NUMBER), have_diversification_nonce_(false), max_packet_length_(0), @@ -167,12 +166,11 @@ size_t QuicPacketCreator::StreamFramePacketOverhead( QuicVersion version, QuicConnectionIdLength connection_id_length, bool include_version, - bool include_path_id, bool include_diversification_nonce, QuicPacketNumberLength packet_number_length, QuicStreamOffset offset) { return GetPacketHeaderSize(version, connection_id_length, include_version, - include_path_id, include_diversification_nonce, + include_diversification_nonce, packet_number_length) + // Assumes this is a stream with a single lone packet. QuicFramer::GetMinStreamFrameSize(1u, offset, true); @@ -184,11 +182,11 @@ void QuicPacketCreator::CreateStreamFrame(QuicStreamId id, QuicStreamOffset offset, bool fin, QuicFrame* frame) { - DCHECK_GT(max_packet_length_, - StreamFramePacketOverhead(framer_->version(), connection_id_length_, - kIncludeVersion, kIncludePathId, - IncludeNonceInPublicHeader(), - PACKET_6BYTE_PACKET_NUMBER, offset)); + DCHECK_GT( + max_packet_length_, + StreamFramePacketOverhead(framer_->version(), connection_id_length_, + kIncludeVersion, IncludeNonceInPublicHeader(), + PACKET_6BYTE_PACKET_NUMBER, offset)); QUIC_BUG_IF(!HasRoomForStreamFrame(id, offset)) << "No room for Stream frame, BytesFree: " << BytesFree() @@ -337,7 +335,6 @@ void QuicPacketCreator::ClearPacket() { packet_.has_stop_waiting = false; packet_.has_crypto_handshake = NOT_HANDSHAKE; packet_.num_padding_bytes = 0; - packet_.original_path_id = kInvalidPathId; packet_.original_packet_number = 0; packet_.transmission_type = NOT_RETRANSMISSION; packet_.encrypted_buffer = nullptr; @@ -446,8 +443,7 @@ size_t QuicPacketCreator::PacketSize() { } packet_size_ = GetPacketHeaderSize( framer_->version(), connection_id_length_, send_version_in_packet_, - send_path_id_in_packet_, IncludeNonceInPublicHeader(), - packet_.packet_number_length); + IncludeNonceInPublicHeader(), packet_.packet_number_length); return packet_size_; } @@ -538,7 +534,7 @@ SerializedPacket QuicPacketCreator::NoPacket() { void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) { header->public_header.connection_id = connection_id_; header->public_header.connection_id_length = connection_id_length_; - header->public_header.multipath_flag = send_path_id_in_packet_; + header->public_header.multipath_flag = false; header->public_header.reset_flag = false; header->public_header.version_flag = send_version_in_packet_; if (IncludeNonceInPublicHeader()) { @@ -630,32 +626,6 @@ void QuicPacketCreator::MaybeAddPadding() { DCHECK(success); } -void QuicPacketCreator::SetCurrentPath( - QuicPathId path_id, - QuicPacketNumber least_packet_awaited_by_peer, - QuicPacketCount max_packets_in_flight) { - if (packet_.path_id == path_id) { - return; - } - - if (HasPendingFrames()) { - QUIC_BUG << "Unable to change paths when a packet is under construction."; - return; - } - // Save current packet number and load switching path's packet number. - multipath_packet_number_[packet_.path_id] = packet_.packet_number; - std::unordered_map<QuicPathId, QuicPacketNumber>::iterator it = - multipath_packet_number_.find(path_id); - // If path_id is not in the map, it's a new path. Set packet_number to 0. - packet_.packet_number = it == multipath_packet_number_.end() ? 0 : it->second; - packet_.path_id = path_id; - DCHECK(packet_.path_id != kInvalidPathId); - // Send path in packet if current path is not the default path. - send_path_id_in_packet_ = packet_.path_id != kDefaultPathId ? true : false; - // Switching path needs to update packet number length. - UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight); -} - bool QuicPacketCreator::IncludeNonceInPublicHeader() { return have_diversification_nonce_ && packet_.encryption_level == ENCRYPTION_INITIAL; diff --git a/chromium/net/quic/core/quic_packet_creator.h b/chromium/net/quic/core/quic_packet_creator.h index 232b31d79f9..f7bce4e830b 100644 --- a/chromium/net/quic/core/quic_packet_creator.h +++ b/chromium/net/quic/core/quic_packet_creator.h @@ -82,7 +82,6 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator { QuicVersion version, QuicConnectionIdLength connection_id_length, bool include_version, - bool include_path_id, bool include_diversification_nonce, QuicPacketNumberLength packet_number_length, QuicStreamOffset offset); @@ -206,14 +205,6 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator { // Sets the maximum packet length. void SetMaxPacketLength(QuicByteCount length); - // Sets the path on which subsequent packets will be created. It is the - // caller's responsibility to guarantee no packet is under construction before - // calling this function. If |path_id| is different from current_path_, - // next_packet_number_length_ is recalculated. - void SetCurrentPath(QuicPathId path_id, - QuicPacketNumber least_packet_awaited_by_peer, - QuicPacketCount max_packets_in_flight); - void set_debug_delegate(DebugDelegate* debug_delegate) { debug_delegate_ = debug_delegate; } @@ -281,8 +272,6 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator { // Controls whether version should be included while serializing the packet. bool send_version_in_packet_; - // Controls whether path id should be included while serializing the packet. - bool send_path_id_in_packet_; // Staging variable to hold next packet number length. When sequence // number length is to be changed, this variable holds the new length until // a packet boundary, when the creator's packet_number_length_ can be changed diff --git a/chromium/net/quic/core/quic_packet_creator_test.cc b/chromium/net/quic/core/quic_packet_creator_test.cc index 18159788573..69439d3db1e 100644 --- a/chromium/net/quic/core/quic_packet_creator_test.cc +++ b/chromium/net/quic/core/quic_packet_creator_test.cc @@ -10,7 +10,6 @@ #include <string> #include "base/macros.h" -#include "base/stl_util.h" #include "net/quic/core/crypto/null_encrypter.h" #include "net/quic/core/crypto/quic_decrypter.h" #include "net/quic/core/crypto/quic_encrypter.h" @@ -176,7 +175,7 @@ class QuicPacketCreatorTest : public ::testing::TestWithParam<TestParams> { size_t GetPacketHeaderOverhead(QuicVersion version) { return GetPacketHeaderSize( version, creator_.connection_id_length(), kIncludeVersion, - !kIncludePathId, !kIncludeDiversificationNonce, + !kIncludeDiversificationNonce, QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); } @@ -721,7 +720,6 @@ TEST_P(QuicPacketCreatorTest, ConsumeDataLargerThanOneStreamFrame) { creator_.SetMaxPacketLength(GetPacketLengthForOneStream( client_framer_.version(), QuicPacketCreatorPeer::SendVersionInPacket(&creator_), - QuicPacketCreatorPeer::SendPathIdInPacket(&creator_), !kIncludeDiversificationNonce, creator_.connection_id_length(), PACKET_1BYTE_PACKET_NUMBER, &payload_length)); QuicFrame frame; @@ -751,7 +749,6 @@ TEST_P(QuicPacketCreatorTest, AddFrameAndFlush) { GetPacketHeaderSize( client_framer_.version(), creator_.connection_id_length(), QuicPacketCreatorPeer::SendVersionInPacket(&creator_), - QuicPacketCreatorPeer::SendPathIdInPacket(&creator_), !kIncludeDiversificationNonce, PACKET_1BYTE_PACKET_NUMBER), creator_.BytesFree()); @@ -793,8 +790,7 @@ TEST_P(QuicPacketCreatorTest, AddFrameAndFlush) { GetPacketHeaderSize( client_framer_.version(), creator_.connection_id_length(), QuicPacketCreatorPeer::SendVersionInPacket(&creator_), - /*include_path_id=*/false, !kIncludeDiversificationNonce, - PACKET_1BYTE_PACKET_NUMBER), + !kIncludeDiversificationNonce, PACKET_1BYTE_PACKET_NUMBER), creator_.BytesFree()); } @@ -824,109 +820,6 @@ TEST_P(QuicPacketCreatorTest, SerializeAndSendStreamFrame) { EXPECT_FALSE(creator_.HasPendingFrames()); } -TEST_P(QuicPacketCreatorTest, SetCurrentPath) { - // Current path is the default path. - EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(&creator_)); - EXPECT_EQ(0u, creator_.packet_number()); - EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, - QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); - // Add a stream frame to the creator. - QuicFrame frame; - QuicIOVector io_vector(MakeIOVectorFromStringPiece("test")); - ASSERT_TRUE(creator_.ConsumeData(kCryptoStreamId, io_vector, 0u, 0u, false, - false, &frame)); - ASSERT_TRUE(frame.stream_frame); - size_t consumed = frame.stream_frame->data_length; - EXPECT_EQ(4u, consumed); - EXPECT_TRUE(creator_.HasPendingFrames()); - EXPECT_EQ(0u, creator_.packet_number()); - - // Change current path. - QuicPathId kPathId1 = 1; - EXPECT_QUIC_BUG(creator_.SetCurrentPath(kPathId1, 1, 0), - "Unable to change paths when a packet is under construction"); - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .Times(1) - .WillRepeatedly( - Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacketForTests)); - creator_.Flush(); - EXPECT_FALSE(creator_.HasPendingFrames()); - creator_.SetCurrentPath(kPathId1, 1, 0); - EXPECT_EQ(kPathId1, QuicPacketCreatorPeer::GetCurrentPath(&creator_)); - EXPECT_FALSE(creator_.HasPendingFrames()); - EXPECT_EQ(0u, creator_.packet_number()); - EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, - QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); - - // Change current path back. - creator_.SetCurrentPath(kDefaultPathId, 2, 1); - EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(&creator_)); - EXPECT_EQ(1u, creator_.packet_number()); - EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, - QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); - // Add a stream frame to the creator. - ASSERT_TRUE(creator_.ConsumeData(kCryptoStreamId, io_vector, 0u, 0u, false, - false, &frame)); - ASSERT_TRUE(frame.stream_frame); - consumed = frame.stream_frame->data_length; - EXPECT_EQ(4u, consumed); - EXPECT_TRUE(creator_.HasPendingFrames()); - - // Does not change current path. - creator_.SetCurrentPath(kDefaultPathId, 2, 0); - EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(&creator_)); - EXPECT_TRUE(creator_.HasPendingFrames()); - EXPECT_EQ(1u, creator_.packet_number()); - EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, - QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); -} - -TEST_P(QuicPacketCreatorTest, SerializePacketOnDifferentPath) { - // Current path is the default path. - EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(&creator_)); - EXPECT_EQ(0u, creator_.packet_number()); - // Add a stream frame to the creator and flush the packet. - QuicFrame frame; - QuicIOVector io_vector(MakeIOVectorFromStringPiece("test")); - ASSERT_TRUE(creator_.ConsumeData(kCryptoStreamId, io_vector, 0u, 0u, false, - false, &frame)); - ASSERT_TRUE(frame.stream_frame); - size_t consumed = frame.stream_frame->data_length; - EXPECT_EQ(4u, consumed); - EXPECT_TRUE(creator_.HasPendingFrames()); - EXPECT_EQ(0u, creator_.packet_number()); - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillRepeatedly( - Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket)); - creator_.Flush(); - EXPECT_FALSE(creator_.HasPendingFrames()); - EXPECT_EQ(1u, creator_.packet_number()); - // Verify serialized data packet's path id. - EXPECT_EQ(kDefaultPathId, serialized_packet_.path_id); - DeleteSerializedPacket(); - - // Change to path 1. - QuicPathId kPathId1 = 1; - creator_.SetCurrentPath(kPathId1, 1, 0); - EXPECT_EQ(kPathId1, QuicPacketCreatorPeer::GetCurrentPath(&creator_)); - EXPECT_FALSE(creator_.HasPendingFrames()); - EXPECT_EQ(0u, creator_.packet_number()); - EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, - QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)); - - // Add a stream frame to the creator and flush the packet. - ASSERT_TRUE(creator_.ConsumeData(kCryptoStreamId, io_vector, 0u, 0u, false, - false, &frame)); - ASSERT_TRUE(frame.stream_frame); - consumed = frame.stream_frame->data_length; - EXPECT_EQ(4u, consumed); - EXPECT_TRUE(creator_.HasPendingFrames()); - creator_.Flush(); - // Verify serialized data packet's path id. - EXPECT_EQ(kPathId1, serialized_packet_.path_id); - DeleteSerializedPacket(); -} - TEST_P(QuicPacketCreatorTest, AddUnencryptedStreamDataClosesConnection) { creator_.set_encryption_level(ENCRYPTION_NONE); EXPECT_CALL(delegate_, OnUnrecoverableError(_, _, _)); diff --git a/chromium/net/quic/core/quic_packet_generator.cc b/chromium/net/quic/core/quic_packet_generator.cc index 3d86874fc44..2191fd3a3bb 100644 --- a/chromium/net/quic/core/quic_packet_generator.cc +++ b/chromium/net/quic/core/quic_packet_generator.cc @@ -329,12 +329,4 @@ void QuicPacketGenerator::SetEncrypter(EncryptionLevel level, packet_creator_.SetEncrypter(level, encrypter); } -void QuicPacketGenerator::SetCurrentPath( - QuicPathId path_id, - QuicPacketNumber least_packet_awaited_by_peer, - QuicPacketCount max_packets_in_flight) { - packet_creator_.SetCurrentPath(path_id, least_packet_awaited_by_peer, - max_packets_in_flight); -} - } // namespace net diff --git a/chromium/net/quic/core/quic_packet_generator.h b/chromium/net/quic/core/quic_packet_generator.h index 0ae2e9e4712..5821aadc48f 100644 --- a/chromium/net/quic/core/quic_packet_generator.h +++ b/chromium/net/quic/core/quic_packet_generator.h @@ -172,11 +172,6 @@ class QUIC_EXPORT_PRIVATE QuicPacketGenerator { // when there are frames queued in the creator. void SetMaxPacketLength(QuicByteCount length); - // Sets |path_id| to be the path on which next packet is generated. - void SetCurrentPath(QuicPathId path_id, - QuicPacketNumber least_packet_awaited_by_peer, - QuicPacketCount max_packets_in_flight); - void set_debug_delegate(QuicPacketCreator::DebugDelegate* debug_delegate) { packet_creator_.set_debug_delegate(debug_delegate); } diff --git a/chromium/net/quic/core/quic_packet_generator_test.cc b/chromium/net/quic/core/quic_packet_generator_test.cc index 4486fc51de1..45f8890e0d2 100644 --- a/chromium/net/quic/core/quic_packet_generator_test.cc +++ b/chromium/net/quic/core/quic_packet_generator_test.cc @@ -9,7 +9,6 @@ #include <string> #include "base/macros.h" -#include "base/stl_util.h" #include "net/quic/core/crypto/crypto_protocol.h" #include "net/quic/core/crypto/null_encrypter.h" #include "net/quic/core/crypto/quic_decrypter.h" @@ -450,7 +449,7 @@ TEST_F(QuicPacketGeneratorTest, ConsumeData_FramesPreviouslyQueued) { NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) + GetPacketHeaderSize( framer_.version(), creator_->connection_id_length(), kIncludeVersion, - !kIncludePathId, !kIncludeDiversificationNonce, + !kIncludeDiversificationNonce, QuicPacketCreatorPeer::GetPacketNumberLength(creator_)) + // Add an extra 3 bytes for the payload and 1 byte so BytesFree is larger // than the GetMinStreamFrameSize. @@ -848,35 +847,6 @@ TEST_F(QuicPacketGeneratorTest, DontCrashOnInvalidStopWaiting) { "for least_unacked_delta: 1001"); } -TEST_F(QuicPacketGeneratorTest, SetCurrentPath) { - delegate_.SetCanWriteAnything(); - generator_.StartBatchOperations(); - - QuicConsumedData consumed = generator_.ConsumeData( - kHeadersStreamId, MakeIOVectorFromStringPiece("foo"), 2, true, nullptr); - EXPECT_EQ(3u, consumed.bytes_consumed); - EXPECT_TRUE(consumed.fin_consumed); - EXPECT_TRUE(generator_.HasQueuedFrames()); - EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(creator_)); - // Does not change current path. - generator_.SetCurrentPath(kDefaultPathId, 1, 0); - EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(creator_)); - - // Try to switch path when a packet is under construction. - QuicPathId kTestPathId1 = 1; - EXPECT_QUIC_BUG(generator_.SetCurrentPath(kTestPathId1, 1, 0), - "Unable to change paths when a packet is under construction"); - EXPECT_EQ(kDefaultPathId, QuicPacketCreatorPeer::GetCurrentPath(creator_)); - - // Try to switch path after current open packet gets serialized. - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - generator_.FlushAllQueuedFrames(); - EXPECT_FALSE(generator_.HasQueuedFrames()); - generator_.SetCurrentPath(kTestPathId1, 1, 0); - EXPECT_EQ(kTestPathId1, QuicPacketCreatorPeer::GetCurrentPath(creator_)); -} - // Regression test for b/31486443. TEST_F(QuicPacketGeneratorTest, ConnectionCloseFrameLargerThanPacketSize) { delegate_.SetCanWriteAnything(); diff --git a/chromium/net/quic/core/quic_packets.cc b/chromium/net/quic/core/quic_packets.cc index 3d7e24b9f65..a88b6e8faea 100644 --- a/chromium/net/quic/core/quic_packets.cc +++ b/chromium/net/quic/core/quic_packets.cc @@ -20,7 +20,6 @@ size_t GetPacketHeaderSize(QuicVersion version, const QuicPacketHeader& header) { return GetPacketHeaderSize(version, header.public_header.connection_id_length, header.public_header.version_flag, - header.public_header.multipath_flag, header.public_header.nonce != nullptr, header.public_header.packet_number_length); } @@ -28,12 +27,10 @@ size_t GetPacketHeaderSize(QuicVersion version, size_t GetPacketHeaderSize(QuicVersion version, QuicConnectionIdLength connection_id_length, bool include_version, - bool include_path_id, bool include_diversification_nonce, QuicPacketNumberLength packet_number_length) { return kPublicFlagsSize + connection_id_length + - (include_version ? kQuicVersionSize : 0) + - (include_path_id ? kQuicPathIdSize : 0) + packet_number_length + + (include_version ? kQuicVersionSize : 0) + packet_number_length + (include_diversification_nonce ? kDiversificationNonceSize : 0); } @@ -45,12 +42,11 @@ size_t GetStartOfEncryptedData(QuicVersion version, size_t GetStartOfEncryptedData(QuicVersion version, QuicConnectionIdLength connection_id_length, bool include_version, - bool include_path_id, bool include_diversification_nonce, QuicPacketNumberLength packet_number_length) { // Encryption starts before private flags. return GetPacketHeaderSize(version, connection_id_length, include_version, - include_path_id, include_diversification_nonce, + include_diversification_nonce, packet_number_length); } @@ -87,7 +83,6 @@ std::ostream& operator<<(std::ostream& os, const QuicPacketHeader& header) { os << "{ connection_id: " << header.public_header.connection_id << ", connection_id_length: " << header.public_header.connection_id_length << ", packet_number_length: " << header.public_header.packet_number_length - << ", multipath_flag: " << header.public_header.multipath_flag << ", reset_flag: " << header.public_header.reset_flag << ", version_flag: " << header.public_header.version_flag; if (header.public_header.version_flag) { @@ -125,14 +120,12 @@ QuicPacket::QuicPacket(char* buffer, bool owns_buffer, QuicConnectionIdLength connection_id_length, bool includes_version, - bool includes_path_id, bool includes_diversification_nonce, QuicPacketNumberLength packet_number_length) : QuicData(buffer, length, owns_buffer), buffer_(buffer), connection_id_length_(connection_id_length), includes_version_(includes_version), - includes_path_id_(includes_path_id), includes_diversification_nonce_(includes_diversification_nonce), packet_number_length_(packet_number_length) {} @@ -194,15 +187,14 @@ std::ostream& operator<<(std::ostream& os, const QuicReceivedPacket& s) { StringPiece QuicPacket::AssociatedData(QuicVersion version) const { return StringPiece( - data(), GetStartOfEncryptedData(version, connection_id_length_, - includes_version_, includes_path_id_, - includes_diversification_nonce_, - packet_number_length_)); + data(), GetStartOfEncryptedData( + version, connection_id_length_, includes_version_, + includes_diversification_nonce_, packet_number_length_)); } StringPiece QuicPacket::Plaintext(QuicVersion version) const { const size_t start_of_encrypted_data = GetStartOfEncryptedData( - version, connection_id_length_, includes_version_, includes_path_id_, + version, connection_id_length_, includes_version_, includes_diversification_nonce_, packet_number_length_); return StringPiece(data() + start_of_encrypted_data, length() - start_of_encrypted_data); @@ -226,7 +218,6 @@ SerializedPacket::SerializedPacket(QuicPathId path_id, has_ack(has_ack), has_stop_waiting(has_stop_waiting), transmission_type(NOT_RETRANSMISSION), - original_path_id(kInvalidPathId), original_packet_number(0) {} SerializedPacket::SerializedPacket(const SerializedPacket& other) = default; diff --git a/chromium/net/quic/core/quic_packets.h b/chromium/net/quic/core/quic_packets.h index b620146157c..5f2d8630568 100644 --- a/chromium/net/quic/core/quic_packets.h +++ b/chromium/net/quic/core/quic_packets.h @@ -41,7 +41,6 @@ QUIC_EXPORT_PRIVATE size_t GetPacketHeaderSize(QuicVersion version, QuicConnectionIdLength connection_id_length, bool include_version, - bool include_path_id, bool include_diversification_nonce, QuicPacketNumberLength packet_number_length); @@ -53,7 +52,6 @@ QUIC_EXPORT_PRIVATE size_t GetStartOfEncryptedData(QuicVersion version, QuicConnectionIdLength connection_id_length, bool include_version, - bool include_path_id, bool include_diversification_nonce, QuicPacketNumberLength packet_number_length); @@ -128,7 +126,7 @@ class QUIC_EXPORT_PRIVATE QuicData { class QUIC_EXPORT_PRIVATE QuicPacket : public QuicData { public: - // TODO(fayang): 4 fields from public header are passed in as arguments. + // TODO(fayang): 3 fields from public header are passed in as arguments. // Consider to add a convenience method which directly accepts the entire // public header. QuicPacket(char* buffer, @@ -136,7 +134,6 @@ class QUIC_EXPORT_PRIVATE QuicPacket : public QuicData { bool owns_buffer, QuicConnectionIdLength connection_id_length, bool includes_version, - bool includes_path_id, bool includes_diversification_nonce, QuicPacketNumberLength packet_number_length); @@ -149,7 +146,6 @@ class QUIC_EXPORT_PRIVATE QuicPacket : public QuicData { char* buffer_; const QuicConnectionIdLength connection_id_length_; const bool includes_version_; - const bool includes_path_id_; const bool includes_diversification_nonce_; const QuicPacketNumberLength packet_number_length_; @@ -242,7 +238,6 @@ struct QUIC_EXPORT_PRIVATE SerializedPacket { bool has_ack; bool has_stop_waiting; TransmissionType transmission_type; - QuicPathId original_path_id; QuicPacketNumber original_packet_number; // Optional notifiers which will be informed when this packet has been ACKed. diff --git a/chromium/net/quic/core/quic_received_packet_manager.cc b/chromium/net/quic/core/quic_received_packet_manager.cc index 1f2734d6036..668301de52d 100644 --- a/chromium/net/quic/core/quic_received_packet_manager.cc +++ b/chromium/net/quic/core/quic_received_packet_manager.cc @@ -7,8 +7,6 @@ #include <limits> #include <utility> -#include "base/stl_util.h" -#include "net/base/linked_hash_map.h" #include "net/quic/core/crypto/crypto_protocol.h" #include "net/quic/core/quic_connection_stats.h" #include "net/quic/platform/api/quic_bug_tracker.h" @@ -73,8 +71,8 @@ bool QuicReceivedPacketManager::IsMissing(QuicPacketNumber packet_number) { bool QuicReceivedPacketManager::IsAwaitingPacket( QuicPacketNumber packet_number) { - return ::net::IsAwaitingPacket(ack_frame_, packet_number, - peer_least_packet_awaiting_ack_); + return net::IsAwaitingPacket(ack_frame_, packet_number, + peer_least_packet_awaiting_ack_); } const QuicFrame QuicReceivedPacketManager::GetUpdatedAckFrame( @@ -105,18 +103,13 @@ const QuicFrame QuicReceivedPacketManager::GetUpdatedAckFrame( return QuicFrame(&ack_frame_); } -bool QuicReceivedPacketManager::DontWaitForPacketsBefore( +void QuicReceivedPacketManager::DontWaitForPacketsBefore( QuicPacketNumber least_unacked) { - peer_least_packet_awaiting_ack_ = least_unacked; - return ack_frame_.packets.RemoveUpTo(least_unacked); -} - -void QuicReceivedPacketManager::UpdatePacketInformationSentByPeer( - const QuicStopWaitingFrame& stop_waiting) { // ValidateAck() should fail if peer_least_packet_awaiting_ack shrinks. - DCHECK_LE(peer_least_packet_awaiting_ack_, stop_waiting.least_unacked); - if (stop_waiting.least_unacked > peer_least_packet_awaiting_ack_) { - bool packets_updated = DontWaitForPacketsBefore(stop_waiting.least_unacked); + DCHECK_LE(peer_least_packet_awaiting_ack_, least_unacked); + if (least_unacked > peer_least_packet_awaiting_ack_) { + peer_least_packet_awaiting_ack_ = least_unacked; + bool packets_updated = ack_frame_.packets.RemoveUpTo(least_unacked); if (packets_updated) { // Ack frame gets updated because packets set is updated because of stop // waiting frame. diff --git a/chromium/net/quic/core/quic_received_packet_manager.h b/chromium/net/quic/core/quic_received_packet_manager.h index 140a825f9e0..08001a84e86 100644 --- a/chromium/net/quic/core/quic_received_packet_manager.h +++ b/chromium/net/quic/core/quic_received_packet_manager.h @@ -15,7 +15,6 @@ namespace net { namespace test { class QuicConnectionPeer; -class QuicReceivedPacketManagerPeer; } // namespace test struct QuicConnectionStats; @@ -43,9 +42,10 @@ class QUIC_EXPORT_PRIVATE QuicReceivedPacketManager { // another packet is received, or it will change. const QuicFrame GetUpdatedAckFrame(QuicTime approximate_now); - // Updates internal state based on |stop_waiting|. - virtual void UpdatePacketInformationSentByPeer( - const QuicStopWaitingFrame& stop_waiting); + // Deletes all missing packets before least unacked. The connection won't + // process any packets with packet number before |least_unacked| that it + // received after this call. + void DontWaitForPacketsBefore(QuicPacketNumber least_unacked); // Returns true if there are any missing packets. bool HasMissingPackets() const; @@ -67,13 +67,6 @@ class QUIC_EXPORT_PRIVATE QuicReceivedPacketManager { private: friend class test::QuicConnectionPeer; - friend class test::QuicReceivedPacketManagerPeer; - - // Deletes all missing packets before least unacked. The connection won't - // process any packets with packet number before |least_unacked| that it - // received after this call. Returns true if there were missing packets before - // |least_unacked| unacked, false otherwise. - bool DontWaitForPacketsBefore(QuicPacketNumber least_unacked); // Least packet number of the the packet sent by the peer for which it // hasn't received an ack. diff --git a/chromium/net/quic/core/quic_received_packet_manager_test.cc b/chromium/net/quic/core/quic_received_packet_manager_test.cc index 6a2e02011b6..e7ff3d3cab5 100644 --- a/chromium/net/quic/core/quic_received_packet_manager_test.cc +++ b/chromium/net/quic/core/quic_received_packet_manager_test.cc @@ -9,7 +9,6 @@ #include <vector> #include "net/quic/core/quic_connection_stats.h" -#include "net/quic/test_tools/quic_received_packet_manager_peer.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { @@ -68,8 +67,7 @@ TEST_P(QuicReceivedPacketManagerTest, DontWaitForPacketsBefore) { received_manager_.RecordPacketReceived(header, QuicTime::Zero()); EXPECT_TRUE(received_manager_.IsAwaitingPacket(3u)); EXPECT_TRUE(received_manager_.IsAwaitingPacket(6u)); - EXPECT_TRUE(QuicReceivedPacketManagerPeer::DontWaitForPacketsBefore( - &received_manager_, 4)); + received_manager_.DontWaitForPacketsBefore(4); EXPECT_FALSE(received_manager_.IsAwaitingPacket(3u)); EXPECT_TRUE(received_manager_.IsAwaitingPacket(6u)); } diff --git a/chromium/net/quic/core/quic_sent_packet_manager.cc b/chromium/net/quic/core/quic_sent_packet_manager.cc index 21646fbd25f..3b601e25365 100644 --- a/chromium/net/quic/core/quic_sent_packet_manager.cc +++ b/chromium/net/quic/core/quic_sent_packet_manager.cc @@ -7,7 +7,6 @@ #include <algorithm> #include <string> -#include "base/stl_util.h" #include "net/quic/chromium/quic_utils_chromium.h" #include "net/quic/core/congestion_control/general_loss_algorithm.h" #include "net/quic/core/congestion_control/pacing_sender.h" @@ -18,6 +17,7 @@ #include "net/quic/core/quic_pending_retransmission.h" #include "net/quic/platform/api/quic_bug_tracker.h" #include "net/quic/platform/api/quic_logging.h" +#include "net/quic/platform/api/quic_map_util.h" namespace net { @@ -280,7 +280,7 @@ void QuicSentPacketManager::OnIncomingAck(const QuicAckFrame& ack_frame, pending_retransmissions_.front().second == LOSS_RETRANSMISSION) { // Cancel any pending retransmissions larger than largest_newly_acked_. unacked_packets_.RestoreToInFlight(pending_retransmissions_.front().first); - pending_retransmissions_.erase(pending_retransmissions_.begin()); + pending_retransmissions_.pop_front(); } if (debug_delegate_ != nullptr) { @@ -397,8 +397,8 @@ void QuicSentPacketManager::MarkForRetransmission( } // TODO(ianswett): Currently the RTO can fire while there are pending NACK // retransmissions for the same data, which is not ideal. - if (base::ContainsKey(pending_retransmissions_, packet_number)) { - return; + if (QuicContainsKey(pending_retransmissions_, packet_number)) { + return; } pending_retransmissions_[packet_number] = transmission_type; @@ -438,7 +438,7 @@ bool QuicSentPacketManager::HasPendingRetransmissions() const { QuicPendingRetransmission QuicSentPacketManager::NextPendingRetransmission() { QUIC_BUG_IF(pending_retransmissions_.empty()) - << "Unexpected call to PendingRetransmissions() with empty pending " + << "Unexpected call to NextPendingRetransmission() with empty pending " << "retransmission list. Corrupted memory usage imminent."; QuicPacketNumber packet_number = pending_retransmissions_.begin()->first; TransmissionType transmission_type = pending_retransmissions_.begin()->second; @@ -781,8 +781,7 @@ const QuicTime QuicSentPacketManager::GetRetransmissionTime() const { pending_timer_transmission_count_ > 0) { return QuicTime::Zero(); } - if (FLAGS_quic_reloadable_flag_quic_more_conservative_retransmission_alarm && - !unacked_packets_.HasUnackedRetransmittableFrames()) { + if (!unacked_packets_.HasUnackedRetransmittableFrames()) { return QuicTime::Zero(); } switch (GetRetransmissionMode()) { diff --git a/chromium/net/quic/core/quic_sent_packet_manager.h b/chromium/net/quic/core/quic_sent_packet_manager.h index 7ed8b90949a..c135b2f9867 100644 --- a/chromium/net/quic/core/quic_sent_packet_manager.h +++ b/chromium/net/quic/core/quic_sent_packet_manager.h @@ -14,7 +14,6 @@ #include <vector> #include "base/macros.h" -#include "net/base/linked_hash_map.h" #include "net/quic/core/congestion_control/general_loss_algorithm.h" #include "net/quic/core/congestion_control/loss_detection_interface.h" #include "net/quic/core/congestion_control/pacing_sender.h" @@ -24,6 +23,7 @@ #include "net/quic/core/quic_pending_retransmission.h" #include "net/quic/core/quic_sustained_bandwidth_recorder.h" #include "net/quic/core/quic_unacked_packet_map.h" +#include "net/quic/platform/api/quic_containers.h" #include "net/quic/platform/api/quic_export.h" namespace net { @@ -240,7 +240,7 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager { LOSS_MODE, }; - typedef linked_hash_map<QuicPacketNumber, TransmissionType> + typedef QuicLinkedHashMap<QuicPacketNumber, TransmissionType> PendingRetransmissionMap; // Updates the least_packet_awaited_by_peer. diff --git a/chromium/net/quic/core/quic_server_id.cc b/chromium/net/quic/core/quic_server_id.cc index 280530a97d5..6239706104c 100644 --- a/chromium/net/quic/core/quic_server_id.cc +++ b/chromium/net/quic/core/quic_server_id.cc @@ -6,10 +6,7 @@ #include <tuple> -#include "net/base/host_port_pair.h" -#include "net/base/port_util.h" #include "net/quic/platform/api/quic_str_cat.h" -#include "url/gurl.h" using std::string; @@ -41,16 +38,6 @@ bool QuicServerId::operator==(const QuicServerId& other) const { host_port_pair_.Equals(other.host_port_pair_); } -// static -QuicServerId QuicServerId::FromString(const std::string& str) { - GURL url(str); - if (!url.is_valid()) - return QuicServerId(); - return QuicServerId(HostPortPair::FromURL(url), url.path_piece() == "/private" - ? PRIVACY_MODE_ENABLED - : PRIVACY_MODE_DISABLED); -} - string QuicServerId::ToString() const { return QuicStrCat("https://", host_port_pair_.ToString(), (privacy_mode_ == PRIVACY_MODE_ENABLED ? "/private" : "")); diff --git a/chromium/net/quic/core/quic_server_id.h b/chromium/net/quic/core/quic_server_id.h index 906529d1c51..580789c40b4 100644 --- a/chromium/net/quic/core/quic_server_id.h +++ b/chromium/net/quic/core/quic_server_id.h @@ -31,15 +31,11 @@ class QUIC_EXPORT_PRIVATE QuicServerId { bool operator<(const QuicServerId& other) const; bool operator==(const QuicServerId& other) const; - // Creates a QuicServerId from a string formatted in same manner as - // ToString(). - static QuicServerId FromString(const std::string& str); - // ToString() will convert the QuicServerId to "scheme:hostname:port" or // "scheme:hostname:port/private". "scheme" will be "https". std::string ToString() const; - // Used in Chromium, but not in the server. + // Used in Chromium, but not internally. const HostPortPair& host_port_pair() const { return host_port_pair_; } const std::string& host() const { return host_port_pair_.host(); } diff --git a/chromium/net/quic/core/quic_server_session_base.cc b/chromium/net/quic/core/quic_server_session_base.cc index d4275440c6d..9b13dba1238 100644 --- a/chromium/net/quic/core/quic_server_session_base.cc +++ b/chromium/net/quic/core/quic_server_session_base.cc @@ -7,7 +7,6 @@ #include "net/quic/core/proto/cached_network_parameters.pb.h" #include "net/quic/core/quic_connection.h" #include "net/quic/core/quic_flags.h" -#include "net/quic/core/quic_spdy_session.h" #include "net/quic/core/quic_stream.h" #include "net/quic/platform/api/quic_bug_tracker.h" #include "net/quic/platform/api/quic_logging.h" @@ -113,7 +112,7 @@ void QuicServerSessionBase::OnCongestionWindowChange(QuicTime now) { sent_packet_manager.GetRttStats()->smoothed_rtt().ToMilliseconds(); int64_t now_ms = (now - last_scup_time_).ToMilliseconds(); int64_t packets_since_last_scup = - connection()->packet_number_of_last_sent_packet() - + connection()->sent_packet_manager().GetLargestSentPacket() - last_scup_packet_number_; if (now_ms < (kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms) || now_ms < kMinIntervalBetweenServerConfigUpdatesMs || @@ -190,7 +189,8 @@ void QuicServerSessionBase::OnCongestionWindowChange(QuicTime now) { connection()->OnSendConnectionState(cached_network_params); last_scup_time_ = now; - last_scup_packet_number_ = connection()->packet_number_of_last_sent_packet(); + last_scup_packet_number_ = + connection()->sent_packet_manager().GetLargestSentPacket(); } bool QuicServerSessionBase::ShouldCreateIncomingDynamicStream(QuicStreamId id) { diff --git a/chromium/net/quic/core/quic_server_session_base.h b/chromium/net/quic/core/quic_server_session_base.h index 5ad9a848e02..6b41e6570a4 100644 --- a/chromium/net/quic/core/quic_server_session_base.h +++ b/chromium/net/quic/core/quic_server_session_base.h @@ -7,8 +7,6 @@ #ifndef NET_QUIC_CORE_QUIC_SERVER_SESSION_BASE_H_ #define NET_QUIC_CORE_QUIC_SERVER_SESSION_BASE_H_ -#include <stdint.h> - #include <cstdint> #include <memory> #include <set> diff --git a/chromium/net/quic/core/quic_server_session_base_test.cc b/chromium/net/quic/core/quic_server_session_base_test.cc index 5baad162205..6e18cd544f6 100644 --- a/chromium/net/quic/core/quic_server_session_base_test.cc +++ b/chromium/net/quic/core/quic_server_session_base_test.cc @@ -31,7 +31,7 @@ #include "net/test/gtest_util.h" #include "net/tools/quic/quic_epoll_connection_helper.h" #include "net/tools/quic/quic_simple_server_stream.h" -#include "net/tools/quic/test_tools/mock_quic_server_session_visitor.h" +#include "net/tools/quic/test_tools/mock_quic_session_visitor.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -120,7 +120,7 @@ const size_t kMaxStreamsForTest = 10; class QuicServerSessionBaseTest : public ::testing::TestWithParam<QuicVersion> { protected: QuicServerSessionBaseTest() - : QuicServerSessionBaseTest(CryptoTestUtils::ProofSourceForTesting()) {} + : QuicServerSessionBaseTest(crypto_test_utils::ProofSourceForTesting()) {} explicit QuicServerSessionBaseTest(std::unique_ptr<ProofSource> proof_source) : crypto_config_(QuicCryptoServerConfig::TESTING, @@ -474,8 +474,11 @@ TEST_P(QuicServerSessionBaseTest, BandwidthEstimates) { // Bandwidth estimate has now changed sufficiently, enough time has passed, // and enough packets have been sent. - QuicConnectionPeer::SetPacketNumberOfLastSentPacket( - session_->connection(), kMinPacketsBetweenServerConfigUpdates); + SerializedPacket packet( + kDefaultPathId, 1 + kMinPacketsBetweenServerConfigUpdates, + PACKET_6BYTE_PACKET_NUMBER, nullptr, 1000, false, false); + sent_packet_manager->OnPacketSent(&packet, 0, now, NOT_RETRANSMISSION, + HAS_RETRANSMITTABLE_DATA); // Verify that the proto has exactly the values we expect. CachedNetworkParameters expected_network_params; @@ -599,14 +602,13 @@ INSTANTIATE_TEST_CASE_P(StreamMemberLifetimeTests, // ProofSource::GetProof. Delay the completion of the operation until after the // stream has been destroyed, and verify that there are no memory bugs. TEST_P(StreamMemberLifetimeTest, Basic) { - FLAGS_quic_reloadable_flag_enable_async_get_proof = true; FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support = true; FLAGS_quic_reloadable_flag_quic_use_cheap_stateless_rejects = true; FLAGS_quic_reloadable_flag_quic_create_session_after_insertion = true; const QuicClock* clock = helper_.GetClock(); QuicVersion version = AllSupportedVersions().front(); - CryptoHandshakeMessage chlo = CryptoTestUtils::GenerateDefaultInchoateCHLO( + CryptoHandshakeMessage chlo = crypto_test_utils::GenerateDefaultInchoateCHLO( clock, version, &crypto_config_); chlo.SetVector(kCOPT, QuicTagVector{kSREJ}); std::vector<QuicVersion> packet_version_list = {version}; diff --git a/chromium/net/quic/core/quic_session.cc b/chromium/net/quic/core/quic_session.cc index 0845816fac4..6160cdd2a31 100644 --- a/chromium/net/quic/core/quic_session.cc +++ b/chromium/net/quic/core/quic_session.cc @@ -4,13 +4,15 @@ #include "net/quic/core/quic_session.h" -#include "base/stl_util.h" -#include "net/quic/core/crypto/proof_verifier.h" +#include <cstdint> +#include <utility> + #include "net/quic/core/quic_connection.h" #include "net/quic/core/quic_flags.h" #include "net/quic/core/quic_flow_controller.h" #include "net/quic/platform/api/quic_bug_tracker.h" #include "net/quic/platform/api/quic_logging.h" +#include "net/quic/platform/api/quic_map_util.h" #include "net/quic/platform/api/quic_str_cat.h" using base::StringPiece; @@ -19,7 +21,7 @@ using std::string; namespace net { #define ENDPOINT \ - (perspective() == Perspective::IS_SERVER ? "Server: " : " Client: ") + (perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ") QuicSession::QuicSession(QuicConnection* connection, Visitor* owner, @@ -41,8 +43,11 @@ QuicSession::QuicSession(QuicConnection* connection, perspective(), kMinimumFlowControlSendWindow, config_.GetInitialSessionFlowControlWindowToSend(), - perspective() == Perspective::IS_SERVER), - currently_writing_stream_id_(0) {} + perspective() == Perspective::IS_SERVER, + nullptr), + currently_writing_stream_id_(0), + flow_control_invariant_( + FLAGS_quic_reloadable_flag_quic_flow_control_invariant) {} void QuicSession::Initialize() { connection_->set_visitor(this); @@ -83,7 +88,7 @@ void QuicSession::OnStreamFrame(const QuicStreamFrame& frame) { } void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) { - if (base::ContainsKey(static_stream_map_, frame.stream_id)) { + if (QuicContainsKey(static_stream_map_, frame.stream_id)) { connection()->CloseConnection( QUIC_INVALID_STREAM_ID, "Attempt to reset a static stream", ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); @@ -311,7 +316,7 @@ QuicConsumedData QuicSession::WritevData( void QuicSession::SendRstStream(QuicStreamId id, QuicRstStreamErrorCode error, QuicStreamOffset bytes_written) { - if (base::ContainsKey(static_stream_map_, id)) { + if (QuicContainsKey(static_stream_map_, id)) { QUIC_BUG << "Cannot send RST for a static stream with ID " << id; return; } @@ -624,8 +629,8 @@ void QuicSession::ActivateStream(std::unique_ptr<QuicStream> stream) { QuicStreamId stream_id = stream->id(); QUIC_DLOG(INFO) << ENDPOINT << "num_streams: " << dynamic_stream_map_.size() << ". activating " << stream_id; - DCHECK(!base::ContainsKey(dynamic_stream_map_, stream_id)); - DCHECK(!base::ContainsKey(static_stream_map_, stream_id)); + DCHECK(!QuicContainsKey(dynamic_stream_map_, stream_id)); + DCHECK(!QuicContainsKey(static_stream_map_, stream_id)); dynamic_stream_map_[stream_id] = std::move(stream); if (IsIncomingStream(stream_id)) { ++num_dynamic_incoming_streams_; @@ -649,8 +654,8 @@ QuicStream* QuicSession::GetOrCreateStream(const QuicStreamId stream_id) { } void QuicSession::StreamDraining(QuicStreamId stream_id) { - DCHECK(base::ContainsKey(dynamic_stream_map_, stream_id)); - if (!base::ContainsKey(draining_streams_, stream_id)) { + DCHECK(QuicContainsKey(dynamic_stream_map_, stream_id)); + if (!QuicContainsKey(draining_streams_, stream_id)) { draining_streams_.insert(stream_id); if (IsIncomingStream(stream_id)) { ++num_draining_incoming_streams_; @@ -703,7 +708,7 @@ bool QuicSession::ShouldYield(QuicStreamId stream_id) { QuicStream* QuicSession::GetOrCreateDynamicStream( const QuicStreamId stream_id) { - DCHECK(!base::ContainsKey(static_stream_map_, stream_id)) + DCHECK(!QuicContainsKey(static_stream_map_, stream_id)) << "Attempt to call GetOrCreateDynamicStream for a static stream"; DynamicStreamMap::iterator it = dynamic_stream_map_.find(stream_id); @@ -772,13 +777,13 @@ bool QuicSession::IsClosedStream(QuicStreamId id) { } // For peer created streams, we also need to consider available streams. return id <= largest_peer_created_stream_id_ && - !base::ContainsKey(available_streams_, id); + !QuicContainsKey(available_streams_, id); } bool QuicSession::IsOpenStream(QuicStreamId id) { DCHECK_NE(0u, id); - if (base::ContainsKey(static_stream_map_, id) || - base::ContainsKey(dynamic_stream_map_, id)) { + if (QuicContainsKey(static_stream_map_, id) || + QuicContainsKey(dynamic_stream_map_, id)) { // Stream is active return true; } diff --git a/chromium/net/quic/core/quic_session.h b/chromium/net/quic/core/quic_session.h index 7397b7195d8..283f55f3ff3 100644 --- a/chromium/net/quic/core/quic_session.h +++ b/chromium/net/quic/core/quic_session.h @@ -7,17 +7,14 @@ #ifndef NET_QUIC_CORE_QUIC_SESSION_H_ #define NET_QUIC_CORE_QUIC_SESSION_H_ -#include <stddef.h> - +#include <cstddef> #include <map> #include <memory> #include <string> -#include <unordered_map> #include <unordered_set> #include <vector> #include "base/compiler_specific.h" -#include "base/containers/small_map.h" #include "base/macros.h" #include "base/strings/string_piece.h" #include "net/quic/core/quic_connection.h" @@ -26,7 +23,9 @@ #include "net/quic/core/quic_packets.h" #include "net/quic/core/quic_stream.h" #include "net/quic/core/quic_write_blocked_list.h" +#include "net/quic/platform/api/quic_containers.h" #include "net/quic/platform/api/quic_export.h" +#include "net/quic/platform/api/quic_socket_address.h" namespace net { @@ -42,7 +41,7 @@ class QUIC_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface { public: // An interface from the session to the entity owning the session. // This lets the session notify its owner (the Dispatcher) when the connection - // is closed, blocked, or added/removed from the time-wait std::list. + // is closed, blocked, or added/removed from the time-wait list. class Visitor { public: virtual ~Visitor() {} @@ -247,13 +246,13 @@ class QUIC_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface { // Returns true if this stream should yield writes to another blocked stream. bool ShouldYield(QuicStreamId stream_id); + bool flow_control_invariant() { return flow_control_invariant_; } + protected: - using StaticStreamMap = - base::SmallMap<std::unordered_map<QuicStreamId, QuicStream*>, 2>; + using StaticStreamMap = QuicSmallMap<QuicStreamId, QuicStream*, 2>; - using DynamicStreamMap = base::SmallMap< - std::unordered_map<QuicStreamId, std::unique_ptr<QuicStream>>, - 10>; + using DynamicStreamMap = + QuicSmallMap<QuicStreamId, std::unique_ptr<QuicStream>, 10>; using ClosedStreams = std::vector<std::unique_ptr<QuicStream>>; @@ -440,6 +439,9 @@ class QUIC_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface { // call stack of OnCanWrite. QuicStreamId currently_writing_stream_id_; + // Latched value of gfe2_reloadable_flag_quic_flow_control_invariant. + const bool flow_control_invariant_; + DISALLOW_COPY_AND_ASSIGN(QuicSession); }; diff --git a/chromium/net/quic/core/quic_session_test.cc b/chromium/net/quic/core/quic_session_test.cc index f2deba15b63..edc935699b0 100644 --- a/chromium/net/quic/core/quic_session_test.cc +++ b/chromium/net/quic/core/quic_session_test.cc @@ -4,11 +4,11 @@ #include "net/quic/core/quic_session.h" +#include <cstdint> #include <set> #include <utility> #include "base/rand_util.h" -#include "base/stl_util.h" #include "build/build_config.h" #include "net/quic/core/crypto/crypto_protocol.h" #include "net/quic/core/crypto/null_encrypter.h" @@ -17,6 +17,7 @@ #include "net/quic/core/quic_packets.h" #include "net/quic/core/quic_stream.h" #include "net/quic/core/quic_utils.h" +#include "net/quic/platform/api/quic_map_util.h" #include "net/quic/platform/api/quic_ptr_util.h" #include "net/quic/platform/api/quic_str_cat.h" #include "net/quic/test_tools/quic_config_peer.h" @@ -33,8 +34,6 @@ #include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" -using net::SpdyHeaderBlock; -using net::SpdyPriority; using std::string; using testing::CreateFunctor; using testing::AtLeast; @@ -262,7 +261,7 @@ class QuicSessionTestBase : public ::testing::TestWithParam<QuicVersion> { void CheckClosedStreams() { for (QuicStreamId i = kCryptoStreamId; i < 100; i++) { - if (!base::ContainsKey(closed_streams_, i)) { + if (!QuicContainsKey(closed_streams_, i)) { EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i; } else { EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i; @@ -1221,7 +1220,7 @@ TEST_P(QuicSessionTestServer, TestMaxIncomingAndOutgoingStreamsAllowed) { TEST_P(QuicSessionTestServer, EnableFHOLThroughConfigOption) { QuicConfigPeer::SetReceivedForceHolBlocking(session_.config()); session_.OnConfigNegotiated(); - if (version() <= QUIC_VERSION_35) { + if (version() != QUIC_VERSION_36) { EXPECT_FALSE(session_.force_hol_blocking()); } else { EXPECT_TRUE(session_.force_hol_blocking()); @@ -1306,7 +1305,7 @@ TEST_P(QuicSessionTestClient, EnableDHDTThroughConnectionOption) { TEST_P(QuicSessionTestClient, EnableFHOLThroughConfigOption) { session_.config()->SetForceHolBlocking(); session_.OnConfigNegotiated(); - if (version() <= QUIC_VERSION_35) { + if (version() != QUIC_VERSION_36) { EXPECT_FALSE(session_.force_hol_blocking()); } else { EXPECT_TRUE(session_.force_hol_blocking()); diff --git a/chromium/net/quic/core/quic_socket_address_coder.cc b/chromium/net/quic/core/quic_socket_address_coder.cc index ae1dd6d673f..dc20f807e72 100644 --- a/chromium/net/quic/core/quic_socket_address_coder.cc +++ b/chromium/net/quic/core/quic_socket_address_coder.cc @@ -4,8 +4,6 @@ #include "net/quic/core/quic_socket_address_coder.h" -#include "net/base/sys_addrinfo.h" - using std::string; namespace net { @@ -59,10 +57,10 @@ bool QuicSocketAddressCoder::Decode(const char* data, size_t length) { size_t ip_length; switch (address_family) { case kIPv4: - ip_length = IPAddress::kIPv4AddressSize; + ip_length = QuicIpAddress::kIPv4AddressSize; break; case kIPv6: - ip_length = IPAddress::kIPv6AddressSize; + ip_length = QuicIpAddress::kIPv6AddressSize; break; default: return false; diff --git a/chromium/net/quic/core/quic_socket_address_coder.h b/chromium/net/quic/core/quic_socket_address_coder.h index 1038c288d25..0a98cfe6e98 100644 --- a/chromium/net/quic/core/quic_socket_address_coder.h +++ b/chromium/net/quic/core/quic_socket_address_coder.h @@ -5,9 +5,7 @@ #ifndef NET_QUIC_CORE_QUIC_SOCKET_ADDRESS_CODER_H_ #define NET_QUIC_CORE_QUIC_SOCKET_ADDRESS_CODER_H_ -#include <stddef.h> -#include <stdint.h> - +#include <cstdint> #include <string> #include "base/macros.h" diff --git a/chromium/net/quic/core/quic_socket_address_coder_test.cc b/chromium/net/quic/core/quic_socket_address_coder_test.cc index 703cc430e04..548fde2eb7a 100644 --- a/chromium/net/quic/core/quic_socket_address_coder_test.cc +++ b/chromium/net/quic/core/quic_socket_address_coder_test.cc @@ -4,7 +4,6 @@ #include "net/quic/core/quic_socket_address_coder.h" -#include "net/base/sys_addrinfo.h" #include "testing/gtest/include/gtest/gtest.h" using std::string; diff --git a/chromium/net/quic/core/quic_spdy_session.cc b/chromium/net/quic/core/quic_spdy_session.cc index 279646b95e6..29f71db0b32 100644 --- a/chromium/net/quic/core/quic_spdy_session.cc +++ b/chromium/net/quic/core/quic_spdy_session.cc @@ -4,6 +4,9 @@ #include "net/quic/core/quic_spdy_session.h" +#include <algorithm> +#include <cstdint> +#include <string> #include <utility> #include "net/quic/core/quic_flags.h" @@ -135,9 +138,9 @@ class QuicSpdySession::SpdyFramerVisitor } void OnError(SpdyFramer* framer) override { - CloseConnection( - QuicStrCat("SPDY framing error: ", - SpdyFramer::ErrorCodeToString(framer->error_code()))); + CloseConnection(QuicStrCat( + "SPDY framing error: ", + SpdyFramer::SpdyFramerErrorToString(framer->spdy_framer_error()))); } void OnDataFrameHeader(SpdyStreamId stream_id, @@ -149,8 +152,7 @@ class QuicSpdySession::SpdyFramerVisitor CloseConnection("SPDY DATA frame received."); } - void OnRstStream(SpdyStreamId stream_id, - SpdyRstStreamStatus status) override { + void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override { CloseConnection("SPDY RST_STREAM frame received."); } @@ -208,7 +210,7 @@ class QuicSpdySession::SpdyFramerVisitor } void OnGoAway(SpdyStreamId last_accepted_stream_id, - SpdyGoAwayStatus status) override { + SpdyErrorCode error_code) override { CloseConnection("SPDY GOAWAY frame received."); } @@ -256,7 +258,7 @@ class QuicSpdySession::SpdyFramerVisitor CloseConnection("SPDY PRIORITY frame received."); } - bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) override { + bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override { CloseConnection("Unknown frame type received."); return false; } @@ -438,7 +440,10 @@ void QuicSpdySession::WriteDataFrame( StringPiece data, bool fin, QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { - SpdyDataIR spdy_data(id, data); + // Note that certain SpdyDataIR constructors perform a deep copy of |data| + // which should be avoided here. + SpdyDataIR spdy_data(id); + spdy_data.SetDataShallow(data); spdy_data.set_fin(fin); SpdySerializedFrame frame(spdy_framer_.SerializeFrame(spdy_data)); QuicReferenceCountedPointer<ForceHolAckListener> force_hol_ack_listener; @@ -566,7 +571,7 @@ void QuicSpdySession::OnConfigNegotiated() { } const QuicVersion version = connection()->version(); if (FLAGS_quic_reloadable_flag_quic_enable_force_hol_blocking && - version > QUIC_VERSION_35 && config()->ForceHolBlocking(perspective())) { + version == QUIC_VERSION_36 && config()->ForceHolBlocking(perspective())) { force_hol_blocking_ = true; // Since all streams are tunneled through the headers stream, it // is important that headers stream never flow control blocks. diff --git a/chromium/net/quic/core/quic_spdy_session.h b/chromium/net/quic/core/quic_spdy_session.h index d0066b59ebe..183c5f1f97b 100644 --- a/chromium/net/quic/core/quic_spdy_session.h +++ b/chromium/net/quic/core/quic_spdy_session.h @@ -5,8 +5,7 @@ #ifndef NET_QUIC_CORE_QUIC_SPDY_SESSION_H_ #define NET_QUIC_CORE_QUIC_SPDY_SESSION_H_ -#include <stddef.h> - +#include <cstddef> #include <memory> #include "base/macros.h" @@ -159,6 +158,9 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession : public QuicSession { spdy_framer_.set_max_decode_buffer_size_bytes(max_decode_buffer_size_bytes); } + void set_max_uncompressed_header_bytes( + size_t set_max_uncompressed_header_bytes); + protected: // Override CreateIncomingDynamicStream() and CreateOutgoingDynamicStream() // with QuicSpdyStream return type to make sure that all data streams are @@ -198,9 +200,6 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession : public QuicSession { // server side. void UpdateEnableServerPush(bool value); - void set_max_uncompressed_header_bytes( - size_t set_max_uncompressed_header_bytes); - bool IsConnected() { return connection()->connected(); } private: diff --git a/chromium/net/quic/core/quic_spdy_stream.cc b/chromium/net/quic/core/quic_spdy_stream.cc index 3fb5e236adb..8a6cf48dbcf 100644 --- a/chromium/net/quic/core/quic_spdy_stream.cc +++ b/chromium/net/quic/core/quic_spdy_stream.cc @@ -6,7 +6,6 @@ #include <utility> -#include "net/base/parse_number.h" #include "net/quic/core/quic_spdy_session.h" #include "net/quic/core/quic_utils.h" #include "net/quic/core/quic_write_blocked_list.h" @@ -20,7 +19,6 @@ using base::StringPiece; using std::string; namespace net { - #define ENDPOINT \ (session()->perspective() == Perspective::IS_SERVER ? "Server: " : "Client:" \ " ") @@ -293,19 +291,15 @@ bool QuicSpdyStream::ParseHeaderStatusCode(const SpdyHeaderBlock& header, if (status.size() != 3) { return false; } - - unsigned int result; - if (!ParseUint32(status, &result, nullptr)) { + // First character must be an integer in range [1,5]. + if (status[0] < '1' || status[0] > '5') { return false; } - - // Valid status codes are only in the range [100, 599]. - if (result < 100 || result >= 600) { + // The remaining two characters must be integers. + if (!isdigit(status[1]) || !isdigit(status[2])) { return false; } - - *status_code = static_cast<int>(result); - return true; + return QuicTextUtils::StringToInt(status, status_code); } bool QuicSpdyStream::FinishedReadingTrailers() const { diff --git a/chromium/net/quic/core/quic_spdy_stream.h b/chromium/net/quic/core/quic_spdy_stream.h index d470e800169..fec1fd70d3d 100644 --- a/chromium/net/quic/core/quic_spdy_stream.h +++ b/chromium/net/quic/core/quic_spdy_stream.h @@ -9,9 +9,9 @@ #ifndef NET_QUIC_CORE_QUIC_SPDY_STREAM_H_ #define NET_QUIC_CORE_QUIC_SPDY_STREAM_H_ -#include <stddef.h> #include <sys/types.h> +#include <cstddef> #include <list> #include <string> @@ -181,7 +181,10 @@ class QUIC_EXPORT_PRIVATE QuicSpdyStream : public QuicStream { allow_bidirectional_data_ = value; } - bool allow_bidirectional_data() const { return allow_bidirectional_data_; } + bool allow_bidirectional_data() const { + return FLAGS_quic_reloadable_flag_quic_always_enable_bidi_streaming || + allow_bidirectional_data_; + } using QuicStream::CloseWriteSide; @@ -221,8 +224,7 @@ class QUIC_EXPORT_PRIVATE QuicSpdyStream : public QuicStream { bool headers_decompressed_; // The priority of the stream, once parsed. SpdyPriority priority_; - // Contains a copy of the decompressed header (name, value) std::pairs until - // they + // Contains a copy of the decompressed header (name, value) pairs until they // are consumed via Readv. QuicHeaderList header_list_; diff --git a/chromium/net/quic/core/quic_spdy_stream_test.cc b/chromium/net/quic/core/quic_spdy_stream_test.cc index 0e45dea119a..04d32fc7ccf 100644 --- a/chromium/net/quic/core/quic_spdy_stream_test.cc +++ b/chromium/net/quic/core/quic_spdy_stream_test.cc @@ -440,7 +440,6 @@ TEST_P(QuicSpdyStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) { // Stream receives enough data to fill a fraction of the receive window. string body(kWindow / 3, 'a'); - auto headers = AsHeaderList(headers_); ProcessHeaders(false, headers_); QuicStreamFrame frame1(kClientDataStreamId1, false, 0, StringPiece(body)); @@ -679,14 +678,51 @@ TEST_P(QuicSpdyStreamTest, ReceivingTrailersViaHeaderList) { EXPECT_TRUE(stream_->IsDoneReading()); } +TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithOffset) { + // Test that when receiving trailing headers with an offset before response + // body, stream is closed at the right offset. + Initialize(kShouldProcessData); + + // Receive initial headers. + QuicHeaderList headers = ProcessHeaders(false, headers_); + stream_->ConsumeHeaderList(); + + const string body = "this is the body"; + // Receive trailing headers. + SpdyHeaderBlock trailers_block; + trailers_block["key1"] = "value1"; + trailers_block["key2"] = "value2"; + trailers_block["key3"] = "value3"; + trailers_block[kFinalOffsetHeaderKey] = + QuicTextUtils::Uint64ToString(body.size()); + + QuicHeaderList trailers = ProcessHeaders(true, trailers_block); + + // The trailers should be decompressed, and readable from the stream. + EXPECT_TRUE(stream_->trailers_decompressed()); + + // The final offset trailer will be consumed by QUIC. + trailers_block.erase(kFinalOffsetHeaderKey); + EXPECT_EQ(trailers_block, stream_->received_trailers()); + + // Consuming the trailers erases them from the stream. + stream_->MarkTrailersConsumed(); + EXPECT_TRUE(stream_->FinishedReadingTrailers()); + + EXPECT_FALSE(stream_->IsDoneReading()); + // Receive and consume body. + QuicStreamFrame frame(kClientDataStreamId1, /*fin=*/false, 0, body); + stream_->OnStreamFrame(frame); + EXPECT_EQ(body, stream_->data()); + EXPECT_TRUE(stream_->IsDoneReading()); +} + TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutOffset) { // Test that receiving trailers without a final offset field is an error. Initialize(kShouldProcessData); // Receive initial headers. - auto headers = AsHeaderList(headers_); - stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(), - headers); + ProcessHeaders(false, headers_); stream_->ConsumeHeaderList(); const string body = "this is the body"; @@ -728,12 +764,13 @@ TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutFin) { trailers.uncompressed_header_bytes(), trailers); } -TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterFin) { - // If Trailers are sent, neither Headers nor Body should contain a FIN. +TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterHeadersWithFin) { + // If headers are received with a FIN, no trailers should then arrive. Initialize(kShouldProcessData); // Receive initial headers with FIN set. ProcessHeaders(true, headers_); + stream_->ConsumeHeaderList(); // Receive trailing headers after FIN already received. SpdyHeaderBlock trailers_block; @@ -749,6 +786,7 @@ TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterBodyWithFin) { // Receive initial headers without FIN set. ProcessHeaders(false, headers_); + stream_->ConsumeHeaderList(); // Receive body data, with FIN. QuicStreamFrame frame(kClientDataStreamId1, /*fin=*/true, 0, "body"); @@ -762,45 +800,6 @@ TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterBodyWithFin) { ProcessHeaders(false, trailers_block); } -TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithOffset) { - // Test that when receiving trailing headers with an offset before response - // body, stream is closed at the right offset. - Initialize(kShouldProcessData); - - // Receive initial headers. - QuicHeaderList headers = ProcessHeaders(false, headers_); - stream_->ConsumeHeaderList(); - - const string body = "this is the body"; - // Receive trailing headers. - SpdyHeaderBlock trailers_block; - trailers_block["key1"] = "value1"; - trailers_block["key2"] = "value2"; - trailers_block["key3"] = "value3"; - trailers_block[kFinalOffsetHeaderKey] = - QuicTextUtils::Uint64ToString(body.size()); - - QuicHeaderList trailers = ProcessHeaders(true, trailers_block); - - // The trailers should be decompressed, and readable from the stream. - EXPECT_TRUE(stream_->trailers_decompressed()); - - // The final offset trailer will be consumed by QUIC. - trailers_block.erase(kFinalOffsetHeaderKey); - EXPECT_EQ(trailers_block, stream_->received_trailers()); - - // Consuming the trailers erases them from the stream. - stream_->MarkTrailersConsumed(); - EXPECT_TRUE(stream_->FinishedReadingTrailers()); - - EXPECT_FALSE(stream_->IsDoneReading()); - // Receive and consume body. - QuicStreamFrame frame(kClientDataStreamId1, /*fin=*/false, 0, body); - stream_->OnStreamFrame(frame); - EXPECT_EQ(body, stream_->data()); - EXPECT_TRUE(stream_->IsDoneReading()); -} - TEST_P(QuicSpdyStreamTest, ClosingStreamWithNoTrailers) { // Verify that a stream receiving headers, body, and no trailers is correctly // marked as done reading on consumption of headers and body. diff --git a/chromium/net/quic/core/quic_stream.cc b/chromium/net/quic/core/quic_stream.cc index 04bfec23a54..13df51088ca 100644 --- a/chromium/net/quic/core/quic_stream.cc +++ b/chromium/net/quic/core/quic_stream.cc @@ -4,10 +4,8 @@ #include "net/quic/core/quic_stream.h" -#include "net/quic/core/quic_flags.h" #include "net/quic/core/quic_flow_controller.h" #include "net/quic/core/quic_session.h" -#include "net/quic/core/quic_write_blocked_list.h" #include "net/quic/platform/api/quic_bug_tracker.h" #include "net/quic/platform/api/quic_logging.h" @@ -72,7 +70,10 @@ QuicStream::QuicStream(QuicStreamId id, QuicSession* session) perspective_, GetReceivedFlowControlWindow(session), GetInitialStreamFlowControlWindowToSend(session), - session_->flow_controller()->auto_tune_receive_window()), + session_->flow_controller()->auto_tune_receive_window(), + session_->flow_control_invariant() + ? session_->flow_controller() + : nullptr), connection_flow_controller_(session_->flow_controller()), stream_contributes_to_connection_flow_control_(true), busy_counter_(0) { @@ -274,8 +275,8 @@ QuicConsumedData QuicStream::WritevData( bool fin, QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { if (write_side_closed_) { - QUIC_DLOG(ERROR) << ENDPOINT - << "Attempt to write when the write side is closed"; + QUIC_DLOG(ERROR) << ENDPOINT << "Stream " << id() + << "attempting to write when the write side is closed"; return QuicConsumedData(0, false); } @@ -347,6 +348,9 @@ QuicConsumedData QuicStream::WritevData( } else { session_->MarkConnectionLevelWriteBlocked(id()); } + if (consumed_data.bytes_consumed > 0 || consumed_data.fin_consumed) { + busy_counter_ = 0; + } return consumed_data; } @@ -369,7 +373,7 @@ void QuicStream::CloseReadSide() { sequencer_.ReleaseBuffer(); if (write_side_closed_) { - QUIC_DLOG(INFO) << ENDPOINT << "Closing stream: " << id(); + QUIC_DLOG(INFO) << ENDPOINT << "Closing stream " << id(); session_->CloseStream(id()); } } @@ -382,7 +386,7 @@ void QuicStream::CloseWriteSide() { write_side_closed_ = true; if (read_side_closed_) { - QUIC_DLOG(INFO) << ENDPOINT << "Closing stream: " << id(); + QUIC_DLOG(INFO) << ENDPOINT << "Closing stream " << id(); session_->CloseStream(id()); } } diff --git a/chromium/net/quic/core/quic_stream.h b/chromium/net/quic/core/quic_stream.h index 5e5cfb0ccb1..553f6ba76bc 100644 --- a/chromium/net/quic/core/quic_stream.h +++ b/chromium/net/quic/core/quic_stream.h @@ -17,10 +17,8 @@ #ifndef NET_QUIC_CORE_QUIC_STREAM_H_ #define NET_QUIC_CORE_QUIC_STREAM_H_ -#include <stddef.h> -#include <stdint.h> -#include <sys/types.h> - +#include <cstddef> +#include <cstdint> #include <list> #include <string> @@ -315,7 +313,8 @@ class QUIC_EXPORT_PRIVATE QuicStream { // limited). bool stream_contributes_to_connection_flow_control_; - // For debugging only, used for busy loop check. + // A counter incremented when OnCanWrite() is called and no progress is made. + // For debugging only. size_t busy_counter_; DISALLOW_COPY_AND_ASSIGN(QuicStream); diff --git a/chromium/net/quic/core/quic_stream_sequencer.cc b/chromium/net/quic/core/quic_stream_sequencer.cc index 941a670e1d5..1196424b314 100644 --- a/chromium/net/quic/core/quic_stream_sequencer.cc +++ b/chromium/net/quic/core/quic_stream_sequencer.cc @@ -9,8 +9,6 @@ #include <string> #include <utility> -#include "base/format_macros.h" -#include "net/quic/core/quic_flags.h" #include "net/quic/core/quic_packets.h" #include "net/quic/core/quic_stream.h" #include "net/quic/core/quic_stream_sequencer_buffer.h" diff --git a/chromium/net/quic/core/quic_stream_sequencer.h b/chromium/net/quic/core/quic_stream_sequencer.h index e19da1b3724..9770bccc804 100644 --- a/chromium/net/quic/core/quic_stream_sequencer.h +++ b/chromium/net/quic/core/quic_stream_sequencer.h @@ -5,8 +5,7 @@ #ifndef NET_QUIC_CORE_QUIC_STREAM_SEQUENCER_H_ #define NET_QUIC_CORE_QUIC_STREAM_SEQUENCER_H_ -#include <stddef.h> - +#include <cstddef> #include <map> #include "base/macros.h" diff --git a/chromium/net/quic/core/quic_stream_sequencer_buffer.cc b/chromium/net/quic/core/quic_stream_sequencer_buffer.cc index 4e9aaf1c4be..210bf56bd5d 100644 --- a/chromium/net/quic/core/quic_stream_sequencer_buffer.cc +++ b/chromium/net/quic/core/quic_stream_sequencer_buffer.cc @@ -508,8 +508,7 @@ size_t QuicStreamSequencerBuffer::NextBlockToRead() const { bool QuicStreamSequencerBuffer::RetireBlockIfEmpty(size_t block_index) { DCHECK(ReadableBytes() == 0 || GetInBlockOffset(total_bytes_read_) == 0) << "RetireBlockIfEmpty() should only be called when advancing to next " - "block" - " or a gap has been reached."; + << "block or a gap has been reached."; // If the whole buffer becomes empty, the last piece of data has been read. if (Empty()) { return RetireBlock(block_index); diff --git a/chromium/net/quic/core/quic_stream_sequencer_buffer.h b/chromium/net/quic/core/quic_stream_sequencer_buffer.h index 22d2bebea1b..14d10147c6c 100644 --- a/chromium/net/quic/core/quic_stream_sequencer_buffer.h +++ b/chromium/net/quic/core/quic_stream_sequencer_buffer.h @@ -5,8 +5,7 @@ #ifndef NET_QUIC_CORE_QUIC_STREAM_SEQUENCER_BUFFER_H_ #define NET_QUIC_CORE_QUIC_STREAM_SEQUENCER_BUFFER_H_ -// QuicStreamSequencerBuffer implements QuicStreamSequencerBufferInterface. -// It is a circular stream buffer with random write and +// QuicStreamSequencerBuffer is a circular stream buffer with random write and // in-sequence read. It consists of a vector of pointers pointing // to memory blocks created as needed and a list of Gaps to indicate // the missing data between the data already written into the buffer. @@ -60,8 +59,7 @@ // size_t consumed = consume_iovs(iovs, iov_count); // buffer.MarkConsumed(consumed); -#include <stddef.h> - +#include <cstddef> #include <functional> #include <list> #include <memory> @@ -221,12 +219,10 @@ class QUIC_EXPORT_PRIVATE QuicStreamSequencerBuffer { // should be removed from the map. void UpdateFrameArrivalMap(QuicStreamOffset offset); - // Return |gaps_| as a std::string: [1024, 1500) [1800, 2048)... for - // debugging. + // Return |gaps_| as a string: [1024, 1500) [1800, 2048)... for debugging. std::string GapsDebugString(); - // Return all received frames as a std::string in same format as - // GapsDebugString(); + // Return all received frames as a string in same format as GapsDebugString(); std::string ReceivedFramesDebugString(); // The maximum total capacity of this buffer in byte, as constructed. diff --git a/chromium/net/quic/core/quic_stream_sequencer_buffer_test.cc b/chromium/net/quic/core/quic_stream_sequencer_buffer_test.cc index 25de41f6b99..e3be181e0c4 100644 --- a/chromium/net/quic/core/quic_stream_sequencer_buffer_test.cc +++ b/chromium/net/quic/core/quic_stream_sequencer_buffer_test.cc @@ -1,6 +1,7 @@ // Copyright (c) 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. + #include "net/quic/core/quic_stream_sequencer_buffer.h" #include <algorithm> diff --git a/chromium/net/quic/core/quic_stream_sequencer_test.cc b/chromium/net/quic/core/quic_stream_sequencer_test.cc index 0e04007bb0e..a7b64b5cbd3 100644 --- a/chromium/net/quic/core/quic_stream_sequencer_test.cc +++ b/chromium/net/quic/core/quic_stream_sequencer_test.cc @@ -10,8 +10,6 @@ #include <utility> #include <vector> -#include "net/base/ip_endpoint.h" -#include "net/quic/core/quic_flags.h" #include "net/quic/core/quic_stream.h" #include "net/quic/core/quic_utils.h" #include "net/quic/platform/api/quic_logging.h" @@ -401,7 +399,7 @@ class QuicSequencerRandomTest : public QuicStreamSequencerTest { QuicSequencerRandomTest() { uint64_t seed = QuicRandom::GetInstance()->RandUint64(); - VLOG(1) << "**** The current seed is " << seed << " ****"; + QUIC_LOG(INFO) << "**** The current seed is " << seed << " ****"; random_.set_seed(seed); CreateFrames(); diff --git a/chromium/net/quic/core/quic_stream_test.cc b/chromium/net/quic/core/quic_stream_test.cc index 99cc0532536..d8c91c9f36e 100644 --- a/chromium/net/quic/core/quic_stream_test.cc +++ b/chromium/net/quic/core/quic_stream_test.cc @@ -167,11 +167,10 @@ class QuicStreamTest : public ::testing::TestWithParam<bool> { TEST_F(QuicStreamTest, WriteAllData) { Initialize(kShouldProcessData); - size_t length = - 1 + QuicPacketCreator::StreamFramePacketOverhead( - connection_->version(), PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, !kIncludePathId, !kIncludeDiversificationNonce, - PACKET_6BYTE_PACKET_NUMBER, 0u); + size_t length = 1 + QuicPacketCreator::StreamFramePacketOverhead( + connection_->version(), PACKET_8BYTE_CONNECTION_ID, + !kIncludeVersion, !kIncludeDiversificationNonce, + PACKET_6BYTE_PACKET_NUMBER, 0u); connection_->SetMaxPacketLength(length); EXPECT_CALL(*session_, WritevData(stream_, kTestStreamId, _, _, _, _)) @@ -242,11 +241,10 @@ TEST_F(QuicStreamTest, WriteOrBufferData) { Initialize(kShouldProcessData); EXPECT_FALSE(HasWriteBlockedStreams()); - size_t length = - 1 + QuicPacketCreator::StreamFramePacketOverhead( - connection_->version(), PACKET_8BYTE_CONNECTION_ID, - !kIncludeVersion, !kIncludePathId, !kIncludeDiversificationNonce, - PACKET_6BYTE_PACKET_NUMBER, 0u); + size_t length = 1 + QuicPacketCreator::StreamFramePacketOverhead( + connection_->version(), PACKET_8BYTE_CONNECTION_ID, + !kIncludeVersion, !kIncludeDiversificationNonce, + PACKET_6BYTE_PACKET_NUMBER, 0u); connection_->SetMaxPacketLength(length); EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) diff --git a/chromium/net/quic/core/quic_sustained_bandwidth_recorder.h b/chromium/net/quic/core/quic_sustained_bandwidth_recorder.h index 63bf4587fec..4af85ed9f26 100644 --- a/chromium/net/quic/core/quic_sustained_bandwidth_recorder.h +++ b/chromium/net/quic/core/quic_sustained_bandwidth_recorder.h @@ -5,7 +5,7 @@ #ifndef NET_QUIC_CORE_QUIC_SUSTAINED_BANDWIDTH_RECORDER_H_ #define NET_QUIC_CORE_QUIC_SUSTAINED_BANDWIDTH_RECORDER_H_ -#include <stdint.h> +#include <cstdint> #include "base/macros.h" #include "net/quic/core/quic_bandwidth.h" diff --git a/chromium/net/quic/core/quic_time.cc b/chromium/net/quic/core/quic_time.cc index d1cfbafcdcb..af761929f75 100644 --- a/chromium/net/quic/core/quic_time.cc +++ b/chromium/net/quic/core/quic_time.cc @@ -8,9 +8,8 @@ #include <cstdlib> #include <limits> -#include "base/strings/stringprintf.h" +#include "net/quic/platform/api/quic_str_cat.h" -using base::StringPrintf; using std::string; namespace net { @@ -24,12 +23,12 @@ string QuicTime::Delta::ToDebugValue() const { // For debugging purposes, always display the value with the highest precision // available. if (absolute_value > one_s && absolute_value % one_s == 0) { - return StringPrintf("%" PRId64 "s", time_offset_ / one_s); + return QuicStringPrintf("%" PRId64 "s", time_offset_ / one_s); } if (absolute_value > one_ms && absolute_value % one_ms == 0) { - return StringPrintf("%" PRId64 "ms", time_offset_ / one_ms); + return QuicStringPrintf("%" PRId64 "ms", time_offset_ / one_ms); } - return StringPrintf("%" PRId64 "us", time_offset_); + return QuicStringPrintf("%" PRId64 "us", time_offset_); } uint64_t QuicWallTime::ToUNIXSeconds() const { diff --git a/chromium/net/quic/core/quic_time.h b/chromium/net/quic/core/quic_time.h index ee883bfcfe0..ee4a38c988f 100644 --- a/chromium/net/quic/core/quic_time.h +++ b/chromium/net/quic/core/quic_time.h @@ -11,9 +11,9 @@ #ifndef NET_QUIC_CORE_QUIC_TIME_H_ #define NET_QUIC_CORE_QUIC_TIME_H_ -#include <stdint.h> - #include <cmath> +#include <cstdint> +#include <limits> #include <ostream> #include "base/compiler_specific.h" diff --git a/chromium/net/quic/core/quic_unacked_packet_map.cc b/chromium/net/quic/core/quic_unacked_packet_map.cc index d5456392bde..62a687c7d3b 100644 --- a/chromium/net/quic/core/quic_unacked_packet_map.cc +++ b/chromium/net/quic/core/quic_unacked_packet_map.cc @@ -4,7 +4,6 @@ #include "net/quic/core/quic_unacked_packet_map.h" -#include "base/stl_util.h" #include "net/quic/core/quic_connection_stats.h" #include "net/quic/core/quic_utils.h" #include "net/quic/platform/api/quic_bug_tracker.h" diff --git a/chromium/net/quic/core/quic_utils.cc b/chromium/net/quic/core/quic_utils.cc index cf516126e85..861ee3d62c6 100644 --- a/chromium/net/quic/core/quic_utils.cc +++ b/chromium/net/quic/core/quic_utils.cc @@ -4,10 +4,8 @@ #include "net/quic/core/quic_utils.h" -#include <ctype.h> -#include <stdint.h> - #include <algorithm> +#include <cstdint> #include <vector> #include "base/containers/adapters.h" diff --git a/chromium/net/quic/core/quic_version_manager.cc b/chromium/net/quic/core/quic_version_manager.cc index f266f0d098b..02730158006 100644 --- a/chromium/net/quic/core/quic_version_manager.cc +++ b/chromium/net/quic/core/quic_version_manager.cc @@ -10,7 +10,8 @@ namespace net { QuicVersionManager::QuicVersionManager(QuicVersionVector supported_versions) - : enable_version_37_(FLAGS_quic_reloadable_flag_quic_enable_version_37), + : enable_version_38_(FLAGS_quic_enable_version_38), + enable_version_37_(FLAGS_quic_reloadable_flag_quic_enable_version_37), enable_version_36_(FLAGS_quic_reloadable_flag_quic_enable_version_36_v3), disable_version_34_(FLAGS_quic_reloadable_flag_quic_disable_version_34), allowed_supported_versions_(supported_versions), @@ -25,11 +26,13 @@ const QuicVersionVector& QuicVersionManager::GetSupportedVersions() { } void QuicVersionManager::MaybeRefilterSupportedVersions() { - if (enable_version_37_ != FLAGS_quic_reloadable_flag_quic_enable_version_37 || + if (enable_version_38_ != FLAGS_quic_enable_version_38 || + enable_version_37_ != FLAGS_quic_reloadable_flag_quic_enable_version_37 || enable_version_36_ != FLAGS_quic_reloadable_flag_quic_enable_version_36_v3 || disable_version_34_ != FLAGS_quic_reloadable_flag_quic_disable_version_34) { + enable_version_38_ = FLAGS_quic_enable_version_38; enable_version_37_ = FLAGS_quic_reloadable_flag_quic_enable_version_37; enable_version_36_ = FLAGS_quic_reloadable_flag_quic_enable_version_36_v3; disable_version_34_ = FLAGS_quic_reloadable_flag_quic_disable_version_34; diff --git a/chromium/net/quic/core/quic_version_manager.h b/chromium/net/quic/core/quic_version_manager.h index 89b8c79694d..c1afef5d750 100644 --- a/chromium/net/quic/core/quic_version_manager.h +++ b/chromium/net/quic/core/quic_version_manager.h @@ -31,6 +31,8 @@ class QUIC_EXPORT_PRIVATE QuicVersionManager { } private: + // FLAGS_quic_enable_version_38 + bool enable_version_38_; // FLAGS_quic_reloadable_flag_quic_enable_version_37 bool enable_version_37_; // FLAGS_quic_reloadable_flag_quic_enable_version_36_v3 diff --git a/chromium/net/quic/core/quic_version_manager_test.cc b/chromium/net/quic/core/quic_version_manager_test.cc index 52ec489ae9c..22faf092e4c 100644 --- a/chromium/net/quic/core/quic_version_manager_test.cc +++ b/chromium/net/quic/core/quic_version_manager_test.cc @@ -16,6 +16,7 @@ namespace { TEST(QuicVersionManagerTest, QuicVersionManager) { QuicFlagSaver flags; + FLAGS_quic_enable_version_38 = false; FLAGS_quic_reloadable_flag_quic_enable_version_36_v3 = false; FLAGS_quic_reloadable_flag_quic_enable_version_37 = false; FLAGS_quic_reloadable_flag_quic_disable_version_34 = false; @@ -40,13 +41,24 @@ TEST(QuicVersionManagerTest, QuicVersionManager) { EXPECT_EQ(QUIC_VERSION_35, manager.GetSupportedVersions()[2]); EXPECT_EQ(QUIC_VERSION_34, manager.GetSupportedVersions()[3]); + FLAGS_quic_enable_version_38 = true; + EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()), + manager.GetSupportedVersions()); + ASSERT_EQ(5u, manager.GetSupportedVersions().size()); + EXPECT_EQ(QUIC_VERSION_38, manager.GetSupportedVersions()[0]); + EXPECT_EQ(QUIC_VERSION_37, manager.GetSupportedVersions()[1]); + EXPECT_EQ(QUIC_VERSION_36, manager.GetSupportedVersions()[2]); + EXPECT_EQ(QUIC_VERSION_35, manager.GetSupportedVersions()[3]); + EXPECT_EQ(QUIC_VERSION_34, manager.GetSupportedVersions()[4]); + FLAGS_quic_reloadable_flag_quic_disable_version_34 = true; EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()), manager.GetSupportedVersions()); - ASSERT_EQ(3u, manager.GetSupportedVersions().size()); - EXPECT_EQ(QUIC_VERSION_37, manager.GetSupportedVersions()[0]); - EXPECT_EQ(QUIC_VERSION_36, manager.GetSupportedVersions()[1]); - EXPECT_EQ(QUIC_VERSION_35, manager.GetSupportedVersions()[2]); + ASSERT_EQ(4u, manager.GetSupportedVersions().size()); + EXPECT_EQ(QUIC_VERSION_38, manager.GetSupportedVersions()[0]); + EXPECT_EQ(QUIC_VERSION_37, manager.GetSupportedVersions()[1]); + EXPECT_EQ(QUIC_VERSION_36, manager.GetSupportedVersions()[2]); + EXPECT_EQ(QUIC_VERSION_35, manager.GetSupportedVersions()[3]); } } // namespace diff --git a/chromium/net/quic/core/quic_versions.cc b/chromium/net/quic/core/quic_versions.cc index 0eb2b6d5c4b..8705df3410a 100644 --- a/chromium/net/quic/core/quic_versions.cc +++ b/chromium/net/quic/core/quic_versions.cc @@ -4,7 +4,6 @@ #include "net/quic/core/quic_versions.h" -#include "base/memory/ptr_util.h" #include "base/strings/string_piece.h" #include "net/quic/core/quic_error_codes.h" #include "net/quic/core/quic_flags.h" @@ -33,7 +32,13 @@ QuicVersionVector FilterSupportedVersions(QuicVersionVector versions) { QuicVersionVector filtered_versions(versions.size()); filtered_versions.clear(); // Guaranteed by spec not to change capacity. for (QuicVersion version : versions) { - if (version == QUIC_VERSION_37) { + if (version == QUIC_VERSION_38) { + if (FLAGS_quic_enable_version_38 && + FLAGS_quic_reloadable_flag_quic_enable_version_37 && + FLAGS_quic_reloadable_flag_quic_enable_version_36_v3) { + filtered_versions.push_back(version); + } + } else if (version == QUIC_VERSION_37) { if (FLAGS_quic_reloadable_flag_quic_enable_version_37 && FLAGS_quic_reloadable_flag_quic_enable_version_36_v3) { filtered_versions.push_back(version); @@ -74,6 +79,8 @@ QuicTag QuicVersionToQuicTag(const QuicVersion version) { return MakeQuicTag('Q', '0', '3', '6'); case QUIC_VERSION_37: return MakeQuicTag('Q', '0', '3', '7'); + case QUIC_VERSION_38: + return MakeQuicTag('Q', '0', '3', '8'); default: // This shold be an ERROR because we should never attempt to convert an // invalid QuicVersion to be written to the wire. @@ -104,6 +111,7 @@ string QuicVersionToString(const QuicVersion version) { RETURN_STRING_LITERAL(QUIC_VERSION_35); RETURN_STRING_LITERAL(QUIC_VERSION_36); RETURN_STRING_LITERAL(QUIC_VERSION_37); + RETURN_STRING_LITERAL(QUIC_VERSION_38); default: return "QUIC_VERSION_UNSUPPORTED"; } diff --git a/chromium/net/quic/core/quic_versions.h b/chromium/net/quic/core/quic_versions.h index 0ce3902ddfb..546f16b306c 100644 --- a/chromium/net/quic/core/quic_versions.h +++ b/chromium/net/quic/core/quic_versions.h @@ -29,6 +29,8 @@ enum QuicVersion { QUIC_VERSION_35 = 35, // Allows endpoints to independently set stream limit. QUIC_VERSION_36 = 36, // Add support to force HOL blocking. QUIC_VERSION_37 = 37, // Add perspective into null encryption. + QUIC_VERSION_38 = 38, // Experimental support for HTTP stream pairs + // and HPACK HoL avoidance. // IMPORTANT: if you are adding to this list, follow the instructions at // http://sites/quic/adding-and-removing-versions @@ -42,7 +44,8 @@ enum QuicVersion { // IMPORTANT: if you are adding to this list, follow the instructions at // http://sites/quic/adding-and-removing-versions static const QuicVersion kSupportedQuicVersions[] = { - QUIC_VERSION_37, QUIC_VERSION_36, QUIC_VERSION_35, QUIC_VERSION_34}; + QUIC_VERSION_38, QUIC_VERSION_37, QUIC_VERSION_36, QUIC_VERSION_35, + QUIC_VERSION_34}; typedef std::vector<QuicVersion> QuicVersionVector; diff --git a/chromium/net/quic/core/spdy_utils.cc b/chromium/net/quic/core/spdy_utils.cc index 11ca27585b5..a38d17657f4 100644 --- a/chromium/net/quic/core/spdy_utils.cc +++ b/chromium/net/quic/core/spdy_utils.cc @@ -7,17 +7,16 @@ #include <memory> #include <vector> -#include "base/stl_util.h" #include "net/quic/platform/api/quic_logging.h" +#include "net/quic/platform/api/quic_map_util.h" #include "net/quic/platform/api/quic_text_utils.h" +#include "net/quic/platform/api/quic_url_utils.h" #include "net/spdy/spdy_flags.h" #include "net/spdy/spdy_frame_builder.h" #include "net/spdy/spdy_framer.h" #include "net/spdy/spdy_protocol.h" -#include "url/gurl.h" using base::StringPiece; -using base::ContainsKey; using std::string; namespace net { @@ -43,7 +42,7 @@ bool SpdyUtils::ParseHeaders(const char* data, return false; // Headers were invalid. } - if (!ContainsKey(*headers, "content-length")) { + if (!QuicContainsKey(*headers, "content-length")) { return true; } @@ -62,8 +61,8 @@ bool SpdyUtils::ExtractContentLengthFromHeaders(int64_t* content_length, std::vector<StringPiece> values = QuicTextUtils::Split(content_length_header, '\0'); for (const StringPiece& value : values) { - int64_t new_value; - if (!base::StringToInt64(value, &new_value) || new_value < 0) { + uint64_t new_value; + if (!QuicTextUtils::StringToUint64(value, &new_value)) { QUIC_DLOG(ERROR) << "Content length was either unparseable or negative."; return false; @@ -72,7 +71,7 @@ bool SpdyUtils::ExtractContentLengthFromHeaders(int64_t* content_length, *content_length = new_value; continue; } - if (new_value != *content_length) { + if (new_value != static_cast<uint64_t>(*content_length)) { QUIC_DLOG(ERROR) << "Parsed content length " << new_value << " is " << "inconsistent with previously detected content length " @@ -100,7 +99,7 @@ bool SpdyUtils::ParseTrailers(const char* data, // response body bytes expected. auto it = trailers->find(kFinalOffsetHeaderKey); if (it == trailers->end() || - !base::StringToSizeT(it->second, final_byte_offset)) { + !QuicTextUtils::StringToSizeT(it->second, final_byte_offset)) { QUIC_DVLOG(1) << "Required key '" << kFinalOffsetHeaderKey << "' not present"; return false; @@ -121,7 +120,7 @@ bool SpdyUtils::ParseTrailers(const char* data, // TODO(rjshade): Check for other forbidden keys, following the HTTP/2 spec. } - QUIC_DVLOG(1) << "Successfully parsed Trailers."; + QUIC_DVLOG(1) << "Successfully parsed Trailers: " << trailers->DebugString(); return true; } @@ -144,7 +143,7 @@ bool SpdyUtils::CopyAndValidateHeaders(const QuicHeaderList& header_list, headers->AppendValueOrAddHeader(name, p.second); } - if (ContainsKey(*headers, "content-length") && + if (QuicContainsKey(*headers, "content-length") && !ExtractContentLengthFromHeaders(content_length, headers)) { return false; } @@ -162,10 +161,8 @@ bool SpdyUtils::CopyAndValidateTrailers(const QuicHeaderList& header_list, // Pull out the final offset pseudo header which indicates the number of // response body bytes expected. - int offset; if (!found_final_byte_offset && name == kFinalOffsetHeaderKey && - base::StringToInt(p.second, &offset)) { - *final_byte_offset = offset; + QuicTextUtils::StringToSizeT(p.second, final_byte_offset)) { found_final_byte_offset = true; continue; } @@ -229,13 +226,15 @@ string SpdyUtils::GetUrlFromHeaderBlock(const SpdyHeaderBlock& headers) { // static string SpdyUtils::GetHostNameFromHeaderBlock(const SpdyHeaderBlock& headers) { - return GURL(GetUrlFromHeaderBlock(headers)).host(); + // TODO(fayang): Consider just checking out the value of the ":authority" key + // in headers. + return QuicUrlUtils::HostName(GetUrlFromHeaderBlock(headers)); } // static bool SpdyUtils::UrlIsValid(const SpdyHeaderBlock& headers) { string url(GetUrlFromHeaderBlock(headers)); - return url != "" && GURL(url).is_valid(); + return url != "" && QuicUrlUtils::IsValidUrl(url); } // static diff --git a/chromium/net/quic/platform/api/quic_containers.h b/chromium/net/quic/platform/api/quic_containers.h new file mode 100644 index 00000000000..5c007e0f880 --- /dev/null +++ b/chromium/net/quic/platform/api/quic_containers.h @@ -0,0 +1,29 @@ +// Copyright (c) 2017 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 NET_QUIC_PLATFORM_API_QUIC_CONTAINERS_H_ +#define NET_QUIC_PLATFORM_API_QUIC_CONTAINERS_H_ + +#include "net/quic/platform/impl/quic_containers_impl.h" + +namespace net { + +// A map which offers insertion-ordered iteration. +template <typename Key, typename Value> +using QuicLinkedHashMap = QuicLinkedHashMapImpl<Key, Value>; + +// Used for maps that are typically small, then it is faster than (for example) +// hash_map which is optimized for large data sets. QuicSmallMap upgrades itself +// automatically to a QuicSmallMapImpl-specified map when it runs out of space. +template <typename Key, typename Value, int Size> +using QuicSmallMap = QuicSmallMapImpl<Key, Value, Size>; + +// A data structure used to represent a sorted set of non-empty, non-adjacent, +// and mutually disjoint intervals. +template <typename T> +using QuicIntervalSet = QuicIntervalSetImpl<T>; + +} // namespace net + +#endif // NET_QUIC_PLATFORM_API_QUIC_CONTAINERS_H_ diff --git a/chromium/net/quic/platform/api/quic_endian.h b/chromium/net/quic/platform/api/quic_endian.h new file mode 100644 index 00000000000..ae58b8b22e2 --- /dev/null +++ b/chromium/net/quic/platform/api/quic_endian.h @@ -0,0 +1,43 @@ +// Copyright 2017 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 NET_QUIC_PLATFORM_API_QUIC_ENDIAN_H_ +#define NET_QUIC_PLATFORM_API_QUIC_ENDIAN_H_ + +#include "net/quic/platform/impl/quic_endian_impl.h" + +namespace net { + +// Provide utility functions that convert from/to network order (big endian) +// to/from host order (can be either little or big endian depending on the +// platform). +class QuicEndian { + // Convert |x| from host order (can be either little or big endian depending + // on the platform) to network order (big endian). + static uint16_t HostToNet16(uint16_t x) { + return QuicEndianImpl::HostToNet16(x); + } + static uint32_t HostToNet32(uint32_t x) { + return QuicEndianImpl::HostToNet32(x); + } + static uint64_t HostToNet64(uint64_t x) { + return QuicEndianImpl::HostToNet64(x); + } + + // Convert |x| from network order (big endian) to host order (can be either + // little or big endian depending on the platform). + static uint16_t NetToHost16(uint16_t x) { + return QuicEndianImpl::NetToHost16(x); + } + static uint32_t NetToHost32(uint32_t x) { + return QuicEndianImpl::NetToHost32(x); + } + static uint64_t NetToHost64(uint64_t x) { + return QuicEndianImpl::NetToHost64(x); + } +}; + +} // namespace net + +#endif // NET_QUIC_PLATFORM_API_QUIC_ENDIAN_H_ diff --git a/chromium/net/quic/platform/api/quic_estimate_memory_usage.h b/chromium/net/quic/platform/api/quic_estimate_memory_usage.h new file mode 100644 index 00000000000..c7ed22efcd9 --- /dev/null +++ b/chromium/net/quic/platform/api/quic_estimate_memory_usage.h @@ -0,0 +1,21 @@ +// Copyright 2017 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 NET_QUIC_PLATFORM_API_QUIC_ESTIMATE_MEMORY_USAGE_H_ +#define NET_QUIC_PLATFORM_API_QUIC_ESTIMATE_MEMORY_USAGE_H_ + +#include <cstddef> + +#include "net/quic/platform/impl/quic_estimate_memory_usage_impl.h" + +namespace net { + +template <class T> +size_t QuicEstimateMemoryUsage(const T& object) { + return QuicEstimateMemoryUsageImpl(object); +} + +} // namespace net + +#endif // NET_QUIC_PLATFORM_API_QUIC_ESTIMATE_MEMORY_USAGE_H_ diff --git a/chromium/net/quic/platform/api/quic_flag_utils.h b/chromium/net/quic/platform/api/quic_flag_utils.h new file mode 100644 index 00000000000..1689f680159 --- /dev/null +++ b/chromium/net/quic/platform/api/quic_flag_utils.h @@ -0,0 +1,13 @@ +// Copyright (c) 2017 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 NET_QUIC_PLATFORM_API_QUIC_FLAG_UTILS_H_ +#define NET_QUIC_PLATFORM_API_QUIC_FLAG_UTILS_H_ + +#include "net/quic/platform/impl/quic_flag_utils_impl.h" + +#define QUIC_FLAG_COUNT QUIC_FLAG_COUNT_IMPL +#define QUIC_FLAG_COUNT_N QUIC_FLAG_COUNT_N_IMPL + +#endif // NET_QUIC_PLATFORM_API_QUIC_FLAG_UTILS_H_ diff --git a/chromium/net/quic/platform/api/quic_hostname_utils.cc b/chromium/net/quic/platform/api/quic_hostname_utils.cc new file mode 100644 index 00000000000..0feceebaf38 --- /dev/null +++ b/chromium/net/quic/platform/api/quic_hostname_utils.cc @@ -0,0 +1,28 @@ +// Copyright (c) 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/quic/platform/api/quic_hostname_utils.h" + +using base::StringPiece; +using std::string; + +namespace net { + +// static +bool QuicHostnameUtils::IsValidSNI(StringPiece sni) { + return QuicHostnameUtilsImpl::IsValidSNI(sni); +} + +// static +char* QuicHostnameUtils::NormalizeHostname(char* hostname) { + return QuicHostnameUtilsImpl::NormalizeHostname(hostname); +} + +// static +void QuicHostnameUtils::StringToQuicServerId(const string& str, + QuicServerId* out) { + QuicHostnameUtilsImpl::StringToQuicServerId(str, out); +} + +} // namespace net diff --git a/chromium/net/quic/platform/api/quic_hostname_utils.h b/chromium/net/quic/platform/api/quic_hostname_utils.h new file mode 100644 index 00000000000..14adea03b3c --- /dev/null +++ b/chromium/net/quic/platform/api/quic_hostname_utils.h @@ -0,0 +1,38 @@ +// Copyright (c) 2017 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 NET_QUIC_PLATFORM_API_QUIC_HOSTNAME_UTILS_H_ +#define NET_QUIC_PLATFORM_API_QUIC_HOSTNAME_UTILS_H_ + +#include "base/macros.h" +#include "net/quic/platform/api/quic_export.h" +#include "net/quic/platform/impl/quic_hostname_utils_impl.h" + +namespace net { + +class QuicServerId; + +class QUIC_EXPORT_PRIVATE QuicHostnameUtils { + public: + // Returns true if the sni is valid, false otherwise. + // (1) disallow IP addresses; + // (2) check that the hostname contains valid characters only; and + // (3) contains at least one dot. + static bool IsValidSNI(base::StringPiece sni); + + // Convert hostname to lowercase and remove the trailing '.'. + // WARNING: mutates |hostname| in place and returns |hostname|. + static char* NormalizeHostname(char* hostname); + + // Creates a QuicServerId from a string formatted in same manner as + // QuicServerId::ToString(). + static void StringToQuicServerId(const std::string& str, QuicServerId* out); + + private: + DISALLOW_COPY_AND_ASSIGN(QuicHostnameUtils); +}; + +} // namespace net + +#endif // NET_QUIC_PLATFORM_API_QUIC_HOSTNAME_UTILS_H_ diff --git a/chromium/net/quic/platform/api/quic_hostname_utils_test.cc b/chromium/net/quic/platform/api/quic_hostname_utils_test.cc new file mode 100644 index 00000000000..2c7e6c8e89a --- /dev/null +++ b/chromium/net/quic/platform/api/quic_hostname_utils_test.cc @@ -0,0 +1,64 @@ +// Copyright (c) 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/quic/platform/api/quic_hostname_utils.h" + +#include "testing/gtest/include/gtest/gtest.h" + +using std::string; + +namespace net { +namespace test { +namespace { + +TEST(QuicHostnameUtilsTest, IsValidSNI) { + // IP as SNI. + EXPECT_FALSE(QuicHostnameUtils::IsValidSNI("192.168.0.1")); + // SNI without any dot. + EXPECT_FALSE(QuicHostnameUtils::IsValidSNI("somedomain")); + // Invalid by RFC2396 but unfortunately domains of this form exist. + EXPECT_TRUE(QuicHostnameUtils::IsValidSNI("some_domain.com")); + // An empty string must be invalid otherwise the QUIC client will try sending + // it. + EXPECT_FALSE(QuicHostnameUtils::IsValidSNI("")); + + // Valid SNI + EXPECT_TRUE(QuicHostnameUtils::IsValidSNI("test.google.com")); +} + +TEST(QuicHostnameUtilsTest, NormalizeHostname) { + struct { + const char *input, *expected; + } tests[] = { + { + "www.google.com", "www.google.com", + }, + { + "WWW.GOOGLE.COM", "www.google.com", + }, + { + "www.google.com.", "www.google.com", + }, + { + "www.google.COM.", "www.google.com", + }, + { + "www.google.com..", "www.google.com", + }, + { + "www.google.com........", "www.google.com", + }, + }; + + for (size_t i = 0; i < arraysize(tests); ++i) { + char buf[256]; + snprintf(buf, sizeof(buf), "%s", tests[i].input); + EXPECT_EQ(string(tests[i].expected), + QuicHostnameUtils::NormalizeHostname(buf)); + } +} + +} // namespace +} // namespace test +} // namespace net diff --git a/chromium/net/quic/platform/api/quic_ip_address.h b/chromium/net/quic/platform/api/quic_ip_address.h index 9b10e8efe90..75b9f0c7ab6 100644 --- a/chromium/net/quic/platform/api/quic_ip_address.h +++ b/chromium/net/quic/platform/api/quic_ip_address.h @@ -17,6 +17,10 @@ class QUIC_EXPORT_PRIVATE QuicIpAddress { // implementation (platform dependent) of an IP address is in // QuicIpAddressImpl. public: + enum : size_t { + kIPv4AddressSize = QuicIpAddressImpl::kIPv4AddressSize, + kIPv6AddressSize = QuicIpAddressImpl::kIPv6AddressSize + }; static QuicIpAddress Loopback4(); static QuicIpAddress Loopback6(); static QuicIpAddress Any4(); diff --git a/chromium/net/quic/platform/api/quic_logging.h b/chromium/net/quic/platform/api/quic_logging.h index 5f840202802..5031e9f8ce1 100644 --- a/chromium/net/quic/platform/api/quic_logging.h +++ b/chromium/net/quic/platform/api/quic_logging.h @@ -14,10 +14,15 @@ #define QUIC_DVLOG(verbose_level) QUIC_DVLOG_IMPL(verbose_level) #define QUIC_DLOG(severity) QUIC_DLOG_IMPL(severity) +#define QUIC_DLOG_IF(severity, condition) QUIC_DLOG_IF_IMPL(severity, condition) #define QUIC_LOG(severity) QUIC_LOG_IMPL(severity) #define QUIC_LOG_FIRST_N(severity, n) QUIC_LOG_FIRST_N_IMPL(severity, n) #define QUIC_LOG_EVERY_N_SEC(severity, seconds) \ QUIC_LOG_EVERY_N_SEC_IMPL(severity, seconds) #define QUIC_LOG_IF(severity, condition) QUIC_LOG_IF_IMPL(severity, condition) +#define QUIC_PREDICT_FALSE(x) QUIC_PREDICT_FALSE_IMPL(x) + +#define QUIC_NOTREACHED() QUIC_NOTREACHED_IMPL() + #endif // NET_QUIC_PLATFORM_API_QUIC_LOGGING_H_ diff --git a/chromium/net/quic/platform/api/quic_map_util.h b/chromium/net/quic/platform/api/quic_map_util.h new file mode 100644 index 00000000000..fbf7e3cb290 --- /dev/null +++ b/chromium/net/quic/platform/api/quic_map_util.h @@ -0,0 +1,24 @@ +// Copyright (c) 2017 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 NET_QUIC_PLATFORM_API_QUIC_MAP_UTIL_H_ +#define NET_QUIC_PLATFORM_API_QUIC_MAP_UTIL_H_ + +#include "net/quic/platform/impl/quic_map_util_impl.h" + +namespace net { + +template <class Collection, class Key> +bool QuicContainsKey(const Collection& collection, const Key& key) { + return QuicContainsKeyImpl(collection, key); +} + +template <typename Collection, typename Value> +bool QuicContainsValue(const Collection& collection, const Value& value) { + return QuicContainsValueImpl(collection, value); +} + +} // namespace net + +#endif // NET_QUIC_PLATFORM_API_QUIC_MAP_UTIL_H_ diff --git a/chromium/net/quic/platform/api/quic_stack_trace.h b/chromium/net/quic/platform/api/quic_stack_trace.h new file mode 100644 index 00000000000..4134e6449ed --- /dev/null +++ b/chromium/net/quic/platform/api/quic_stack_trace.h @@ -0,0 +1,18 @@ +// Copyright (c) 2017 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 NET_QUIC_PLATFORM_API_QUIC_STACK_TRACE_H_ +#define NET_QUIC_PLATFORM_API_QUIC_STACK_TRACE_H_ + +#include "net/quic/platform/impl/quic_stack_trace_impl.h" + +namespace net { + +inline std::string QuicStackTrace() { + return QuicStackTraceImpl(); +} + +} // namespace net + +#endif // NET_QUIC_PLATFORM_API_QUIC_STACK_TRACE_H_ diff --git a/chromium/net/quic/platform/api/quic_str_cat.h b/chromium/net/quic/platform/api/quic_str_cat.h index cfbc67d6e77..ff60dac2654 100644 --- a/chromium/net/quic/platform/api/quic_str_cat.h +++ b/chromium/net/quic/platform/api/quic_str_cat.h @@ -14,6 +14,11 @@ inline std::string QuicStrCat(const Args&... args) { return std::move(QuicStrCatImpl(std::forward<const Args&>(args)...)); } +template <typename... Args> +inline std::string QuicStringPrintf(const Args&... args) { + return std::move(QuicStringPrintfImpl(std::forward<const Args&>(args)...)); +} + } // namespace net #endif // NET_QUIC_PLATFORM_API_QUIC_STR_CAT_H_ diff --git a/chromium/net/quic/platform/api/quic_text_utils.h b/chromium/net/quic/platform/api/quic_text_utils.h index 7eabe73ea4a..3509e9decb8 100644 --- a/chromium/net/quic/platform/api/quic_text_utils.h +++ b/chromium/net/quic/platform/api/quic_text_utils.h @@ -40,6 +40,24 @@ class QuicTextUtils { return QuicTextUtilsImpl::StringToUint64(in, out); } + // Returns true if |in| represents a valid int, and stores that value in + // |out|. + static bool StringToInt(base::StringPiece in, int* out) { + return QuicTextUtilsImpl::StringToInt(in, out); + } + + // Returns true if |in| represents a valid uint32, and stores that value in + // |out|. + static bool StringToUint32(base::StringPiece in, uint32_t* out) { + return QuicTextUtilsImpl::StringToUint32(in, out); + } + + // Returns true if |in| represents a valid size_t, and stores that value in + // |out|. + static bool StringToSizeT(base::StringPiece in, size_t* out) { + return QuicTextUtilsImpl::StringToSizeT(in, out); + } + // Returns a new string representing |in|. static std::string Uint64ToString(uint64_t in) { return QuicTextUtilsImpl::Uint64ToString(in); diff --git a/chromium/net/quic/platform/api/quic_text_utils_test.cc b/chromium/net/quic/platform/api/quic_text_utils_test.cc index 49efeb16182..758ad545548 100644 --- a/chromium/net/quic/platform/api/quic_text_utils_test.cc +++ b/chromium/net/quic/platform/api/quic_text_utils_test.cc @@ -43,23 +43,85 @@ TEST(QuicTextUtilsText, ToLower) { TEST(QuicTextUtilsText, RemoveLeadingAndTrailingWhitespace) { string input; - for (auto input : {"text", " text", " text", "text ", "text ", " text ", - " text ", "\r\n\ttext", "text\n\r\t"}) { + for (auto* input : {"text", " text", " text", "text ", "text ", " text ", + " text ", "\r\n\ttext", "text\n\r\t"}) { StringPiece piece(input); QuicTextUtils::RemoveLeadingAndTrailingWhitespace(&piece); EXPECT_EQ("text", piece); } } -TEST(QuicTextUtilsText, StringToUint64) { - uint64_t val = 0; - EXPECT_TRUE(QuicTextUtils::StringToUint64("123", &val)); - EXPECT_EQ(123u, val); - EXPECT_TRUE(QuicTextUtils::StringToUint64("1234", &val)); - EXPECT_EQ(1234u, val); - EXPECT_FALSE(QuicTextUtils::StringToUint64("", &val)); - EXPECT_FALSE(QuicTextUtils::StringToUint64("-123", &val)); - EXPECT_FALSE(QuicTextUtils::StringToUint64("-123.0", &val)); +TEST(QuicTextUtilsText, StringToNumbers) { + const string kMaxInt32Plus1 = "2147483648"; + const string kMinInt32Minus1 = "-2147483649"; + const string kMaxUint32Plus1 = "4294967296"; + + { + // StringToUint64 + uint64_t uint64_val = 0; + EXPECT_TRUE(QuicTextUtils::StringToUint64("123", &uint64_val)); + EXPECT_EQ(123u, uint64_val); + EXPECT_TRUE(QuicTextUtils::StringToUint64("1234", &uint64_val)); + EXPECT_EQ(1234u, uint64_val); + EXPECT_FALSE(QuicTextUtils::StringToUint64("", &uint64_val)); + EXPECT_FALSE(QuicTextUtils::StringToUint64("-123", &uint64_val)); + EXPECT_FALSE(QuicTextUtils::StringToUint64("-123.0", &uint64_val)); + EXPECT_TRUE(QuicTextUtils::StringToUint64(kMaxUint32Plus1, &uint64_val)); + EXPECT_EQ(4294967296u, uint64_val); + } + + { + // StringToint + int int_val = 0; + EXPECT_TRUE(QuicTextUtils::StringToInt("123", &int_val)); + EXPECT_EQ(123, int_val); + EXPECT_TRUE(QuicTextUtils::StringToInt("1234", &int_val)); + EXPECT_EQ(1234, int_val); + EXPECT_FALSE(QuicTextUtils::StringToInt("", &int_val)); + EXPECT_TRUE(QuicTextUtils::StringToInt("-123", &int_val)); + EXPECT_EQ(-123, int_val); + EXPECT_FALSE(QuicTextUtils::StringToInt("-123.0", &int_val)); + if (sizeof(int) > 4) { + EXPECT_TRUE(QuicTextUtils::StringToInt(kMinInt32Minus1, &int_val)); + EXPECT_EQ(-2147483649ll, int_val); + EXPECT_TRUE(QuicTextUtils::StringToInt(kMaxInt32Plus1, &int_val)); + EXPECT_EQ(2147483648ll, int_val); + } else { + EXPECT_FALSE(QuicTextUtils::StringToInt(kMinInt32Minus1, &int_val)); + EXPECT_FALSE(QuicTextUtils::StringToInt(kMaxInt32Plus1, &int_val)); + } + } + + { + // StringToUint32 + uint32_t uint32_val = 0; + EXPECT_TRUE(QuicTextUtils::StringToUint32("123", &uint32_val)); + EXPECT_EQ(123u, uint32_val); + EXPECT_TRUE(QuicTextUtils::StringToUint32("1234", &uint32_val)); + EXPECT_EQ(1234u, uint32_val); + EXPECT_FALSE(QuicTextUtils::StringToUint32("", &uint32_val)); + EXPECT_FALSE(QuicTextUtils::StringToUint32("-123", &uint32_val)); + EXPECT_FALSE(QuicTextUtils::StringToUint32("-123.0", &uint32_val)); + EXPECT_FALSE(QuicTextUtils::StringToUint32(kMaxUint32Plus1, &uint32_val)); + } + + { + // StringToSizeT + size_t size_t_val = 0; + EXPECT_TRUE(QuicTextUtils::StringToSizeT("123", &size_t_val)); + EXPECT_EQ(123u, size_t_val); + EXPECT_TRUE(QuicTextUtils::StringToSizeT("1234", &size_t_val)); + EXPECT_EQ(1234u, size_t_val); + EXPECT_FALSE(QuicTextUtils::StringToSizeT("", &size_t_val)); + EXPECT_FALSE(QuicTextUtils::StringToSizeT("-123", &size_t_val)); + EXPECT_FALSE(QuicTextUtils::StringToSizeT("-123.0", &size_t_val)); + if (sizeof(size_t) > 4) { + EXPECT_TRUE(QuicTextUtils::StringToSizeT(kMaxUint32Plus1, &size_t_val)); + EXPECT_EQ(4294967296ull, size_t_val); + } else { + EXPECT_FALSE(QuicTextUtils::StringToSizeT(kMaxUint32Plus1, &size_t_val)); + } + } } TEST(QuicTextUtilsText, Uint64ToString) { diff --git a/chromium/net/quic/platform/api/quic_url.cc b/chromium/net/quic/platform/api/quic_url.cc new file mode 100644 index 00000000000..950f9dd877e --- /dev/null +++ b/chromium/net/quic/platform/api/quic_url.cc @@ -0,0 +1,51 @@ +// Copyright (c) 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/quic/platform/api/quic_url.h" + +using base::StringPiece; +using std::string; + +namespace net { + +QuicUrl::QuicUrl(StringPiece url) : impl_(url) {} + +QuicUrl::QuicUrl(StringPiece url, StringPiece default_scheme) + : impl_(url, default_scheme) {} + +QuicUrl::QuicUrl(const QuicUrl& url) : impl_(url.impl()) {} + +bool QuicUrl::IsValid() const { + return impl_.IsValid(); +} + +string QuicUrl::ToString() const { + return impl_.ToStringIfValid(); +} + +string QuicUrl::HostPort() const { + return impl_.HostPort(); +} + +string QuicUrl::PathParamsQuery() const { + return impl_.PathParamsQuery(); +} + +string QuicUrl::host() const { + return impl_.host(); +} + +string QuicUrl::path() const { + return impl_.path(); +} + +string QuicUrl::scheme() const { + return impl_.scheme(); +} + +uint16_t QuicUrl::port() const { + return impl_.port(); +} + +} // namespace net diff --git a/chromium/net/quic/platform/api/quic_url.h b/chromium/net/quic/platform/api/quic_url.h new file mode 100644 index 00000000000..931fcbd0d9d --- /dev/null +++ b/chromium/net/quic/platform/api/quic_url.h @@ -0,0 +1,68 @@ +// Copyright (c) 2017 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 NET_QUIC_PLATFORM_API_QUIC_URL_H_ +#define NET_QUIC_PLATFORM_API_QUIC_URL_H_ + +#include "net/quic/platform/api/quic_export.h" +#include "net/quic/platform/impl/quic_url_impl.h" + +namespace net { + +// QuicUrl stores a representation of a URL. +class QUIC_EXPORT_PRIVATE QuicUrl { + public: + // Constructs an empty QuicUrl. + QuicUrl() = default; + + // Constructs a QuicUrl from the url string |url|. + // NOTE: If |url| doesn't have a scheme, it will have an empty scheme + // field. If that's not what you want, use the QuicUrlImpl(url, + // default_scheme) form below. + explicit QuicUrl(base::StringPiece url); + + // Constructs a QuicUrl from |url|, assuming that the scheme for the QuicUrl + // is |default_scheme| if there is no scheme specified in |url|. + QuicUrl(base::StringPiece url, base::StringPiece default_scheme); + + QuicUrl(const QuicUrl& url); + + // Returns false if any of these conditions occur: + // No scheme specified + // Host name too long (the maximum hostname length is platform-dependent) + // Invalid characters in host name, path or params + // Invalid port number (e.g. greater than 65535) + bool IsValid() const; + + // PLEASE NOTE: ToString(), HostPort(), PathParamsQuery(), scheme(), host(), + // path() and port() functions should be only called on a valid QuicUrl. + // Return values are platform-dependent if called on a invalid QuicUrl. + + // Returns full text of the QuicUrl. + std::string ToString() const; + + // Returns host:port. + // If the host is empty, it will return an empty string. + // If the host is an IPv6 address, it will be bracketed. + // If port is not present or is equal to default_port of scheme (e.g., port + // 80 for HTTP), it won't be returned. + std::string HostPort() const; + + // Returns a string assembles path, parameters and query. + std::string PathParamsQuery() const; + + std::string scheme() const; + std::string host() const; + std::string path() const; + uint16_t port() const; + + const QuicUrlImpl& impl() const { return impl_; } + + private: + QuicUrlImpl impl_; +}; + +} // namespace net + +#endif // NET_QUIC_PLATFORM_API_QUIC_URL_H_ diff --git a/chromium/net/quic/platform/api/quic_url_test.cc b/chromium/net/quic/platform/api/quic_url_test.cc new file mode 100644 index 00000000000..8f575c5616b --- /dev/null +++ b/chromium/net/quic/platform/api/quic_url_test.cc @@ -0,0 +1,154 @@ +// Copyright (c) 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/quic/platform/api/quic_url.h" + +#include "testing/gtest/include/gtest/gtest.h" + +using std::string; + +namespace net { +namespace test { +namespace { + +TEST(QuicUrlTest, Basic) { + // No scheme specified. + string url_str = "www.example.com"; + QuicUrl url(url_str); + EXPECT_FALSE(url.IsValid()); + + // scheme is HTTP. + url_str = "http://www.example.com"; + url = QuicUrl(url_str); + EXPECT_TRUE(url.IsValid()); + EXPECT_EQ("http://www.example.com/", url.ToString()); + EXPECT_EQ("http", url.scheme()); + EXPECT_EQ("www.example.com", url.HostPort()); + EXPECT_EQ("/", url.PathParamsQuery()); + EXPECT_EQ(80u, url.port()); + + // scheme is HTTPS. + url_str = "https://www.example.com:12345/path/to/resource?a=1&campaign=2"; + url = QuicUrl(url_str); + EXPECT_TRUE(url.IsValid()); + EXPECT_EQ("https://www.example.com:12345/path/to/resource?a=1&campaign=2", + url.ToString()); + EXPECT_EQ("https", url.scheme()); + EXPECT_EQ("www.example.com:12345", url.HostPort()); + EXPECT_EQ("/path/to/resource?a=1&campaign=2", url.PathParamsQuery()); + EXPECT_EQ(12345u, url.port()); + + // scheme is FTP. + url_str = "ftp://www.example.com"; + url = QuicUrl(url_str); + EXPECT_TRUE(url.IsValid()); + EXPECT_EQ("ftp://www.example.com/", url.ToString()); + EXPECT_EQ("ftp", url.scheme()); + EXPECT_EQ("www.example.com", url.HostPort()); + EXPECT_EQ("/", url.PathParamsQuery()); + EXPECT_EQ(21u, url.port()); +} + +TEST(QuicUrlTest, DefaultScheme) { + // Default scheme to HTTP. + string url_str = "www.example.com"; + QuicUrl url(url_str, "http"); + EXPECT_EQ("http://www.example.com/", url.ToString()); + EXPECT_EQ("http", url.scheme()); + + // URL already has a scheme specified. + url_str = "http://www.example.com"; + url = QuicUrl(url_str, "https"); + EXPECT_EQ("http://www.example.com/", url.ToString()); + EXPECT_EQ("http", url.scheme()); + + // Default scheme to FTP. + url_str = "www.example.com"; + url = QuicUrl(url_str, "ftp"); + EXPECT_EQ("ftp://www.example.com/", url.ToString()); + EXPECT_EQ("ftp", url.scheme()); +} + +TEST(QuicUrlTest, IsValid) { + string url_str = + "ftp://www.example.com:12345/path/to/resource?a=1&campaign=2"; + EXPECT_TRUE(QuicUrl(url_str).IsValid()); + + // Invalid characters in host name. + url_str = "https://www%.example.com:12345/path/to/resource?a=1&campaign=2"; + EXPECT_FALSE(QuicUrl(url_str).IsValid()); + + // Invalid characters in scheme. + url_str = "%http://www.example.com:12345/path/to/resource?a=1&campaign=2"; + EXPECT_FALSE(QuicUrl(url_str).IsValid()); + + // Host name too long. + string host(1024, 'a'); + url_str = "https://" + host; + EXPECT_FALSE(QuicUrl(url_str).IsValid()); + + // Invalid port number. + url_str = "https://www..example.com:123456/path/to/resource?a=1&campaign=2"; + EXPECT_FALSE(QuicUrl(url_str).IsValid()); +} + +TEST(QuicUrlTest, HostPort) { + string url_str = "http://www.example.com/"; + QuicUrl url(url_str); + EXPECT_EQ("www.example.com", url.HostPort()); + EXPECT_EQ("www.example.com", url.host()); + EXPECT_EQ(80u, url.port()); + + url_str = "http://www.example.com:80/"; + url = QuicUrl(url_str); + EXPECT_EQ("www.example.com", url.HostPort()); + EXPECT_EQ("www.example.com", url.host()); + EXPECT_EQ(80u, url.port()); + + url_str = "http://www.example.com:81/"; + url = QuicUrl(url_str); + EXPECT_EQ("www.example.com:81", url.HostPort()); + EXPECT_EQ("www.example.com", url.host()); + EXPECT_EQ(81u, url.port()); + + url_str = "https://192.168.1.1:443/"; + url = QuicUrl(url_str); + EXPECT_EQ("192.168.1.1", url.HostPort()); + EXPECT_EQ("192.168.1.1", url.host()); + EXPECT_EQ(443u, url.port()); + + url_str = "http://[2001::1]:80/"; + url = QuicUrl(url_str); + EXPECT_EQ("[2001::1]", url.HostPort()); + EXPECT_EQ("2001::1", url.host()); + EXPECT_EQ(80u, url.port()); + + url_str = "http://[2001::1]:81/"; + url = QuicUrl(url_str); + EXPECT_EQ("[2001::1]:81", url.HostPort()); + EXPECT_EQ("2001::1", url.host()); + EXPECT_EQ(81u, url.port()); +} + +TEST(QuicUrlTest, PathParamsQuery) { + string url_str = + "https://www.example.com:12345/path/to/resource?a=1&campaign=2"; + QuicUrl url(url_str); + EXPECT_EQ("/path/to/resource?a=1&campaign=2", url.PathParamsQuery()); + EXPECT_EQ("/path/to/resource", url.path()); + + url_str = "https://www.example.com/?"; + url = QuicUrl(url_str); + EXPECT_EQ("/?", url.PathParamsQuery()); + EXPECT_EQ("/", url.path()); + + url_str = "https://www.example.com/"; + url = QuicUrl(url_str); + EXPECT_EQ("/", url.PathParamsQuery()); + EXPECT_EQ("/", url.path()); +} + +} // namespace +} // namespace test +} // namespace net diff --git a/chromium/net/quic/platform/api/quic_url_utils.cc b/chromium/net/quic/platform/api/quic_url_utils.cc new file mode 100644 index 00000000000..4b2c33b561e --- /dev/null +++ b/chromium/net/quic/platform/api/quic_url_utils.cc @@ -0,0 +1,22 @@ +// Copyright (c) 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/quic/platform/api/quic_url_utils.h" + +using base::StringPiece; +using std::string; + +namespace net { + +// static +string QuicUrlUtils::HostName(StringPiece url) { + return QuicUrlUtilsImpl::HostName(url); +} + +// static +bool QuicUrlUtils::IsValidUrl(StringPiece url) { + return QuicUrlUtilsImpl::IsValidUrl(url); +} + +} // namespace net diff --git a/chromium/net/quic/platform/api/quic_url_utils.h b/chromium/net/quic/platform/api/quic_url_utils.h new file mode 100644 index 00000000000..022e041be99 --- /dev/null +++ b/chromium/net/quic/platform/api/quic_url_utils.h @@ -0,0 +1,30 @@ +// Copyright (c) 2017 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 NET_QUIC_PLATFORM_API_QUIC_URL_UTILS_H_ +#define NET_QUIC_PLATFORM_API_QUIC_URL_UTILS_H_ + +#include "base/macros.h" +#include "net/quic/platform/api/quic_export.h" +#include "net/quic/platform/impl/quic_url_utils_impl.h" + +namespace net { + +class QUIC_EXPORT_PRIVATE QuicUrlUtils { + public: + // Returns hostname, or empty std::string if missing. + static std::string HostName(base::StringPiece url); + + // Returns false if any of these conditions occur: (1) Host name too long; (2) + // Invalid characters in host name, path or params; (3) Invalid port number + // (e.g. greater than 65535). + static bool IsValidUrl(base::StringPiece url); + + private: + DISALLOW_COPY_AND_ASSIGN(QuicUrlUtils); +}; + +} // namespace net + +#endif // NET_QUIC_PLATFORM_API_QUIC_URL_UTILS_H_ diff --git a/chromium/net/quic/platform/impl/quic_bug_tracker_impl.h b/chromium/net/quic/platform/impl/quic_bug_tracker_impl.h index 16675042718..a0b0efd1acf 100644 --- a/chromium/net/quic/platform/impl/quic_bug_tracker_impl.h +++ b/chromium/net/quic/platform/impl/quic_bug_tracker_impl.h @@ -6,9 +6,6 @@ #include "net/quic/platform/api/quic_logging.h" -// For external QUIC, QUIC_BUG should be #defined to QUIC_LOG(DFATAL) and -// QUIC_BUG_IF(condition) to QUIC LOG_IF(DFATAL, condition) as client-side log -// rate limiting is less important and chrome doesn't QUIC_LOG_FIRST_N anyway. #define QUIC_BUG_IMPL QUIC_LOG(DFATAL) #define QUIC_BUG_IF_IMPL(condition) QUIC_LOG_IF(DFATAL, condition) diff --git a/chromium/net/quic/platform/impl/quic_containers_impl.h b/chromium/net/quic/platform/impl/quic_containers_impl.h new file mode 100644 index 00000000000..287b73b3216 --- /dev/null +++ b/chromium/net/quic/platform/impl/quic_containers_impl.h @@ -0,0 +1,33 @@ +// Copyright (c) 2017 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 NET_QUIC_PLATFORM_IMPL_QUIC_CONTAINERS_IMPL_H_ +#define NET_QUIC_PLATFORM_IMPL_QUIC_CONTAINERS_IMPL_H_ + +#include <unordered_map> + +#include "base/containers/small_map.h" +#include "net/base/interval_set.h" +#include "net/base/linked_hash_map.h" + +namespace net { + +// A map which offers insertion-ordered iteration. +template <typename Key, typename Value> +using QuicLinkedHashMapImpl = linked_hash_map<Key, Value>; + +// A map which is faster than (for example) hash_map for a certain number of +// unique key-value-pair elements, and upgrades itself to unordered_map when +// runs out of space. +template <typename Key, typename Value, int Size> +using QuicSmallMapImpl = base::SmallMap<std::unordered_map<Key, Value>, Size>; + +// A data structure used to represent a sorted set of non-empty, non-adjacent, +// and mutually disjoint intervals. +template <typename T> +using QuicIntervalSetImpl = IntervalSet<T>; + +} // namespace net + +#endif // NET_QUIC_PLATFORM_IMPL_QUIC_CONTAINERS_IMPL_H_ diff --git a/chromium/net/quic/platform/impl/quic_endian_impl.h b/chromium/net/quic/platform/impl/quic_endian_impl.h new file mode 100644 index 00000000000..4bcb3bb20a0 --- /dev/null +++ b/chromium/net/quic/platform/impl/quic_endian_impl.h @@ -0,0 +1,29 @@ +// Copyright 2017 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 NET_QUIC_PLATFORM_IMPL_QUIC_ENDIAN_IMPL_H_ +#define NET_QUIC_PLATFORM_IMPL_QUIC_ENDIAN_IMPL_H_ + +#include "base/sys_byteorder.h" + +namespace net { + +class QuicEndianImpl { + public: + // Convert |x| from host order (can be either little or big endian depending + // on the platform) to network order (big endian). + static uint16_t HostToNet16(uint16_t x) { return HostToNet16(x); } + static uint32_t HostToNet32(uint32_t x) { return HostToNet32(x); } + static uint64_t HostToNet64(uint64_t x) { return HostToNet64(x); } + + // Convert |x| from network order (big endian) to host order (can be either + // little or big endian depending on the platform). + static uint16_t NetToHost16(uint16_t x) { return NetToHost16(x); } + static uint32_t NetToHost32(uint32_t x) { return NetToHost32(x); } + static uint64_t NetToHost64(uint64_t x) { return NetToHost64(x); } +}; + +} // namespace net + +#endif // NET_QUIC_PLATFORM_IMPL_QUIC_ENDIAN_IMPL_H_ diff --git a/chromium/net/quic/platform/impl/quic_estimate_memory_usage_impl.h b/chromium/net/quic/platform/impl/quic_estimate_memory_usage_impl.h new file mode 100644 index 00000000000..fdfc6ce22f7 --- /dev/null +++ b/chromium/net/quic/platform/impl/quic_estimate_memory_usage_impl.h @@ -0,0 +1,21 @@ +// Copyright 2017 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 NET_QUIC_PLATFORM_IMPL_QUIC_ESTIMATE_MEMORY_USAGE_IMPL_H_ +#define NET_QUIC_PLATFORM_IMPL_QUIC_ESTIMATE_MEMORY_USAGE_IMPL_H_ + +#include <cstddef> + +#include "base/trace_event/memory_usage_estimator.h" + +namespace net { + +template <class T> +size_t QuicEstimateMemoryUsageImpl(const T& object) { + return base::trace_event::EstimateMemoryUsage(object); +} + +} // namespace net + +#endif // NET_QUIC_PLATFORM_IMPL_QUIC_ESTIMATE_MEMORY_USAGE_IMPL_H_ diff --git a/chromium/net/quic/platform/impl/quic_flag_utils_impl.h b/chromium/net/quic/platform/impl/quic_flag_utils_impl.h new file mode 100644 index 00000000000..52e710766d1 --- /dev/null +++ b/chromium/net/quic/platform/impl/quic_flag_utils_impl.h @@ -0,0 +1,15 @@ +// Copyright (c) 2017 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 NET_QUIC_PLATFORM_IMPL_QUIC_FLAG_UTILS_IMPL_H_ +#define NET_QUIC_PLATFORM_IMPL_QUIC_FLAG_UTILS_IMPL_H_ + +#define QUIC_FLAG_COUNT_IMPL(flag) \ + do { \ + } while (0) +#define QUIC_FLAG_COUNT_N_IMPL(flag, instance, total) \ + do { \ + } while (0) + +#endif // NET_QUIC_PLATFORM_IMPL_QUIC_FLAG_UTILS_IMPL_H_ diff --git a/chromium/net/quic/platform/impl/quic_hostname_utils_impl.cc b/chromium/net/quic/platform/impl/quic_hostname_utils_impl.cc new file mode 100644 index 00000000000..0dc81390348 --- /dev/null +++ b/chromium/net/quic/platform/impl/quic_hostname_utils_impl.cc @@ -0,0 +1,65 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/quic/platform/impl/quic_hostname_utils_impl.h" + +#include "net/base/url_util.h" +#include "url/gurl.h" +#include "url/url_canon.h" + +using base::StringPiece; +using std::string; + +namespace net { + +// static +bool QuicHostnameUtilsImpl::IsValidSNI(StringPiece sni) { + // TODO(rtenneti): Support RFC2396 hostname. + // NOTE: Microsoft does NOT enforce this spec, so if we throw away hostnames + // based on the above spec, we may be losing some hostnames that windows + // would consider valid. By far the most common hostname character NOT + // accepted by the above spec is '_'. + url::CanonHostInfo host_info; + string canonicalized_host(CanonicalizeHost(sni.as_string(), &host_info)); + return !host_info.IsIPAddress() && + IsCanonicalizedHostCompliant(canonicalized_host) && + sni.find_last_of('.') != string::npos; +} + +// static +char* QuicHostnameUtilsImpl::NormalizeHostname(char* hostname) { + url::CanonHostInfo host_info; + string host(CanonicalizeHost(hostname, &host_info)); + + // Walk backwards over the string, stopping at the first trailing dot. + size_t host_end = host.length(); + while (host_end != 0 && host[host_end - 1] == '.') { + host_end--; + } + + // Erase the trailing dots. + if (host_end != host.length()) { + host.erase(host_end, host.length() - host_end); + } + + memcpy(hostname, host.c_str(), host.length()); + hostname[host.length()] = '\0'; + + return hostname; +} + +// static +void QuicHostnameUtilsImpl::StringToQuicServerId(const string& str, + QuicServerId* out) { + GURL url(str); + if (!url.is_valid()) { + *out = QuicServerId(); + return; + } + *out = QuicServerId(HostPortPair::FromURL(url), url.path_piece() == "/private" + ? PRIVACY_MODE_ENABLED + : PRIVACY_MODE_DISABLED); +} + +} // namespace net diff --git a/chromium/net/quic/platform/impl/quic_hostname_utils_impl.h b/chromium/net/quic/platform/impl/quic_hostname_utils_impl.h new file mode 100644 index 00000000000..7e5cd1d39c1 --- /dev/null +++ b/chromium/net/quic/platform/impl/quic_hostname_utils_impl.h @@ -0,0 +1,37 @@ +// Copyright (c) 2013 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 NET_QUIC_PLATFORM_IMPL_QUIC_HOSTNAME_UTILS_IMPL_H_ +#define NET_QUIC_PLATFORM_IMPL_QUIC_HOSTNAME_UTILS_IMPL_H_ + +#include "base/macros.h" +#include "base/strings/string_piece.h" +#include "net/quic/core/quic_server_id.h" +#include "net/quic/platform/api/quic_export.h" + +namespace net { + +class QUIC_EXPORT_PRIVATE QuicHostnameUtilsImpl { + public: + // Returns true if the sni is valid, false otherwise. + // (1) disallow IP addresses; + // (2) check that the hostname contains valid characters only; and + // (3) contains at least one dot. + static bool IsValidSNI(base::StringPiece sni); + + // Convert hostname to lowercase and remove the trailing '.'. + // WARNING: mutates |hostname| in place and returns |hostname|. + static char* NormalizeHostname(char* hostname); + + // Creates a QuicServerId from a string formatted in same manner as + // QuicServerId::ToString(). + static void StringToQuicServerId(const std::string& str, QuicServerId* out); + + private: + DISALLOW_COPY_AND_ASSIGN(QuicHostnameUtilsImpl); +}; + +} // namespace net + +#endif // NET_QUIC_PLATFORM_IMPL_QUIC_HOSTNAME_UTILS_IMPL_H_ diff --git a/chromium/net/quic/platform/impl/quic_ip_address_impl.h b/chromium/net/quic/platform/impl/quic_ip_address_impl.h index c2b0d895afa..c9c2998fe62 100644 --- a/chromium/net/quic/platform/impl/quic_ip_address_impl.h +++ b/chromium/net/quic/platform/impl/quic_ip_address_impl.h @@ -15,6 +15,10 @@ namespace net { class QUIC_EXPORT_PRIVATE QuicIpAddressImpl { public: + enum : size_t { + kIPv4AddressSize = IPAddress::kIPv4AddressSize, + kIPv6AddressSize = IPAddress::kIPv6AddressSize + }; static QuicIpAddressImpl Loopback4(); static QuicIpAddressImpl Loopback6(); static QuicIpAddressImpl Any4(); diff --git a/chromium/net/quic/platform/impl/quic_logging_impl.h b/chromium/net/quic/platform/impl/quic_logging_impl.h index 000b20b95e1..d6e6cdc029c 100644 --- a/chromium/net/quic/platform/impl/quic_logging_impl.h +++ b/chromium/net/quic/platform/impl/quic_logging_impl.h @@ -11,6 +11,8 @@ #define QUIC_LOG_EVERY_N_SEC_IMPL(severity, seconds) QUIC_LOG_IMPL(severity) #define QUIC_LOG_FIRST_N_IMPL(severity, n) QUIC_LOG_IMPL(severity) #define QUIC_DLOG_IMPL(severity) QUIC_CHROMIUM_DLOG_##severity +#define QUIC_DLOG_IF_IMPL(severity, condition) \ + QUIC_CHROMIUM_DLOG_IF_##severity(condition) #define QUIC_LOG_IF_IMPL(severity, condition) \ QUIC_CHROMIUM_LOG_IF_##severity(condition) @@ -32,6 +34,12 @@ #define QUIC_CHROMIUM_LOG_IF_FATAL(condition) LOG_IF(FATAL, condition) #define QUIC_CHROMIUM_LOG_IF_DFATAL(condition) LOG_IF(DFATAL, condition) +#define QUIC_CHROMIUM_DLOG_IF_INFO(condition) DVLOG_IF(1, condition) +#define QUIC_CHROMIUM_DLOG_IF_WARNING(condition) DLOG_IF(WARNING, condition) +#define QUIC_CHROMIUM_DLOG_IF_ERROR(condition) DLOG_IF(ERROR, condition) +#define QUIC_CHROMIUM_DLOG_IF_FATAL(condition) DLOG_IF(FATAL, condition) +#define QUIC_CHROMIUM_DLOG_IF_DFATAL(condition) DLOG_IF(DFATAL, condition) + #define QUIC_DVLOG_IMPL(verbose_level) DVLOG(verbose_level) #if defined(OS_WIN) @@ -42,6 +50,11 @@ #define QUIC_CHROMIUM_LOG_0 QUIC_CHROMIUM_LOG_ERROR #define QUIC_CHROMIUM_DLOG_0 QUIC_CHROMIUM_DLOG_ERROR #define QUIC_CHROMIUM_LOG_IF_0 QUIC_CHROMIUM_LOG_IF_ERROR +#define QUIC_CHROMIUM_DLOG_IF_0 QUIC_CHROMIUM_DLOG_IF_ERROR #endif +#define QUIC_PREDICT_FALSE_IMPL(x) x + +#define QUIC_NOTREACHED_IMPL() NOTREACHED() + #endif // NET_QUIC_PLATFORM_IMPL_QUIC_LOGGING_IMPL_H_ diff --git a/chromium/net/quic/platform/impl/quic_map_util_impl.h b/chromium/net/quic/platform/impl/quic_map_util_impl.h new file mode 100644 index 00000000000..833f5ab5f21 --- /dev/null +++ b/chromium/net/quic/platform/impl/quic_map_util_impl.h @@ -0,0 +1,24 @@ +// Copyright (c) 2017 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 NET_QUIC_PLATFORM_IMPL_QUIC_MAP_UTIL_IMPL_H_ +#define NET_QUIC_PLATFORM_IMPL_QUIC_MAP_UTIL_IMPL_H_ + +#include "base/stl_util.h" + +namespace net { + +template <class Collection, class Key> +bool QuicContainsKeyImpl(const Collection& collection, const Key& key) { + return base::ContainsKey(collection, key); +} + +template <typename Collection, typename Value> +bool QuicContainsValueImpl(const Collection& collection, const Value& value) { + return base::ContainsValue(collection, value); +} + +} // namespace net + +#endif // NET_QUIC_PLATFORM_IMPL_QUIC_MAP_UTIL_IMPL_H_ diff --git a/chromium/net/quic/platform/impl/quic_stack_trace_impl.h b/chromium/net/quic/platform/impl/quic_stack_trace_impl.h new file mode 100644 index 00000000000..06af537346f --- /dev/null +++ b/chromium/net/quic/platform/impl/quic_stack_trace_impl.h @@ -0,0 +1,18 @@ +// Copyright (c) 2017 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 NET_QUIC_PLATFORM_IMPL_QUIC_STACK_TRACE_IMPL_H_ +#define NET_QUIC_PLATFORM_IMPL_QUIC_STACK_TRACE_IMPL_H_ + +#include "base/debug/stack_trace.h" + +namespace net { + +inline std::string QuicStackTraceImpl() { + return base::debug::StackTrace().ToString(); +} + +} // namespace net + +#endif // NET_QUIC_PLATFORM_IMPL_QUIC_STACK_TRACE_IMPL_H_ diff --git a/chromium/net/quic/platform/impl/quic_str_cat_impl.h b/chromium/net/quic/platform/impl/quic_str_cat_impl.h index 1989e8df5d5..3e07d64cbbc 100644 --- a/chromium/net/quic/platform/impl/quic_str_cat_impl.h +++ b/chromium/net/quic/platform/impl/quic_str_cat_impl.h @@ -8,6 +8,8 @@ #include <sstream> #include <string> +#include "base/strings/stringprintf.h" + namespace net { template <typename... Args> @@ -18,6 +20,11 @@ inline std::string QuicStrCatImpl(const Args&... args) { return oss.str(); } +template <typename... Args> +inline std::string QuicStringPrintfImpl(const Args&... args) { + return std::move(base::StringPrintf(std::forward<const Args&>(args)...)); +} + } // namespace net #endif // NET_QUIC_PLATFORM_IMPL_QUIC_STR_CAT_IMPL_H_ diff --git a/chromium/net/quic/platform/impl/quic_text_utils_impl.h b/chromium/net/quic/platform/impl/quic_text_utils_impl.h index a3cce167695..c797ac6f446 100644 --- a/chromium/net/quic/platform/impl/quic_text_utils_impl.h +++ b/chromium/net/quic/platform/impl/quic_text_utils_impl.h @@ -13,6 +13,7 @@ #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" +#include "net/base/parse_number.h" namespace net { @@ -46,6 +47,24 @@ class QuicTextUtilsImpl { return base::StringToUint64(in, out); } + // Returns true if |in| represents a valid int, and stores that value in + // |out|. + static bool StringToInt(base::StringPiece in, int* out) { + return base::StringToInt(in, out); + } + + // Returns true if |in| represents a valid uint32, and stores that value in + // |out|. + static bool StringToUint32(base::StringPiece in, uint32_t* out) { + return ParseUint32(in, out, nullptr); + } + + // Returns true if |in| represents a valid size_t, and stores that value in + // |out|. + static bool StringToSizeT(base::StringPiece in, size_t* out) { + return base::StringToSizeT(in, out); + } + // Returns a new std::string representing |in|. static std::string Uint64ToString(uint64_t in) { return base::Uint64ToString(in); diff --git a/chromium/net/quic/platform/impl/quic_url_impl.cc b/chromium/net/quic/platform/impl/quic_url_impl.cc new file mode 100644 index 00000000000..76f5a540cd8 --- /dev/null +++ b/chromium/net/quic/platform/impl/quic_url_impl.cc @@ -0,0 +1,107 @@ +// Copyright (c) 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/quic/platform/impl/quic_url_impl.h" + +#include "net/quic/platform/api/quic_text_utils.h" + +using base::StringPiece; +using std::string; + +namespace net { + +QuicUrlImpl::QuicUrlImpl(StringPiece url) : url_(url) {} + +QuicUrlImpl::QuicUrlImpl(StringPiece url, StringPiece default_scheme) + : url_(url) { + if (url_.has_scheme()) { + return; + } + string buffer = default_scheme.as_string() + "://" + url.as_string(); + url_ = GURL(buffer); +} + +QuicUrlImpl::QuicUrlImpl(const QuicUrlImpl& url) : url_(url.url()) {} + +string QuicUrlImpl::ToStringIfValid() const { + if (IsValid()) { + return url_.spec(); + } + return ""; +} + +bool QuicUrlImpl::IsValid() const { + if (!url_.is_valid() || !url_.has_scheme()) { + return false; + } + + if (url_.has_host() && url_.host().length() > kMaxHostNameLength) { + return false; + } + + return true; +} + +string QuicUrlImpl::HostPort() const { + if (!IsValid() || !url_.has_host()) { + return ""; + } + + string buffer = url_.host(); + int port = url_.IntPort(); + string scheme = url_.scheme(); + if (port == url::PORT_UNSPECIFIED || + (url_.IsStandard() && + port == url::DefaultPortForScheme(scheme.c_str(), scheme.length()))) { + return buffer; + } + buffer = buffer + ":" + std::to_string(port); + return buffer; +} + +string QuicUrlImpl::PathParamsQuery() const { + if (!IsValid() || !url_.has_path()) { + return "/"; + } + + return url_.PathForRequest(); +} + +string QuicUrlImpl::scheme() const { + if (!IsValid()) { + return ""; + } + + return url_.scheme(); +} + +string QuicUrlImpl::host() const { + if (!IsValid()) { + return ""; + } + + return url_.HostNoBrackets(); +} + +string QuicUrlImpl::path() const { + if (!IsValid()) { + return ""; + } + + return url_.path(); +} + +uint16_t QuicUrlImpl::port() const { + if (!IsValid()) { + return 0; + } + + int port = url_.EffectiveIntPort(); + if (port == url::PORT_UNSPECIFIED) { + return 0; + } + return port; +} + +} // namespace net diff --git a/chromium/net/quic/platform/impl/quic_url_impl.h b/chromium/net/quic/platform/impl/quic_url_impl.h new file mode 100644 index 00000000000..bb688a9cc1d --- /dev/null +++ b/chromium/net/quic/platform/impl/quic_url_impl.h @@ -0,0 +1,66 @@ +// Copyright (c) 2017 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 NET_QUIC_PLATFORM_IMPL_QUIC_URL_IMPL_H_ +#define NET_QUIC_PLATFORM_IMPL_QUIC_URL_IMPL_H_ + +#include "net/quic/platform/api/quic_export.h" +#include "url/gurl.h" + +namespace net { + +class QUIC_EXPORT_PRIVATE QuicUrlImpl { + public: + static const size_t kMaxHostNameLength = 256; + + // Constructs an empty QuicUrl. + QuicUrlImpl() = default; + + // Constructs a QuicUrlImpl from the url string |url|. + // NOTE: If |url| doesn't have a scheme, it will have an empty scheme + // field. If that's not what you want, use the QuicUrlImpl(url, + // default_scheme) form below. + explicit QuicUrlImpl(base::StringPiece url); + + // Constructs a QuicUrlImpl from |url|, assuming that the scheme for the URL + // is |default_scheme| if there is no scheme specified in |url|. + QuicUrlImpl(base::StringPiece url, base::StringPiece default_scheme); + + QuicUrlImpl(const QuicUrlImpl& url); + + // Returns false if any of these conditions occur: + // No scheme specified + // Host name too long (> 256 bytes) + // Invalid characters in host name, path or params + // Invalid port number (e.g. greater than 65535) + bool IsValid() const; + + // Returns full text of the QuicUrlImpl if it is valid. Return empty string + // otherwise. + std::string ToStringIfValid() const; + + // Returns host:port. + // If the host is empty, it will return an empty std::string. + // If the host is an IPv6 address, it will be bracketed. + // If port is not present or is equal to default_port of scheme (e.g., port + // 80 for HTTP), it won't be returned. + std::string HostPort() const; + + // Returns a string assembles path, parameters and query. + std::string PathParamsQuery() const; + + std::string scheme() const; + std::string host() const; + std::string path() const; + uint16_t port() const; + + const GURL& url() const { return url_; } + + private: + GURL url_; +}; + +} // namespace net + +#endif // NET_QUIC_PLATFORM_IMPL_QUIC_URL_IMPL_H_ diff --git a/chromium/net/quic/platform/impl/quic_url_utils_impl.cc b/chromium/net/quic/platform/impl/quic_url_utils_impl.cc new file mode 100644 index 00000000000..1ef757b1fd3 --- /dev/null +++ b/chromium/net/quic/platform/impl/quic_url_utils_impl.cc @@ -0,0 +1,24 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/quic/platform/impl/quic_url_utils_impl.h" + +#include "url/gurl.h" + +using base::StringPiece; +using std::string; + +namespace net { + +// static +string QuicUrlUtilsImpl::HostName(StringPiece url) { + return GURL(url).host(); +} + +// static +bool QuicUrlUtilsImpl::IsValidUrl(StringPiece url) { + return GURL(url).is_valid(); +} + +} // namespace net diff --git a/chromium/net/quic/platform/impl/quic_url_utils_impl.h b/chromium/net/quic/platform/impl/quic_url_utils_impl.h new file mode 100644 index 00000000000..31fbfec32ed --- /dev/null +++ b/chromium/net/quic/platform/impl/quic_url_utils_impl.h @@ -0,0 +1,31 @@ +// Copyright (c) 2013 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 NET_QUIC_PLATFORM_IMPL_QUIC_URL_UTILS_IMPL_H_ +#define NET_QUIC_PLATFORM_IMPL_QUIC_URL_UTILS_IMPL_H_ + +#include "base/macros.h" +#include "base/strings/string_piece.h" +#include "net/quic/core/quic_server_id.h" +#include "net/quic/platform/api/quic_export.h" + +namespace net { + +class QUIC_EXPORT_PRIVATE QuicUrlUtilsImpl { + public: + // Returns hostname, or empty std::string if missing. + static std::string HostName(base::StringPiece url); + + // Returns false if any of these conditions occur: (1) Host name too long; (2) + // Invalid characters in host name, path or params; (3) Invalid port number + // (e.g. greater than 65535). + static bool IsValidUrl(base::StringPiece url); + + private: + DISALLOW_COPY_AND_ASSIGN(QuicUrlUtilsImpl); +}; + +} // namespace net + +#endif // NET_QUIC_PLATFORM_IMPL_QUIC_URL_UTILS_IMPL_H_ diff --git a/chromium/net/quic/quartc/quartc_factory.cc b/chromium/net/quic/quartc/quartc_factory.cc index 6a90bd614b5..9cf63c06394 100644 --- a/chromium/net/quic/quartc/quartc_factory.cc +++ b/chromium/net/quic/quartc/quartc_factory.cc @@ -41,7 +41,7 @@ class QuartcAlarm : public net::QuicAlarm, DCHECK(task_runner_); DCHECK(!scheduled_task_); - scheduled_task_.reset((task_runner_->Schedule(this, delay_ms)).release()); + scheduled_task_ = task_runner_->Schedule(this, delay_ms); } void CancelImpl() override { diff --git a/chromium/net/quic/quartc/quartc_session.cc b/chromium/net/quic/quartc/quartc_session.cc index e31f72bb0df..3664d893f61 100644 --- a/chromium/net/quic/quartc/quartc_session.cc +++ b/chromium/net/quic/quartc/quartc_session.cc @@ -28,30 +28,22 @@ class DummyProofSource : public net::ProofSource { ~DummyProofSource() override {} // ProofSource override. - bool GetProof( - const net::QuicSocketAddress& server_addr, - const std::string& hostname, - const std::string& server_config, - net::QuicVersion quic_version, - base::StringPiece chlo_hash, - const net::QuicTagVector& connection_options, - net::QuicReferenceCountedPointer<net::ProofSource::Chain>* out_chain, - net::QuicCryptoProof* proof) override { - std::vector<std::string> certs; - certs.push_back("Dummy cert"); - *out_chain = new ProofSource::Chain(certs); - proof->signature = "Dummy signature"; - proof->leaf_cert_scts = "Dummy timestamp"; - return true; - } - void GetProof(const net::QuicSocketAddress& server_addr, const std::string& hostname, const std::string& server_config, net::QuicVersion quic_version, base::StringPiece chlo_hash, const net::QuicTagVector& connection_options, - std::unique_ptr<Callback> callback) override {} + std::unique_ptr<Callback> callback) override { + net::QuicReferenceCountedPointer<net::ProofSource::Chain> chain; + net::QuicCryptoProof proof; + std::vector<std::string> certs; + certs.push_back("Dummy cert"); + chain = new ProofSource::Chain(certs); + proof.signature = "Dummy signature"; + proof.leaf_cert_scts = "Dummy timestamp"; + callback->Run(true, chain, proof, nullptr /* details */); + } }; // Used by QuicCryptoClientConfig to ignore the peer's credentials diff --git a/chromium/net/quic/quartc/quartc_session_test.cc b/chromium/net/quic/quartc/quartc_session_test.cc index dd8db243eda..6bc2b5904a4 100644 --- a/chromium/net/quic/quartc/quartc_session_test.cc +++ b/chromium/net/quic/quartc/quartc_session_test.cc @@ -21,6 +21,7 @@ #include "net/quic/platform/impl/quic_chromium_clock.h" #include "net/quic/quartc/quartc_alarm_factory.h" #include "net/quic/quartc/quartc_packet_writer.h" +#include "net/quic/test_tools/quic_test_utils.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { @@ -52,32 +53,23 @@ class FakeProofSource : public net::ProofSource { explicit FakeProofSource(bool success) : success_(success) {} // ProofSource override. - bool GetProof(const QuicSocketAddress& server_ip, + void GetProof(const QuicSocketAddress& server_ip, const std::string& hostname, const std::string& server_config, net::QuicVersion quic_version, base::StringPiece chlo_hash, const net::QuicTagVector& connection_options, - QuicReferenceCountedPointer<net::ProofSource::Chain>* out_certs, - net::QuicCryptoProof* proof) override { + std::unique_ptr<Callback> callback) override { + QuicReferenceCountedPointer<net::ProofSource::Chain> chain; + net::QuicCryptoProof proof; if (success_) { std::vector<std::string> certs; certs.push_back("Required to establish handshake"); - *out_certs = new ProofSource::Chain(certs); - proof->signature = "Signature"; - proof->leaf_cert_scts = "Time"; + chain = new ProofSource::Chain(certs); + proof.signature = "Signature"; + proof.leaf_cert_scts = "Time"; } - return success_; - } - - void GetProof(const QuicSocketAddress& server_ip, - const std::string& hostname, - const std::string& server_config, - net::QuicVersion quic_version, - base::StringPiece chlo_hash, - const net::QuicTagVector& connection_options, - std::unique_ptr<Callback> callback) override { - LOG(INFO) << "GetProof() providing dummy credentials for insecure QUIC"; + callback->Run(success_, chain, proof, nullptr /* details */); } private: @@ -450,6 +442,7 @@ class QuartcSessionTest : public ::testing::Test, std::unique_ptr<QuicAlarmFactory> alarm_factory_; SimpleBufferAllocator buffer_allocator_; QuicChromiumClock clock_; + QuicFlagSaver flags_; // Save/restore all QUIC flag values. std::unique_ptr<FakeTransportChannel> client_channel_; std::unique_ptr<FakeTransportChannel> server_channel_; diff --git a/chromium/net/quic/test_tools/crypto_test_utils.cc b/chromium/net/quic/test_tools/crypto_test_utils.cc index f210e26b821..f7eff11696b 100644 --- a/chromium/net/quic/test_tools/crypto_test_utils.cc +++ b/chromium/net/quic/test_tools/crypto_test_utils.cc @@ -6,8 +6,6 @@ #include <memory> -#include "crypto/openssl_util.h" -#include "crypto/secure_hash.h" #include "net/quic/core/crypto/channel_id.h" #include "net/quic/core/crypto/common_cert_set.h" #include "net/quic/core/crypto/crypto_handshake.h" @@ -27,12 +25,12 @@ #include "net/quic/platform/api/quic_text_utils.h" #include "net/quic/test_tools/quic_connection_peer.h" #include "net/quic/test_tools/quic_framer_peer.h" +#include "net/quic/test_tools/quic_stream_peer.h" #include "net/quic/test_tools/quic_test_utils.h" #include "net/quic/test_tools/simple_quic_framer.h" #include "third_party/boringssl/src/include/openssl/bn.h" #include "third_party/boringssl/src/include/openssl/ec.h" #include "third_party/boringssl/src/include/openssl/ecdsa.h" -#include "third_party/boringssl/src/include/openssl/evp.h" #include "third_party/boringssl/src/include/openssl/obj_mac.h" #include "third_party/boringssl/src/include/openssl/sha.h" @@ -42,6 +40,128 @@ using std::string; namespace net { namespace test { +TestChannelIDKey::TestChannelIDKey(EVP_PKEY* ecdsa_key) + : ecdsa_key_(ecdsa_key) {} +TestChannelIDKey::~TestChannelIDKey() {} + +bool TestChannelIDKey::Sign(StringPiece signed_data, + string* out_signature) const { + bssl::ScopedEVP_MD_CTX md_ctx; + if (EVP_DigestSignInit(md_ctx.get(), nullptr, EVP_sha256(), nullptr, + ecdsa_key_.get()) != 1) { + return false; + } + + EVP_DigestUpdate(md_ctx.get(), ChannelIDVerifier::kContextStr, + strlen(ChannelIDVerifier::kContextStr) + 1); + EVP_DigestUpdate(md_ctx.get(), ChannelIDVerifier::kClientToServerStr, + strlen(ChannelIDVerifier::kClientToServerStr) + 1); + EVP_DigestUpdate(md_ctx.get(), signed_data.data(), signed_data.size()); + + size_t sig_len; + if (!EVP_DigestSignFinal(md_ctx.get(), nullptr, &sig_len)) { + return false; + } + + std::unique_ptr<uint8_t[]> der_sig(new uint8_t[sig_len]); + if (!EVP_DigestSignFinal(md_ctx.get(), der_sig.get(), &sig_len)) { + return false; + } + + uint8_t* derp = der_sig.get(); + bssl::UniquePtr<ECDSA_SIG> sig( + d2i_ECDSA_SIG(nullptr, const_cast<const uint8_t**>(&derp), sig_len)); + if (sig.get() == nullptr) { + return false; + } + + // The signature consists of a pair of 32-byte numbers. + static const size_t kSignatureLength = 32 * 2; + std::unique_ptr<uint8_t[]> signature(new uint8_t[kSignatureLength]); + if (!BN_bn2bin_padded(&signature[0], 32, sig->r) || + !BN_bn2bin_padded(&signature[32], 32, sig->s)) { + return false; + } + + *out_signature = + string(reinterpret_cast<char*>(signature.get()), kSignatureLength); + + return true; +} + +string TestChannelIDKey::SerializeKey() const { + // i2d_PublicKey will produce an ANSI X9.62 public key which, for a P-256 + // key, is 0x04 (meaning uncompressed) followed by the x and y field + // elements as 32-byte, big-endian numbers. + static const int kExpectedKeyLength = 65; + + int len = i2d_PublicKey(ecdsa_key_.get(), nullptr); + if (len != kExpectedKeyLength) { + return ""; + } + + uint8_t buf[kExpectedKeyLength]; + uint8_t* derp = buf; + i2d_PublicKey(ecdsa_key_.get(), &derp); + + return string(reinterpret_cast<char*>(buf + 1), kExpectedKeyLength - 1); +} + +TestChannelIDSource::~TestChannelIDSource() {} + +QuicAsyncStatus TestChannelIDSource::GetChannelIDKey( + const string& hostname, + std::unique_ptr<ChannelIDKey>* channel_id_key, + ChannelIDSourceCallback* /*callback*/) { + channel_id_key->reset(new TestChannelIDKey(HostnameToKey(hostname))); + return QUIC_SUCCESS; +} + +// static +EVP_PKEY* TestChannelIDSource::HostnameToKey(const string& hostname) { + // In order to generate a deterministic key for a given hostname the + // hostname is hashed with SHA-256 and the resulting digest is treated as a + // big-endian number. The most-significant bit is cleared to ensure that + // the resulting value is less than the order of the group and then it's + // taken as a private key. Given the private key, the public key is + // calculated with a group multiplication. + SHA256_CTX sha256; + SHA256_Init(&sha256); + SHA256_Update(&sha256, hostname.data(), hostname.size()); + + unsigned char digest[SHA256_DIGEST_LENGTH]; + SHA256_Final(digest, &sha256); + + // Ensure that the digest is less than the order of the P-256 group by + // clearing the most-significant bit. + digest[0] &= 0x7f; + + bssl::UniquePtr<BIGNUM> k(BN_new()); + CHECK(BN_bin2bn(digest, sizeof(digest), k.get()) != nullptr); + + bssl::UniquePtr<EC_GROUP> p256( + EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)); + CHECK(p256); + + bssl::UniquePtr<EC_KEY> ecdsa_key(EC_KEY_new()); + CHECK(ecdsa_key && EC_KEY_set_group(ecdsa_key.get(), p256.get())); + + bssl::UniquePtr<EC_POINT> point(EC_POINT_new(p256.get())); + CHECK(EC_POINT_mul(p256.get(), point.get(), k.get(), nullptr, nullptr, + nullptr)); + + EC_KEY_set_private_key(ecdsa_key.get(), k.get()); + EC_KEY_set_public_key(ecdsa_key.get(), point.get()); + + bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new()); + // EVP_PKEY_set1_EC_KEY takes a reference so no |release| here. + EVP_PKEY_set1_EC_KEY(pkey.get(), ecdsa_key.get()); + + return pkey.release(); +} + +namespace crypto_test_utils { + namespace { // CryptoFramerVisitor is a framer visitor that records handshake messages. @@ -86,8 +206,7 @@ bool HexChar(char c, uint8_t* value) { // A ChannelIDSource that works in asynchronous mode unless the |callback| // argument to GetChannelIDKey is nullptr. -class AsyncTestChannelIDSource : public ChannelIDSource, - public CryptoTestUtils::CallbackSource { +class AsyncTestChannelIDSource : public ChannelIDSource, public CallbackSource { public: // Takes ownership of |sync_source|, a synchronous ChannelIDSource. explicit AsyncTestChannelIDSource(ChannelIDSource* sync_source) @@ -127,147 +246,16 @@ class AsyncTestChannelIDSource : public ChannelIDSource, std::unique_ptr<ChannelIDKey> channel_id_key_; }; -class TestChannelIDKey : public ChannelIDKey { - public: - explicit TestChannelIDKey(EVP_PKEY* ecdsa_key) : ecdsa_key_(ecdsa_key) {} - ~TestChannelIDKey() override {} - - // ChannelIDKey implementation. - - bool Sign(StringPiece signed_data, string* out_signature) const override { - bssl::ScopedEVP_MD_CTX md_ctx; - if (EVP_DigestSignInit(md_ctx.get(), nullptr, EVP_sha256(), nullptr, - ecdsa_key_.get()) != 1) { - return false; - } - - EVP_DigestUpdate(md_ctx.get(), ChannelIDVerifier::kContextStr, - strlen(ChannelIDVerifier::kContextStr) + 1); - EVP_DigestUpdate(md_ctx.get(), ChannelIDVerifier::kClientToServerStr, - strlen(ChannelIDVerifier::kClientToServerStr) + 1); - EVP_DigestUpdate(md_ctx.get(), signed_data.data(), signed_data.size()); - - size_t sig_len; - if (!EVP_DigestSignFinal(md_ctx.get(), nullptr, &sig_len)) { - return false; - } - - std::unique_ptr<uint8_t[]> der_sig(new uint8_t[sig_len]); - if (!EVP_DigestSignFinal(md_ctx.get(), der_sig.get(), &sig_len)) { - return false; - } - - uint8_t* derp = der_sig.get(); - bssl::UniquePtr<ECDSA_SIG> sig( - d2i_ECDSA_SIG(nullptr, const_cast<const uint8_t**>(&derp), sig_len)); - if (sig.get() == nullptr) { - return false; - } - - // The signature consists of a pair of 32-byte numbers. - static const size_t kSignatureLength = 32 * 2; - std::unique_ptr<uint8_t[]> signature(new uint8_t[kSignatureLength]); - if (!BN_bn2bin_padded(&signature[0], 32, sig->r) || - !BN_bn2bin_padded(&signature[32], 32, sig->s)) { - return false; - } - - *out_signature = - string(reinterpret_cast<char*>(signature.get()), kSignatureLength); - - return true; - } - - string SerializeKey() const override { - // i2d_PublicKey will produce an ANSI X9.62 public key which, for a P-256 - // key, is 0x04 (meaning uncompressed) followed by the x and y field - // elements as 32-byte, big-endian numbers. - static const int kExpectedKeyLength = 65; - - int len = i2d_PublicKey(ecdsa_key_.get(), nullptr); - if (len != kExpectedKeyLength) { - return ""; - } - - uint8_t buf[kExpectedKeyLength]; - uint8_t* derp = buf; - i2d_PublicKey(ecdsa_key_.get(), &derp); - - return string(reinterpret_cast<char*>(buf + 1), kExpectedKeyLength - 1); - } - - private: - bssl::UniquePtr<EVP_PKEY> ecdsa_key_; -}; - -class TestChannelIDSource : public ChannelIDSource { - public: - ~TestChannelIDSource() override {} - - // ChannelIDSource implementation. - - QuicAsyncStatus GetChannelIDKey( - const string& hostname, - std::unique_ptr<ChannelIDKey>* channel_id_key, - ChannelIDSourceCallback* /*callback*/) override { - channel_id_key->reset(new TestChannelIDKey(HostnameToKey(hostname))); - return QUIC_SUCCESS; - } - - private: - static EVP_PKEY* HostnameToKey(const string& hostname) { - // In order to generate a deterministic key for a given hostname the - // hostname is hashed with SHA-256 and the resulting digest is treated as a - // big-endian number. The most-significant bit is cleared to ensure that - // the resulting value is less than the order of the group and then it's - // taken as a private key. Given the private key, the public key is - // calculated with a group multiplication. - SHA256_CTX sha256; - SHA256_Init(&sha256); - SHA256_Update(&sha256, hostname.data(), hostname.size()); - - unsigned char digest[SHA256_DIGEST_LENGTH]; - SHA256_Final(digest, &sha256); - - // Ensure that the digest is less than the order of the P-256 group by - // clearing the most-significant bit. - digest[0] &= 0x7f; - - bssl::UniquePtr<BIGNUM> k(BN_new()); - CHECK(BN_bin2bn(digest, sizeof(digest), k.get()) != nullptr); - - bssl::UniquePtr<EC_GROUP> p256( - EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)); - CHECK(p256); - - bssl::UniquePtr<EC_KEY> ecdsa_key(EC_KEY_new()); - CHECK(ecdsa_key && EC_KEY_set_group(ecdsa_key.get(), p256.get())); - - bssl::UniquePtr<EC_POINT> point(EC_POINT_new(p256.get())); - CHECK(EC_POINT_mul(p256.get(), point.get(), k.get(), nullptr, nullptr, - nullptr)); - - EC_KEY_set_private_key(ecdsa_key.get(), k.get()); - EC_KEY_set_public_key(ecdsa_key.get(), point.get()); - - bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new()); - // EVP_PKEY_set1_EC_KEY takes a reference so no |release| here. - EVP_PKEY_set1_EC_KEY(pkey.get(), ecdsa_key.get()); - - return pkey.release(); - } -}; - } // anonymous namespace -CryptoTestUtils::FakeServerOptions::FakeServerOptions() {} +FakeServerOptions::FakeServerOptions() {} -CryptoTestUtils::FakeServerOptions::~FakeServerOptions() {} +FakeServerOptions::~FakeServerOptions() {} -CryptoTestUtils::FakeClientOptions::FakeClientOptions() +FakeClientOptions::FakeClientOptions() : channel_id_enabled(false), channel_id_source_async(false) {} -CryptoTestUtils::FakeClientOptions::~FakeClientOptions() {} +FakeClientOptions::~FakeClientOptions() {} namespace { // This class is used by GenerateFullCHLO() to extract SCID and STK from @@ -368,7 +356,7 @@ class FullChloGenerator { *out_ = result_->client_hello; out_->SetStringPiece(kSCID, scid); out_->SetStringPiece(kSourceAddressTokenTag, srct); - uint64_t xlct = CryptoTestUtils::LeafCertHashForTesting(); + uint64_t xlct = LeafCertHashForTesting(); out_->SetValue(kXLCT, xlct); } @@ -388,14 +376,12 @@ class FullChloGenerator { } // namespace -// static -int CryptoTestUtils::HandshakeWithFakeServer( - QuicConfig* server_quic_config, - MockQuicConnectionHelper* helper, - MockAlarmFactory* alarm_factory, - PacketSavingConnection* client_conn, - QuicCryptoClientStream* client, - const FakeServerOptions& options) { +int HandshakeWithFakeServer(QuicConfig* server_quic_config, + MockQuicConnectionHelper* helper, + MockAlarmFactory* alarm_factory, + PacketSavingConnection* client_conn, + QuicCryptoClientStream* client, + const FakeServerOptions& options) { PacketSavingConnection* server_conn = new PacketSavingConnection(helper, alarm_factory, Perspective::IS_SERVER, client_conn->supported_versions()); @@ -423,14 +409,12 @@ int CryptoTestUtils::HandshakeWithFakeServer( return client->num_sent_client_hellos(); } -// static -int CryptoTestUtils::HandshakeWithFakeClient( - MockQuicConnectionHelper* helper, - MockAlarmFactory* alarm_factory, - PacketSavingConnection* server_conn, - QuicCryptoServerStream* server, - const QuicServerId& server_id, - const FakeClientOptions& options) { +int HandshakeWithFakeClient(MockQuicConnectionHelper* helper, + MockAlarmFactory* alarm_factory, + PacketSavingConnection* server_conn, + QuicCryptoServerStream* server, + const QuicServerId& server_id, + const FakeClientOptions& options) { PacketSavingConnection* client_conn = new PacketSavingConnection(helper, alarm_factory, Perspective::IS_CLIENT); // Advance the time, because timers do not like uninitialized times. @@ -481,12 +465,10 @@ int CryptoTestUtils::HandshakeWithFakeClient( return client_session.GetCryptoStream()->num_sent_client_hellos(); } -// static -void CryptoTestUtils::SetupCryptoServerConfigForTest( - const QuicClock* clock, - QuicRandom* rand, - QuicCryptoServerConfig* crypto_config, - const FakeServerOptions& fake_options) { +void SetupCryptoServerConfigForTest(const QuicClock* clock, + QuicRandom* rand, + QuicCryptoServerConfig* crypto_config, + const FakeServerOptions& fake_options) { QuicCryptoServerConfig::ConfigOptions options; options.channel_id_enabled = true; options.token_binding_params = fake_options.token_binding_params; @@ -494,18 +476,15 @@ void CryptoTestUtils::SetupCryptoServerConfigForTest( crypto_config->AddDefaultConfig(rand, clock, options)); } -// static -void CryptoTestUtils::CommunicateHandshakeMessages( - PacketSavingConnection* client_conn, - QuicCryptoStream* client, - PacketSavingConnection* server_conn, - QuicCryptoStream* server) { +void CommunicateHandshakeMessages(PacketSavingConnection* client_conn, + QuicCryptoStream* client, + PacketSavingConnection* server_conn, + QuicCryptoStream* server) { CommunicateHandshakeMessagesAndRunCallbacks(client_conn, client, server_conn, server, nullptr); } -// static -void CryptoTestUtils::CommunicateHandshakeMessagesAndRunCallbacks( +void CommunicateHandshakeMessagesAndRunCallbacks( PacketSavingConnection* client_conn, QuicCryptoStream* client, PacketSavingConnection* server_conn, @@ -535,14 +514,12 @@ void CryptoTestUtils::CommunicateHandshakeMessagesAndRunCallbacks( } } -// static -std::pair<size_t, size_t> CryptoTestUtils::AdvanceHandshake( - PacketSavingConnection* client_conn, - QuicCryptoStream* client, - size_t client_i, - PacketSavingConnection* server_conn, - QuicCryptoStream* server, - size_t server_i) { +std::pair<size_t, size_t> AdvanceHandshake(PacketSavingConnection* client_conn, + QuicCryptoStream* client, + size_t client_i, + PacketSavingConnection* server_conn, + QuicCryptoStream* server, + size_t server_i) { QUIC_LOG(INFO) << "Processing " << client_conn->encrypted_packets_.size() - client_i << " packets client->server"; @@ -561,9 +538,7 @@ std::pair<size_t, size_t> CryptoTestUtils::AdvanceHandshake( return std::make_pair(client_i, server_i); } -// static -string CryptoTestUtils::GetValueForTag(const CryptoHandshakeMessage& message, - QuicTag tag) { +string GetValueForTag(const CryptoHandshakeMessage& message, QuicTag tag) { QuicTagValueMap::const_iterator it = message.tag_value_map().find(tag); if (it == message.tag_value_map().end()) { return string(); @@ -571,16 +546,37 @@ string CryptoTestUtils::GetValueForTag(const CryptoHandshakeMessage& message, return it->second; } -uint64_t CryptoTestUtils::LeafCertHashForTesting() { +uint64_t LeafCertHashForTesting() { QuicReferenceCountedPointer<ProofSource::Chain> chain; QuicSocketAddress server_address; QuicCryptoProof proof; - std::unique_ptr<ProofSource> proof_source( - CryptoTestUtils::ProofSourceForTesting()); - if (!proof_source->GetProof(server_address, "", "", - AllSupportedVersions().front(), "", - QuicTagVector(), &chain, &proof) || - chain->certs.empty()) { + std::unique_ptr<ProofSource> proof_source(ProofSourceForTesting()); + + class Callback : public ProofSource::Callback { + public: + Callback(bool* ok, QuicReferenceCountedPointer<ProofSource::Chain>* chain) + : ok_(ok), chain_(chain) {} + + void Run(bool ok, + const QuicReferenceCountedPointer<ProofSource::Chain>& chain, + const QuicCryptoProof& /* proof */, + std::unique_ptr<ProofSource::Details> /* details */) override { + *ok_ = ok; + *chain_ = chain; + } + + private: + bool* ok_; + QuicReferenceCountedPointer<ProofSource::Chain>* chain_; + }; + + // Note: relies on the callback being invoked synchronously + bool ok = false; + proof_source->GetProof( + server_address, "", "", AllSupportedVersions().front(), "", + QuicTagVector(), + std::unique_ptr<ProofSource::Callback>(new Callback(&ok, &chain))); + if (!ok || chain->certs.empty()) { DCHECK(false) << "Proof generation failed"; return 0; } @@ -641,15 +637,13 @@ class MockCommonCertSets : public CommonCertSets { const uint32_t index_; }; -CommonCertSets* CryptoTestUtils::MockCommonCertSets(StringPiece cert, - uint64_t hash, - uint32_t index) { +CommonCertSets* MockCommonCertSets(StringPiece cert, + uint64_t hash, + uint32_t index) { return new class MockCommonCertSets(cert, hash, index); } -// static -void CryptoTestUtils::FillInDummyReject(CryptoHandshakeMessage* rej, - bool reject_is_stateless) { +void FillInDummyReject(CryptoHandshakeMessage* rej, bool reject_is_stateless) { if (reject_is_stateless) { rej->set_tag(kSREJ); } else { @@ -683,29 +677,28 @@ void CryptoTestUtils::FillInDummyReject(CryptoHandshakeMessage* rej, rej->SetVector(kRREJ, reject_reasons); } -void CryptoTestUtils::CompareClientAndServerKeys( - QuicCryptoClientStream* client, - QuicCryptoServerStream* server) { - QuicFramer* client_framer = - QuicConnectionPeer::GetFramer(client->session()->connection()); - QuicFramer* server_framer = - QuicConnectionPeer::GetFramer(server->session()->connection()); +void CompareClientAndServerKeys(QuicCryptoClientStream* client, + QuicCryptoServerStream* server) { + QuicFramer* client_framer = QuicConnectionPeer::GetFramer( + QuicStreamPeer::session(client)->connection()); + QuicFramer* server_framer = QuicConnectionPeer::GetFramer( + QuicStreamPeer::session(server)->connection()); const QuicEncrypter* client_encrypter( QuicFramerPeer::GetEncrypter(client_framer, ENCRYPTION_INITIAL)); const QuicDecrypter* client_decrypter( - client->session()->connection()->decrypter()); + QuicStreamPeer::session(client)->connection()->decrypter()); const QuicEncrypter* client_forward_secure_encrypter( QuicFramerPeer::GetEncrypter(client_framer, ENCRYPTION_FORWARD_SECURE)); const QuicDecrypter* client_forward_secure_decrypter( - client->session()->connection()->alternative_decrypter()); + QuicStreamPeer::session(client)->connection()->alternative_decrypter()); const QuicEncrypter* server_encrypter( QuicFramerPeer::GetEncrypter(server_framer, ENCRYPTION_INITIAL)); const QuicDecrypter* server_decrypter( - server->session()->connection()->decrypter()); + QuicStreamPeer::session(server)->connection()->decrypter()); const QuicEncrypter* server_forward_secure_encrypter( QuicFramerPeer::GetEncrypter(server_framer, ENCRYPTION_FORWARD_SECURE)); const QuicDecrypter* server_forward_secure_decrypter( - server->session()->connection()->alternative_decrypter()); + QuicStreamPeer::session(server)->connection()->alternative_decrypter()); StringPiece client_encrypter_key = client_encrypter->GetKey(); StringPiece client_encrypter_iv = client_encrypter->GetNoncePrefix(); @@ -803,8 +796,7 @@ void CryptoTestUtils::CompareClientAndServerKeys( server_tb_ekm.data(), server_tb_ekm.length()); } -// static -QuicTag CryptoTestUtils::ParseTag(const char* tagstr) { +QuicTag ParseTag(const char* tagstr) { const size_t len = strlen(tagstr); CHECK_NE(0u, len); @@ -836,58 +828,35 @@ QuicTag CryptoTestUtils::ParseTag(const char* tagstr) { return tag; } -// static -CryptoHandshakeMessage CryptoTestUtils::Message(const char* message_tag, ...) { - va_list ap; - va_start(ap, message_tag); +CryptoHandshakeMessage CreateCHLO( + std::vector<std::pair<string, string>> tags_and_values) { + return CreateCHLO(tags_and_values, -1); +} +CryptoHandshakeMessage CreateCHLO( + std::vector<std::pair<string, string>> tags_and_values, + int minimum_size_bytes) { CryptoHandshakeMessage msg; - msg.set_tag(ParseTag(message_tag)); - - for (;;) { - const char* tagstr = va_arg(ap, const char*); - if (tagstr == nullptr) { - break; - } - - if (tagstr[0] == '$') { - // Special value. - const char* const special = tagstr + 1; - if (strcmp(special, "padding") == 0) { - const int min_bytes = va_arg(ap, int); - msg.set_minimum_size(min_bytes); - } else { - CHECK(false) << "Unknown special value: " << special; - } + msg.set_tag(MakeQuicTag('C', 'H', 'L', 'O')); - continue; - } - - const QuicTag tag = ParseTag(tagstr); - const char* valuestr = va_arg(ap, const char*); - - size_t len = strlen(valuestr); - if (len > 0 && valuestr[0] == '#') { - valuestr++; - len--; + if (minimum_size_bytes > 0) { + msg.set_minimum_size(minimum_size_bytes); + } - CHECK_EQ(0u, len % 2); - std::unique_ptr<uint8_t[]> buf(new uint8_t[len / 2]); + for (const auto& tag_and_value : tags_and_values) { + const string& tag = tag_and_value.first; + const string& value = tag_and_value.second; - for (size_t i = 0; i < len / 2; i++) { - uint8_t v = 0; - CHECK(HexChar(valuestr[i * 2], &v)); - buf[i] = v << 4; - CHECK(HexChar(valuestr[i * 2 + 1], &v)); - buf[i] |= v; - } + const QuicTag quic_tag = ParseTag(tag.c_str()); - msg.SetStringPiece( - tag, StringPiece(reinterpret_cast<char*>(buf.get()), len / 2)); + size_t value_len = value.length(); + if (value_len > 0 && value[0] == '#') { + // This is ascii encoded hex. + string hex_value = QuicTextUtils::HexDecode(StringPiece(&value[1])); + msg.SetStringPiece(quic_tag, hex_value); continue; } - - msg.SetStringPiece(tag, valuestr); + msg.SetStringPiece(quic_tag, value); } // The CryptoHandshakeMessage needs to be serialized and parsed to ensure @@ -897,21 +866,18 @@ CryptoHandshakeMessage CryptoTestUtils::Message(const char* message_tag, ...) { CryptoFramer::ParseMessage(bytes->AsStringPiece())); CHECK(parsed.get()); - va_end(ap); return *parsed; } -// static -ChannelIDSource* CryptoTestUtils::ChannelIDSourceForTesting() { +ChannelIDSource* ChannelIDSourceForTesting() { return new TestChannelIDSource(); } -// static -void CryptoTestUtils::MovePackets(PacketSavingConnection* source_conn, - size_t* inout_packet_index, - QuicCryptoStream* dest_stream, - PacketSavingConnection* dest_conn, - Perspective dest_perspective) { +void MovePackets(PacketSavingConnection* source_conn, + size_t* inout_packet_index, + QuicCryptoStream* dest_stream, + PacketSavingConnection* dest_conn, + Perspective dest_perspective) { SimpleQuicFramer framer(source_conn->supported_versions(), dest_perspective); CryptoFramer crypto_framer; CryptoFramerVisitor crypto_visitor; @@ -953,68 +919,61 @@ void CryptoTestUtils::MovePackets(PacketSavingConnection* source_conn, QuicConnectionPeer::SetCurrentPacket(dest_conn, StringPiece(nullptr, 0)); } -CryptoHandshakeMessage CryptoTestUtils::GenerateDefaultInchoateCHLO( +CryptoHandshakeMessage GenerateDefaultInchoateCHLO( const QuicClock* clock, QuicVersion version, QuicCryptoServerConfig* crypto_config) { // clang-format off - return CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "AEAD", "AESG", - "KEXS", "C255", - "PUBS", CryptoTestUtils::GenerateClientPublicValuesHex().c_str(), - "NONC", CryptoTestUtils::GenerateClientNonceHex(clock, - crypto_config).c_str(), - "VER\0", QuicTagToString( - QuicVersionToQuicTag(version)).c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); + return CreateCHLO( + {{"PDMD", "X509"}, + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"PUBS", GenerateClientPublicValuesHex().c_str()}, + {"NONC", GenerateClientNonceHex(clock, crypto_config).c_str()}, + {"VER\0", QuicTagToString(QuicVersionToQuicTag(version)).c_str()}}, + kClientHelloMinimumSize); // clang-format on } -string CryptoTestUtils::GenerateClientNonceHex( - const QuicClock* clock, - QuicCryptoServerConfig* crypto_config) { - net::QuicCryptoServerConfig::ConfigOptions old_config_options; - net::QuicCryptoServerConfig::ConfigOptions new_config_options; +string GenerateClientNonceHex(const QuicClock* clock, + QuicCryptoServerConfig* crypto_config) { + QuicCryptoServerConfig::ConfigOptions old_config_options; + QuicCryptoServerConfig::ConfigOptions new_config_options; old_config_options.id = "old-config-id"; - delete crypto_config->AddDefaultConfig(net::QuicRandom::GetInstance(), clock, + delete crypto_config->AddDefaultConfig(QuicRandom::GetInstance(), clock, old_config_options); std::unique_ptr<QuicServerConfigProtobuf> primary_config( - crypto_config->GenerateConfig(net::QuicRandom::GetInstance(), clock, + crypto_config->GenerateConfig(QuicRandom::GetInstance(), clock, new_config_options)); primary_config->set_primary_time(clock->WallNow().ToUNIXSeconds()); - std::unique_ptr<net::CryptoHandshakeMessage> msg( + std::unique_ptr<CryptoHandshakeMessage> msg( crypto_config->AddConfig(std::move(primary_config), clock->WallNow())); StringPiece orbit; - CHECK(msg->GetStringPiece(net::kORBT, &orbit)); + CHECK(msg->GetStringPiece(kORBT, &orbit)); string nonce; - net::CryptoUtils::GenerateNonce( - clock->WallNow(), net::QuicRandom::GetInstance(), + CryptoUtils::GenerateNonce( + clock->WallNow(), QuicRandom::GetInstance(), StringPiece(reinterpret_cast<const char*>(orbit.data()), sizeof(orbit.size())), &nonce); return ("#" + QuicTextUtils::HexEncode(nonce)); } -string CryptoTestUtils::GenerateClientPublicValuesHex() { +string GenerateClientPublicValuesHex() { char public_value[32]; memset(public_value, 42, sizeof(public_value)); return ("#" + QuicTextUtils::HexEncode(public_value, sizeof(public_value))); } -// static -void CryptoTestUtils::GenerateFullCHLO( - const CryptoHandshakeMessage& inchoate_chlo, - QuicCryptoServerConfig* crypto_config, - QuicSocketAddress server_addr, - QuicSocketAddress client_addr, - QuicVersion version, - const QuicClock* clock, - QuicReferenceCountedPointer<QuicSignedServerConfig> proof, - QuicCompressedCertsCache* compressed_certs_cache, - CryptoHandshakeMessage* out) { +void GenerateFullCHLO(const CryptoHandshakeMessage& inchoate_chlo, + QuicCryptoServerConfig* crypto_config, + QuicSocketAddress server_addr, + QuicSocketAddress client_addr, + QuicVersion version, + const QuicClock* clock, + QuicReferenceCountedPointer<QuicSignedServerConfig> proof, + QuicCompressedCertsCache* compressed_certs_cache, + CryptoHandshakeMessage* out) { // Pass a inchoate CHLO. FullChloGenerator generator(crypto_config, server_addr, client_addr, clock, proof, compressed_certs_cache, out); @@ -1023,5 +982,6 @@ void CryptoTestUtils::GenerateFullCHLO( generator.GetValidateClientHelloCallback()); } +} // namespace crypto_test_utils } // namespace test } // namespace net diff --git a/chromium/net/quic/test_tools/crypto_test_utils.h b/chromium/net/quic/test_tools/crypto_test_utils.h index 8c3565d1447..0ed27ec24fc 100644 --- a/chromium/net/quic/test_tools/crypto_test_utils.h +++ b/chromium/net/quic/test_tools/crypto_test_utils.h @@ -17,6 +17,7 @@ #include "net/quic/core/quic_framer.h" #include "net/quic/core/quic_packets.h" #include "net/quic/test_tools/quic_test_utils.h" +#include "third_party/boringssl/src/include/openssl/evp.h" namespace net { @@ -38,207 +39,229 @@ namespace test { class PacketSavingConnection; -class CryptoTestUtils { +class TestChannelIDKey : public ChannelIDKey { public: - // An interface for a source of callbacks. This is used for invoking - // callbacks asynchronously. - // - // Call the RunPendingCallbacks method regularly to run the callbacks from - // this source. - class CallbackSource { - public: - virtual ~CallbackSource() {} - - // Runs pending callbacks from this source. If there is no pending - // callback, does nothing. - virtual void RunPendingCallbacks() = 0; - }; - - // FakeServerOptions bundles together a number of options for configuring the - // server in HandshakeWithFakeServer. - struct FakeServerOptions { - FakeServerOptions(); - ~FakeServerOptions(); - - // The Token Binding params that the server supports and will negotiate. - QuicTagVector token_binding_params; - }; - - // FakeClientOptions bundles together a number of options for configuring - // HandshakeWithFakeClient. - struct FakeClientOptions { - FakeClientOptions(); - ~FakeClientOptions(); - - // If channel_id_enabled is true then the client will attempt to send a - // ChannelID. - bool channel_id_enabled; - - // If channel_id_source_async is true then the client will use an async - // ChannelIDSource for testing. Ignored if channel_id_enabled is false. - bool channel_id_source_async; - - // The Token Binding params that the client supports and will negotiate. - QuicTagVector token_binding_params; - }; - - // returns: the number of client hellos that the client sent. - static int HandshakeWithFakeServer(QuicConfig* server_quic_config, - MockQuicConnectionHelper* helper, - MockAlarmFactory* alarm_factory, - PacketSavingConnection* client_conn, - QuicCryptoClientStream* client, - const FakeServerOptions& options); - - // returns: the number of client hellos that the client sent. - static int HandshakeWithFakeClient(MockQuicConnectionHelper* helper, - MockAlarmFactory* alarm_factory, - PacketSavingConnection* server_conn, - QuicCryptoServerStream* server, - const QuicServerId& server_id, - const FakeClientOptions& options); - - // SetupCryptoServerConfigForTest configures |crypto_config| - // with sensible defaults for testing. - static void SetupCryptoServerConfigForTest( - const QuicClock* clock, - QuicRandom* rand, - QuicCryptoServerConfig* crypto_config, - const FakeServerOptions& options); - - // CommunicateHandshakeMessages moves messages from |client| to |server| and - // back until |clients|'s handshake has completed. - static void CommunicateHandshakeMessages(PacketSavingConnection* client_conn, - QuicCryptoStream* client, - PacketSavingConnection* server_conn, - QuicCryptoStream* server); - - // CommunicateHandshakeMessagesAndRunCallbacks moves messages from |client| - // to |server| and back until |client|'s handshake has completed. If - // |callback_source| is not nullptr, - // CommunicateHandshakeMessagesAndRunCallbacks also runs callbacks from - // |callback_source| between processing messages. - static void CommunicateHandshakeMessagesAndRunCallbacks( - PacketSavingConnection* client_conn, - QuicCryptoStream* client, - PacketSavingConnection* server_conn, - QuicCryptoStream* server, - CallbackSource* callback_source); - - // AdvanceHandshake attempts to moves messages from |client| to |server| and - // |server| to |client|. Returns the number of messages moved. - static std::pair<size_t, size_t> AdvanceHandshake( - PacketSavingConnection* client_conn, - QuicCryptoStream* client, - size_t client_i, - PacketSavingConnection* server_conn, - QuicCryptoStream* server, - size_t server_i); - - // Returns the value for the tag |tag| in the tag value map of |message|. - static std::string GetValueForTag(const CryptoHandshakeMessage& message, - QuicTag tag); - - // Returns a new |ProofSource| that serves up test certificates. - static std::unique_ptr<ProofSource> ProofSourceForTesting(); - - // Identical to |ProofSourceForTesting|, with the addition of setting - // the |emit_expect_ct_header| field on the test certificates - // to be the value of |send_expect_ct_header|. - static std::unique_ptr<ProofSource> ProofSourceForTesting( - bool send_expect_ct_header); - - // Returns a new |ProofVerifier| that uses the QUIC testing root CA. - static std::unique_ptr<ProofVerifier> ProofVerifierForTesting(); - - // Returns a hash of the leaf test certificate. - static uint64_t LeafCertHashForTesting(); - - // Returns a |ProofVerifyContext| that must be used with the verifier - // returned by |ProofVerifierForTesting|. - static ProofVerifyContext* ProofVerifyContextForTesting(); - - // MockCommonCertSets returns a CommonCertSets that contains a single set with - // hash |hash|, consisting of the certificate |cert| at index |index|. - static CommonCertSets* MockCommonCertSets(base::StringPiece cert, - uint64_t hash, - uint32_t index); - - // Creates a minimal dummy reject message that will pass the client-config - // validation tests. This will include a server config, but no certs, proof - // source address token, or server nonce. - static void FillInDummyReject(CryptoHandshakeMessage* rej, - bool reject_is_stateless); - - // ParseTag returns a QuicTag from parsing |tagstr|. |tagstr| may either be - // in the format "EXMP" (i.e. ASCII format), or "#11223344" (an explicit hex - // format). It CHECK fails if there's a parse error. - static QuicTag ParseTag(const char* tagstr); - - // Message constructs a handshake message from a variable number of - // arguments. |message_tag| is passed to |ParseTag| and used as the tag of - // the resulting message. The arguments are taken in pairs and nullptr - // terminated. The first of each pair is the tag of a tag/value and is given - // as an argument to |ParseTag|. The second is the value of the tag/value - // pair and is either a hex dump, preceeded by a '#', or a raw value. - // - // Message( - // "CHLO", - // "NOCE", "#11223344", - // "SNI", "www.example.com", - // nullptr); - static CryptoHandshakeMessage Message(const char* message_tag, ...); - - // ChannelIDSourceForTesting returns a ChannelIDSource that generates keys - // deterministically based on the hostname given in the GetChannelIDKey call. - // This ChannelIDSource works in synchronous mode, i.e., its GetChannelIDKey - // method never returns QUIC_PENDING. - static ChannelIDSource* ChannelIDSourceForTesting(); - - // MovePackets parses crypto handshake messages from packet number - // |*inout_packet_index| through to the last packet (or until a packet fails - // to decrypt) and has |dest_stream| process them. |*inout_packet_index| is - // updated with an index one greater than the last packet processed. - static void MovePackets(PacketSavingConnection* source_conn, - size_t* inout_packet_index, - QuicCryptoStream* dest_stream, - PacketSavingConnection* dest_conn, - Perspective dest_perspective); - - // Return an inchoate CHLO with some basic tag value pairs. - static CryptoHandshakeMessage GenerateDefaultInchoateCHLO( - const QuicClock* clock, - QuicVersion version, - QuicCryptoServerConfig* crypto_config); - - // Takes a inchoate CHLO, returns a full CHLO in |out| which can pass - // |crypto_config|'s validation. - static void GenerateFullCHLO( - const CryptoHandshakeMessage& inchoate_chlo, - QuicCryptoServerConfig* crypto_config, - QuicSocketAddress server_addr, - QuicSocketAddress client_addr, - QuicVersion version, - const QuicClock* clock, - QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config, - QuicCompressedCertsCache* compressed_certs_cache, - CryptoHandshakeMessage* out); + explicit TestChannelIDKey(EVP_PKEY* ecdsa_key); + ~TestChannelIDKey() override; + + // ChannelIDKey implementation. + + bool Sign(base::StringPiece signed_data, + std::string* out_signature) const override; + + std::string SerializeKey() const override; + + const EVP_PKEY* get_evp_pkey() const { return ecdsa_key_.get(); } + + private: + bssl::UniquePtr<EVP_PKEY> ecdsa_key_; +}; + +class TestChannelIDSource : public ChannelIDSource { + public: + ~TestChannelIDSource() override; + + // ChannelIDSource implementation. + + QuicAsyncStatus GetChannelIDKey( + const std::string& hostname, + std::unique_ptr<ChannelIDKey>* channel_id_key, + ChannelIDSourceCallback* /*callback*/) override; private: - static void CompareClientAndServerKeys(QuicCryptoClientStream* client, - QuicCryptoServerStream* server); + static EVP_PKEY* HostnameToKey(const std::string& hostname); +}; - // Return a CHLO nonce in hexadecimal. - static std::string GenerateClientNonceHex( - const QuicClock* clock, - QuicCryptoServerConfig* crypto_config); +namespace crypto_test_utils { - // Return a CHLO PUBS in hexadecimal. - static std::string GenerateClientPublicValuesHex(); +// An interface for a source of callbacks. This is used for invoking +// callbacks asynchronously. +// +// Call the RunPendingCallbacks method regularly to run the callbacks from +// this source. +class CallbackSource { + public: + virtual ~CallbackSource() {} - DISALLOW_COPY_AND_ASSIGN(CryptoTestUtils); + // Runs pending callbacks from this source. If there is no pending + // callback, does nothing. + virtual void RunPendingCallbacks() = 0; }; +// FakeServerOptions bundles together a number of options for configuring the +// server in HandshakeWithFakeServer. +struct FakeServerOptions { + FakeServerOptions(); + ~FakeServerOptions(); + + // The Token Binding params that the server supports and will negotiate. + QuicTagVector token_binding_params; +}; + +// FakeClientOptions bundles together a number of options for configuring +// HandshakeWithFakeClient. +struct FakeClientOptions { + FakeClientOptions(); + ~FakeClientOptions(); + + // If channel_id_enabled is true then the client will attempt to send a + // ChannelID. + bool channel_id_enabled; + + // If channel_id_source_async is true then the client will use an async + // ChannelIDSource for testing. Ignored if channel_id_enabled is false. + bool channel_id_source_async; + + // The Token Binding params that the client supports and will negotiate. + QuicTagVector token_binding_params; +}; + +// returns: the number of client hellos that the client sent. +int HandshakeWithFakeServer(QuicConfig* server_quic_config, + MockQuicConnectionHelper* helper, + MockAlarmFactory* alarm_factory, + PacketSavingConnection* client_conn, + QuicCryptoClientStream* client, + const FakeServerOptions& options); + +// returns: the number of client hellos that the client sent. +int HandshakeWithFakeClient(MockQuicConnectionHelper* helper, + MockAlarmFactory* alarm_factory, + PacketSavingConnection* server_conn, + QuicCryptoServerStream* server, + const QuicServerId& server_id, + const FakeClientOptions& options); + +// SetupCryptoServerConfigForTest configures |crypto_config| +// with sensible defaults for testing. +void SetupCryptoServerConfigForTest(const QuicClock* clock, + QuicRandom* rand, + QuicCryptoServerConfig* crypto_config, + const FakeServerOptions& options); + +// CommunicateHandshakeMessages moves messages from |client| to |server| and +// back until |clients|'s handshake has completed. +void CommunicateHandshakeMessages(PacketSavingConnection* client_conn, + QuicCryptoStream* client, + PacketSavingConnection* server_conn, + QuicCryptoStream* server); + +// CommunicateHandshakeMessagesAndRunCallbacks moves messages from |client| +// to |server| and back until |client|'s handshake has completed. If +// |callback_source| is not nullptr, +// CommunicateHandshakeMessagesAndRunCallbacks also runs callbacks from +// |callback_source| between processing messages. +void CommunicateHandshakeMessagesAndRunCallbacks( + PacketSavingConnection* client_conn, + QuicCryptoStream* client, + PacketSavingConnection* server_conn, + QuicCryptoStream* server, + CallbackSource* callback_source); + +// AdvanceHandshake attempts to moves messages from |client| to |server| and +// |server| to |client|. Returns the number of messages moved. +std::pair<size_t, size_t> AdvanceHandshake(PacketSavingConnection* client_conn, + QuicCryptoStream* client, + size_t client_i, + PacketSavingConnection* server_conn, + QuicCryptoStream* server, + size_t server_i); + +// Returns the value for the tag |tag| in the tag value map of |message|. +std::string GetValueForTag(const CryptoHandshakeMessage& message, QuicTag tag); + +// Returns a new |ProofSource| that serves up test certificates. +std::unique_ptr<ProofSource> ProofSourceForTesting(); + +// Returns a new |ProofVerifier| that uses the QUIC testing root CA. +std::unique_ptr<ProofVerifier> ProofVerifierForTesting(); + +// Returns a hash of the leaf test certificate. +uint64_t LeafCertHashForTesting(); + +// Returns a |ProofVerifyContext| that must be used with the verifier +// returned by |ProofVerifierForTesting|. +ProofVerifyContext* ProofVerifyContextForTesting(); + +// MockCommonCertSets returns a CommonCertSets that contains a single set with +// hash |hash|, consisting of the certificate |cert| at index |index|. +CommonCertSets* MockCommonCertSets(base::StringPiece cert, + uint64_t hash, + uint32_t index); + +// Creates a minimal dummy reject message that will pass the client-config +// validation tests. This will include a server config, but no certs, proof +// source address token, or server nonce. +void FillInDummyReject(CryptoHandshakeMessage* rej, bool reject_is_stateless); + +// ParseTag returns a QuicTag from parsing |tagstr|. |tagstr| may either be +// in the format "EXMP" (i.e. ASCII format), or "#11223344" (an explicit hex +// format). It CHECK fails if there's a parse error. +QuicTag ParseTag(const char* tagstr); + +// Message constructs a CHLO message from a provided vector of tag/value pairs. +// The first of each pair is the tag of a tag/value and is given as an argument +// to |ParseTag|. The second is the value of the tag/value pair and is either a +// hex dump, preceeded by a '#', or a raw value. If minimum_size_bytes is +// provided then the message will be padded to this minimum size. +// +// CreateCHLO( +// {{"NOCE", "#11223344"}, +// {"SNI", "www.example.com"}}, +// optional_minimum_size_bytes); +CryptoHandshakeMessage CreateCHLO( + std::vector<std::pair<std::string, std::string>> tags_and_values); +CryptoHandshakeMessage CreateCHLO( + std::vector<std::pair<std::string, std::string>> tags_and_values, + int minimum_size_bytes); + +// ChannelIDSourceForTesting returns a ChannelIDSource that generates keys +// deterministically based on the hostname given in the GetChannelIDKey call. +// This ChannelIDSource works in synchronous mode, i.e., its GetChannelIDKey +// method never returns QUIC_PENDING. +ChannelIDSource* ChannelIDSourceForTesting(); + +// MovePackets parses crypto handshake messages from packet number +// |*inout_packet_index| through to the last packet (or until a packet fails +// to decrypt) and has |dest_stream| process them. |*inout_packet_index| is +// updated with an index one greater than the last packet processed. +void MovePackets(PacketSavingConnection* source_conn, + size_t* inout_packet_index, + QuicCryptoStream* dest_stream, + PacketSavingConnection* dest_conn, + Perspective dest_perspective); + +// Return an inchoate CHLO with some basic tag value pairs. +CryptoHandshakeMessage GenerateDefaultInchoateCHLO( + const QuicClock* clock, + QuicVersion version, + QuicCryptoServerConfig* crypto_config); + +// Takes a inchoate CHLO, returns a full CHLO in |out| which can pass +// |crypto_config|'s validation. +void GenerateFullCHLO( + const CryptoHandshakeMessage& inchoate_chlo, + QuicCryptoServerConfig* crypto_config, + QuicSocketAddress server_addr, + QuicSocketAddress client_addr, + QuicVersion version, + const QuicClock* clock, + QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config, + QuicCompressedCertsCache* compressed_certs_cache, + CryptoHandshakeMessage* out); + +void CompareClientAndServerKeys(QuicCryptoClientStream* client, + QuicCryptoServerStream* server); + +// Return a CHLO nonce in hexadecimal. +std::string GenerateClientNonceHex(const QuicClock* clock, + QuicCryptoServerConfig* crypto_config); + +// Return a CHLO PUBS in hexadecimal. +std::string GenerateClientPublicValuesHex(); + +} // namespace crypto_test_utils + } // namespace test } // namespace net diff --git a/chromium/net/quic/test_tools/crypto_test_utils_test.cc b/chromium/net/quic/test_tools/crypto_test_utils_test.cc index 85069446e41..2349f1f9c51 100644 --- a/chromium/net/quic/test_tools/crypto_test_utils_test.cc +++ b/chromium/net/quic/test_tools/crypto_test_utils_test.cc @@ -112,7 +112,7 @@ TEST(CryptoTestUtilsTest, TestGenerateFullCHLO) { MockClock clock; QuicCryptoServerConfig crypto_config( QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(), - CryptoTestUtils::ProofSourceForTesting()); + crypto_test_utils::ProofSourceForTesting()); QuicSocketAddress server_addr; QuicSocketAddress client_addr(QuicIpAddress::Loopback4(), 1); QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config( @@ -148,23 +148,19 @@ TEST(CryptoTestUtilsTest, TestGenerateFullCHLO) { "#" + QuicTextUtils::HexEncode(public_value, sizeof(public_value)); QuicVersion version(AllSupportedVersions().front()); - // clang-format off - CryptoHandshakeMessage inchoate_chlo = CryptoTestUtils::Message( - "CHLO", - "PDMD", "X509", - "AEAD", "AESG", - "KEXS", "C255", - "COPT", "SREJ", - "PUBS", pub_hex.c_str(), - "NONC", nonce_hex.c_str(), - "VER\0", QuicTagToString(QuicVersionToQuicTag(version)).c_str(), - "$padding", static_cast<int>(kClientHelloMinimumSize), - nullptr); - // clang-format on - - CryptoTestUtils::GenerateFullCHLO(inchoate_chlo, &crypto_config, server_addr, - client_addr, version, &clock, signed_config, - &compressed_certs_cache, &full_chlo); + CryptoHandshakeMessage inchoate_chlo = crypto_test_utils::CreateCHLO( + {{"PDMD", "X509"}, + {"AEAD", "AESG"}, + {"KEXS", "C255"}, + {"COPT", "SREJ"}, + {"PUBS", pub_hex}, + {"NONC", nonce_hex}, + {"VER\0", QuicTagToString(QuicVersionToQuicTag(version))}}, + kClientHelloMinimumSize); + + crypto_test_utils::GenerateFullCHLO( + inchoate_chlo, &crypto_config, server_addr, client_addr, version, &clock, + signed_config, &compressed_certs_cache, &full_chlo); // Verify that full_chlo can pass crypto_config's verification. ShloVerifier shlo_verifier(&crypto_config, server_addr, client_addr, &clock, signed_config, &compressed_certs_cache); diff --git a/chromium/net/quic/test_tools/delayed_verify_strike_register_client.h b/chromium/net/quic/test_tools/delayed_verify_strike_register_client.h index cb87f2fc979..c67aedbda25 100644 --- a/chromium/net/quic/test_tools/delayed_verify_strike_register_client.h +++ b/chromium/net/quic/test_tools/delayed_verify_strike_register_client.h @@ -5,8 +5,7 @@ #ifndef NET_QUIC_TEST_TOOLS_DELAYED_VERIFY_STRIKE_REGISTER_CLIENT_H_ #define NET_QUIC_TEST_TOOLS_DELAYED_VERIFY_STRIKE_REGISTER_CLIENT_H_ -#include <stdint.h> - +#include <cstdint> #include <string> #include <vector> diff --git a/chromium/net/quic/test_tools/failing_proof_source.cc b/chromium/net/quic/test_tools/failing_proof_source.cc index 53b69e19c85..a45bf5264de 100644 --- a/chromium/net/quic/test_tools/failing_proof_source.cc +++ b/chromium/net/quic/test_tools/failing_proof_source.cc @@ -7,18 +7,6 @@ namespace net { namespace test { -bool FailingProofSource::GetProof( - const QuicSocketAddress& server_address, - const std::string& hostname, - const std::string& server_config, - QuicVersion quic_version, - base::StringPiece chlo_hash, - const QuicTagVector& connection_options, - QuicReferenceCountedPointer<ProofSource::Chain>* out_chain, - QuicCryptoProof* out_proof) { - return false; -} - void FailingProofSource::GetProof(const QuicSocketAddress& server_address, const std::string& hostname, const std::string& server_config, diff --git a/chromium/net/quic/test_tools/failing_proof_source.h b/chromium/net/quic/test_tools/failing_proof_source.h index 67aa44e0a89..dfc72fe32fe 100644 --- a/chromium/net/quic/test_tools/failing_proof_source.h +++ b/chromium/net/quic/test_tools/failing_proof_source.h @@ -12,15 +12,6 @@ namespace test { class FailingProofSource : public ProofSource { public: - bool GetProof(const QuicSocketAddress& server_address, - const std::string& hostname, - const std::string& server_config, - QuicVersion quic_version, - base::StringPiece chlo_hash, - const QuicTagVector& connection_options, - QuicReferenceCountedPointer<ProofSource::Chain>* out_chain, - QuicCryptoProof* out_proof) override; - void GetProof(const QuicSocketAddress& server_address, const std::string& hostname, const std::string& server_config, diff --git a/chromium/net/quic/test_tools/fake_proof_source.cc b/chromium/net/quic/test_tools/fake_proof_source.cc index e4360195b83..296384ee8bf 100644 --- a/chromium/net/quic/test_tools/fake_proof_source.cc +++ b/chromium/net/quic/test_tools/fake_proof_source.cc @@ -2,8 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/quic/platform/api/quic_logging.h" #include "net/quic/test_tools/fake_proof_source.h" + +#include "net/quic/platform/api/quic_logging.h" #include "net/quic/test_tools/crypto_test_utils.h" using std::string; @@ -12,15 +13,15 @@ namespace net { namespace test { FakeProofSource::FakeProofSource() - : delegate_(CryptoTestUtils::ProofSourceForTesting()) {} + : delegate_(crypto_test_utils::ProofSourceForTesting()) {} FakeProofSource::~FakeProofSource() {} FakeProofSource::Params::Params(const QuicSocketAddress& server_addr, - std::string hostname, - std::string server_config, + string hostname, + string server_config, QuicVersion quic_version, - std::string chlo_hash, + string chlo_hash, const QuicTagVector& connection_options, std::unique_ptr<ProofSource::Callback> callback) : server_address(server_addr), @@ -42,21 +43,6 @@ void FakeProofSource::Activate() { active_ = true; } -bool FakeProofSource::GetProof( - const QuicSocketAddress& server_address, - const string& hostname, - const string& server_config, - QuicVersion quic_version, - StringPiece chlo_hash, - const QuicTagVector& connection_options, - QuicReferenceCountedPointer<ProofSource::Chain>* out_chain, - QuicCryptoProof* out_proof) { - QUIC_LOG(WARNING) << "Synchronous GetProof called"; - return delegate_->GetProof(server_address, hostname, server_config, - quic_version, chlo_hash, connection_options, - out_chain, out_proof); -} - void FakeProofSource::GetProof( const QuicSocketAddress& server_address, const string& hostname, @@ -66,16 +52,11 @@ void FakeProofSource::GetProof( const QuicTagVector& connection_options, std::unique_ptr<ProofSource::Callback> callback) { if (!active_) { - QuicReferenceCountedPointer<Chain> chain; - QuicCryptoProof proof; - const bool ok = - GetProof(server_address, hostname, server_config, quic_version, - chlo_hash, connection_options, &chain, &proof); - callback->Run(ok, chain, proof, /* details = */ nullptr); + delegate_->GetProof(server_address, hostname, server_config, quic_version, + chlo_hash, connection_options, std::move(callback)); return; } - QUIC_LOG(WARNING) << "Asynchronous GetProof called"; params_.push_back(Params{server_address, hostname, server_config, quic_version, chlo_hash.as_string(), connection_options, std::move(callback)}); @@ -88,16 +69,14 @@ int FakeProofSource::NumPendingCallbacks() const { void FakeProofSource::InvokePendingCallback(int n) { CHECK(NumPendingCallbacks() > n); - const Params& params = params_[n]; + Params& params = params_[n]; - QuicReferenceCountedPointer<ProofSource::Chain> chain; - QuicCryptoProof proof; - const bool ok = delegate_->GetProof( - params.server_address, params.hostname, params.server_config, - params.quic_version, params.chlo_hash, params.connection_options, &chain, - &proof); + // Note: relies on the callback being invoked synchronously + delegate_->GetProof(params.server_address, params.hostname, + params.server_config, params.quic_version, + params.chlo_hash, params.connection_options, + std::move(params.callback)); - params.callback->Run(ok, chain, proof, /* details = */ nullptr); auto it = params_.begin() + n; params_.erase(it); } diff --git a/chromium/net/quic/test_tools/fake_proof_source.h b/chromium/net/quic/test_tools/fake_proof_source.h index 776466d6645..b6713f37716 100644 --- a/chromium/net/quic/test_tools/fake_proof_source.h +++ b/chromium/net/quic/test_tools/fake_proof_source.h @@ -30,14 +30,6 @@ class FakeProofSource : public ProofSource { void Activate(); // ProofSource interface - bool GetProof(const QuicSocketAddress& server_address, - const std::string& hostname, - const std::string& server_config, - QuicVersion quic_version, - base::StringPiece chlo_hash, - const QuicTagVector& connection_options, - QuicReferenceCountedPointer<ProofSource::Chain>* out_chain, - QuicCryptoProof* out_proof) override; void GetProof(const QuicSocketAddress& server_address, const std::string& hostname, const std::string& server_config, diff --git a/chromium/net/quic/test_tools/mock_crypto_client_stream.cc b/chromium/net/quic/test_tools/mock_crypto_client_stream.cc index 25ba8684ce5..2f0089a2625 100644 --- a/chromium/net/quic/test_tools/mock_crypto_client_stream.cc +++ b/chromium/net/quic/test_tools/mock_crypto_client_stream.cc @@ -44,9 +44,8 @@ void MockCryptoClientStream::OnHandshakeMessage( void MockCryptoClientStream::CryptoConnect() { if (proof_verify_details_) { - bool unused = false; if (!proof_verify_details_->cert_verify_result.verified_cert - ->VerifyNameMatch(server_id_.host(), &unused)) { + ->VerifyNameMatch(server_id_.host(), false)) { handshake_confirmed_ = false; encryption_established_ = false; session()->connection()->CloseConnection( @@ -101,6 +100,11 @@ void MockCryptoClientStream::CryptoConnect() { encryption_established_ = false; break; } + + case USE_DEFAULT_CRYPTO_STREAM: { + NOTREACHED(); + break; + } } } diff --git a/chromium/net/quic/test_tools/mock_crypto_client_stream.h b/chromium/net/quic/test_tools/mock_crypto_client_stream.h index 7c8b9fb1099..ffec4aa527a 100644 --- a/chromium/net/quic/test_tools/mock_crypto_client_stream.h +++ b/chromium/net/quic/test_tools/mock_crypto_client_stream.h @@ -20,6 +20,8 @@ namespace net { class MockCryptoClientStream : public QuicCryptoClientStream { public: + // TODO(zhongyi): might consider move HandshakeMode up to + // MockCryptoClientStreamFactory. // HandshakeMode enumerates the handshake mode MockCryptoClientStream should // mock in CryptoConnect. enum HandshakeMode { @@ -35,6 +37,11 @@ class MockCryptoClientStream : public QuicCryptoClientStream { // COLD_START indicates that CryptoConnect will neither establish encryption // nor confirm the handshake COLD_START, + + // USE_DEFAULT_CRYPTO_STREAM indicates that MockCryptoClientStreamFactory + // will create a QuicCryptoClientStream instead of a + // MockCryptoClientStream. + USE_DEFAULT_CRYPTO_STREAM, }; MockCryptoClientStream( diff --git a/chromium/net/quic/test_tools/mock_quic_spdy_client_stream.cc b/chromium/net/quic/test_tools/mock_quic_spdy_client_stream.cc index 874f89f675d..6da6fd0ee77 100644 --- a/chromium/net/quic/test_tools/mock_quic_spdy_client_stream.cc +++ b/chromium/net/quic/test_tools/mock_quic_spdy_client_stream.cc @@ -4,8 +4,6 @@ #include "net/quic/test_tools/mock_quic_spdy_client_stream.h" -using net::QuicClientSession; - namespace net { namespace test { diff --git a/chromium/net/quic/test_tools/mock_quic_spdy_client_stream.h b/chromium/net/quic/test_tools/mock_quic_spdy_client_stream.h index 5522cb65465..e4ca6007195 100644 --- a/chromium/net/quic/test_tools/mock_quic_spdy_client_stream.h +++ b/chromium/net/quic/test_tools/mock_quic_spdy_client_stream.h @@ -10,14 +10,13 @@ #include "net/quic/core/quic_packets.h" #include "net/tools/quic/quic_spdy_client_stream.h" #include "testing/gmock/include/gmock/gmock.h" -// #include "testing/gtest/include/gtest/gtest.h" namespace net { namespace test { -class MockQuicSpdyClientStream : public net::QuicSpdyClientStream { +class MockQuicSpdyClientStream : public QuicSpdyClientStream { public: - MockQuicSpdyClientStream(QuicStreamId id, net::QuicClientSession* session); + MockQuicSpdyClientStream(QuicStreamId id, QuicClientSession* session); ~MockQuicSpdyClientStream() override; MOCK_METHOD1(OnStreamFrame, void(const QuicStreamFrame& frame)); diff --git a/chromium/net/quic/test_tools/mock_random.h b/chromium/net/quic/test_tools/mock_random.h index a3ed228146d..43765d29b82 100644 --- a/chromium/net/quic/test_tools/mock_random.h +++ b/chromium/net/quic/test_tools/mock_random.h @@ -5,9 +5,6 @@ #ifndef NET_QUIC_TEST_TOOLS_MOCK_RANDOM_H_ #define NET_QUIC_TEST_TOOLS_MOCK_RANDOM_H_ -#include <stddef.h> -#include <stdint.h> - #include "base/compiler_specific.h" #include "base/macros.h" #include "net/quic/core/crypto/quic_random.h" diff --git a/chromium/net/quic/test_tools/quic_config_peer.cc b/chromium/net/quic/test_tools/quic_config_peer.cc index 45cf42500ee..d22304b3587 100644 --- a/chromium/net/quic/test_tools/quic_config_peer.cc +++ b/chromium/net/quic/test_tools/quic_config_peer.cc @@ -69,11 +69,5 @@ void QuicConfigPeer::SetReceivedForceHolBlocking(QuicConfig* config) { config->force_hol_blocking_.SetReceivedValue(1); } -// static -void QuicConfigPeer::SetReceivedAlternateServerAddress(QuicConfig* config, - QuicSocketAddress addr) { - config->alternate_server_address_.SetReceivedValue(addr); -} - } // namespace test } // namespace net diff --git a/chromium/net/quic/test_tools/quic_config_peer.h b/chromium/net/quic/test_tools/quic_config_peer.h index 20c8f08d933..7c6691dd0fd 100644 --- a/chromium/net/quic/test_tools/quic_config_peer.h +++ b/chromium/net/quic/test_tools/quic_config_peer.h @@ -5,8 +5,6 @@ #ifndef NET_QUIC_TEST_TOOLS_QUIC_CONFIG_PEER_H_ #define NET_QUIC_TEST_TOOLS_QUIC_CONFIG_PEER_H_ -#include <stdint.h> - #include "base/macros.h" #include "net/quic/core/quic_config.h" #include "net/quic/core/quic_packets.h" @@ -33,6 +31,7 @@ class QuicConfigPeer { static void SetReceivedBytesForConnectionId(QuicConfig* config, uint32_t bytes); + static void SetReceivedDisableConnectionMigration(QuicConfig* config); static void SetReceivedMaxIncomingDynamicStreams(QuicConfig* config, @@ -43,9 +42,6 @@ class QuicConfigPeer { static void SetReceivedForceHolBlocking(QuicConfig* config); - static void SetReceivedAlternateServerAddress(QuicConfig* config, - QuicSocketAddress addr); - private: DISALLOW_COPY_AND_ASSIGN(QuicConfigPeer); }; diff --git a/chromium/net/quic/test_tools/quic_connection_peer.cc b/chromium/net/quic/test_tools/quic_connection_peer.cc index 11e34198cc9..8c2e1956134 100644 --- a/chromium/net/quic/test_tools/quic_connection_peer.cc +++ b/chromium/net/quic/test_tools/quic_connection_peer.cc @@ -4,7 +4,6 @@ #include "net/quic/test_tools/quic_connection_peer.h" -#include "base/stl_util.h" #include "net/quic/core/congestion_control/send_algorithm_interface.h" #include "net/quic/core/quic_flags.h" #include "net/quic/core/quic_packet_writer.h" @@ -216,13 +215,6 @@ QuicPacketHeader* QuicConnectionPeer::GetLastHeader( } // static -void QuicConnectionPeer::SetPacketNumberOfLastSentPacket( - QuicConnection* connection, - QuicPacketNumber number) { - connection->packet_number_of_last_sent_packet_ = number; -} - -// static QuicConnectionStats* QuicConnectionPeer::GetStats(QuicConnection* connection) { return &connection->stats_; } diff --git a/chromium/net/quic/test_tools/quic_connection_peer.h b/chromium/net/quic/test_tools/quic_connection_peer.h index 0a5c529b140..64e06855763 100644 --- a/chromium/net/quic/test_tools/quic_connection_peer.h +++ b/chromium/net/quic/test_tools/quic_connection_peer.h @@ -6,7 +6,6 @@ #define NET_QUIC_TEST_TOOLS_QUIC_CONNECTION_PEER_H_ #include "base/macros.h" -#include "net/base/ip_endpoint.h" #include "net/quic/core/quic_connection.h" #include "net/quic/core/quic_connection_stats.h" #include "net/quic/core/quic_packets.h" diff --git a/chromium/net/quic/test_tools/quic_crypto_server_config_peer.cc b/chromium/net/quic/test_tools/quic_crypto_server_config_peer.cc index d9a47f7747b..1be6ffc7f2d 100644 --- a/chromium/net/quic/test_tools/quic_crypto_server_config_peer.cc +++ b/chromium/net/quic/test_tools/quic_crypto_server_config_peer.cc @@ -4,8 +4,6 @@ #include "net/quic/test_tools/quic_crypto_server_config_peer.h" -#include <cstdarg> - #include "net/quic/test_tools/mock_clock.h" #include "net/quic/test_tools/mock_random.h" #include "net/quic/test_tools/quic_test_utils.h" @@ -97,44 +95,19 @@ string QuicCryptoServerConfigPeer::NewServerNonce(QuicRandom* rand, return server_config_->NewServerNonce(rand, now); } -void QuicCryptoServerConfigPeer::CheckConfigs(const char* server_config_id1, - ...) { - va_list ap; - va_start(ap, server_config_id1); - - std::vector<std::pair<ServerConfigID, bool>> expected; - bool first = true; - for (;;) { - const char* server_config_id; - if (first) { - server_config_id = server_config_id1; - first = false; - } else { - server_config_id = va_arg(ap, const char*); - } - - if (!server_config_id) { - break; - } - - // varargs will promote the value to an int so we have to read that from - // the stack and cast down. - const bool is_primary = static_cast<bool>(va_arg(ap, int)); - expected.push_back(std::make_pair(server_config_id, is_primary)); - } - - va_end(ap); - +void QuicCryptoServerConfigPeer::CheckConfigs( + std::vector<std::pair<string, bool>> expected_ids_and_status) { QuicReaderMutexLock locked(&server_config_->configs_lock_); - ASSERT_EQ(expected.size(), server_config_->configs_.size()) << ConfigsDebug(); + ASSERT_EQ(expected_ids_and_status.size(), server_config_->configs_.size()) + << ConfigsDebug(); for (const std::pair< const ServerConfigID, QuicReferenceCountedPointer<QuicCryptoServerConfig::Config>>& i : server_config_->configs_) { bool found = false; - for (std::pair<ServerConfigID, bool>& j : expected) { + for (std::pair<ServerConfigID, bool>& j : expected_ids_and_status) { if (i.first == j.first && i.second->is_primary == j.second) { found = true; j.first.clear(); diff --git a/chromium/net/quic/test_tools/quic_crypto_server_config_peer.h b/chromium/net/quic/test_tools/quic_crypto_server_config_peer.h index 310be87bf26..2b4bc053c75 100644 --- a/chromium/net/quic/test_tools/quic_crypto_server_config_peer.h +++ b/chromium/net/quic/test_tools/quic_crypto_server_config_peer.h @@ -60,24 +60,25 @@ class QuicCryptoServerConfigPeer { std::string NewServerNonce(QuicRandom* rand, QuicWallTime now) const; // CheckConfigs compares the state of the Configs in |server_config_| to the - // description given as arguments. The arguments are given as - // nullptr-terminated pairs. The first of each pair is the server config ID of - // a Config. The second is a boolean describing whether the config is the - // primary. For example: - // CheckConfigs(nullptr); // checks that no Configs are loaded. + // description given as arguments. + // The first of each pair is the server config ID of a Config. The second is a + // boolean describing whether the config is the primary. For example: + // CheckConfigs(std::vector<std::pair<ServerConfigID, bool>>()); // checks + // that no Configs are loaded. // // // Checks that exactly three Configs are loaded with the given IDs and // // status. // CheckConfigs( - // "id1", false, - // "id2", true, - // "id3", false, - // nullptr); - void CheckConfigs(const char* server_config_id1, ...); + // {{"id1", false}, + // {"id2", true}, + // {"id3", false}}); + void CheckConfigs( + std::vector<std::pair<ServerConfigID, bool>> expected_ids_and_status); // ConfigsDebug returns a string that contains debugging information about // the set of Configs loaded in |server_config_| and their status. - std::string ConfigsDebug(); + std::string ConfigsDebug() + SHARED_LOCKS_REQUIRED(server_config_->configs_lock_); void SelectNewPrimaryConfig(int seconds); diff --git a/chromium/net/quic/test_tools/quic_framer_peer.cc b/chromium/net/quic/test_tools/quic_framer_peer.cc index 9c873f7a21a..2f8df04c312 100644 --- a/chromium/net/quic/test_tools/quic_framer_peer.cc +++ b/chromium/net/quic/test_tools/quic_framer_peer.cc @@ -4,9 +4,9 @@ #include "net/quic/test_tools/quic_framer_peer.h" -#include "base/stl_util.h" #include "net/quic/core/quic_framer.h" #include "net/quic/core/quic_packets.h" +#include "net/quic/platform/api/quic_map_util.h" namespace net { namespace test { @@ -77,15 +77,5 @@ QuicPacketNumber QuicFramerPeer::GetLastPacketNumber(QuicFramer* framer) { return framer->last_packet_number_; } -// static -QuicPathId QuicFramerPeer::GetLastPathId(QuicFramer* framer) { - return framer->last_path_id_; -} - -// static -bool QuicFramerPeer::IsPathClosed(QuicFramer* framer, QuicPathId path_id) { - return base::ContainsKey(framer->closed_paths_, path_id); -} - } // namespace test } // namespace net diff --git a/chromium/net/quic/test_tools/quic_framer_peer.h b/chromium/net/quic/test_tools/quic_framer_peer.h index 7b8b17947a0..930f1645c0c 100644 --- a/chromium/net/quic/test_tools/quic_framer_peer.h +++ b/chromium/net/quic/test_tools/quic_framer_peer.h @@ -37,10 +37,6 @@ class QuicFramerPeer { static QuicPacketNumber GetLastPacketNumber(QuicFramer* framer); - static QuicPathId GetLastPathId(QuicFramer* framer); - - static bool IsPathClosed(QuicFramer* framer, QuicPathId path_id); - private: DISALLOW_COPY_AND_ASSIGN(QuicFramerPeer); }; diff --git a/chromium/net/quic/test_tools/quic_packet_creator_peer.cc b/chromium/net/quic/test_tools/quic_packet_creator_peer.cc index dacf23393e3..840eec894c9 100644 --- a/chromium/net/quic/test_tools/quic_packet_creator_peer.cc +++ b/chromium/net/quic/test_tools/quic_packet_creator_peer.cc @@ -15,11 +15,6 @@ bool QuicPacketCreatorPeer::SendVersionInPacket(QuicPacketCreator* creator) { } // static -bool QuicPacketCreatorPeer::SendPathIdInPacket(QuicPacketCreator* creator) { - return creator->send_path_id_in_packet_; -} - -// static void QuicPacketCreatorPeer::SetSendVersionInPacket( QuicPacketCreator* creator, bool send_version_in_packet) { @@ -27,12 +22,6 @@ void QuicPacketCreatorPeer::SetSendVersionInPacket( } // static -void QuicPacketCreatorPeer::SetSendPathIdInPacket(QuicPacketCreator* creator, - bool send_path_id_in_packet) { - creator->send_path_id_in_packet_ = send_path_id_in_packet; -} - -// static void QuicPacketCreatorPeer::SetPacketNumberLength( QuicPacketCreator* creator, QuicPacketNumberLength packet_number_length) { diff --git a/chromium/net/quic/test_tools/quic_packet_creator_peer.h b/chromium/net/quic/test_tools/quic_packet_creator_peer.h index 1cdb91b5dbc..5c190918b69 100644 --- a/chromium/net/quic/test_tools/quic_packet_creator_peer.h +++ b/chromium/net/quic/test_tools/quic_packet_creator_peer.h @@ -5,8 +5,6 @@ #ifndef NET_QUIC_TEST_TOOLS_QUIC_PACKET_CREATOR_PEER_H_ #define NET_QUIC_TEST_TOOLS_QUIC_PACKET_CREATOR_PEER_H_ -#include <stddef.h> - #include "base/macros.h" #include "net/quic/core/quic_iovector.h" #include "net/quic/core/quic_packets.h" @@ -19,12 +17,9 @@ namespace test { class QuicPacketCreatorPeer { public: static bool SendVersionInPacket(QuicPacketCreator* creator); - static bool SendPathIdInPacket(QuicPacketCreator* creator); static void SetSendVersionInPacket(QuicPacketCreator* creator, bool send_version_in_packet); - static void SetSendPathIdInPacket(QuicPacketCreator* creator, - bool send_path_id_in_packet); static void SetPacketNumberLength( QuicPacketCreator* creator, QuicPacketNumberLength packet_number_length); diff --git a/chromium/net/quic/test_tools/quic_received_packet_manager_peer.cc b/chromium/net/quic/test_tools/quic_received_packet_manager_peer.cc deleted file mode 100644 index 1e0ee002c4d..00000000000 --- a/chromium/net/quic/test_tools/quic_received_packet_manager_peer.cc +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/quic/test_tools/quic_received_packet_manager_peer.h" - -#include "net/quic/core/quic_packets.h" -#include "net/quic/core/quic_received_packet_manager.h" - -namespace net { -namespace test { - -// static -bool QuicReceivedPacketManagerPeer::DontWaitForPacketsBefore( - QuicReceivedPacketManager* received_packet_manager, - QuicPacketNumber least_unacked) { - return received_packet_manager->DontWaitForPacketsBefore(least_unacked); -} - -} // namespace test -} // namespace net diff --git a/chromium/net/quic/test_tools/quic_received_packet_manager_peer.h b/chromium/net/quic/test_tools/quic_received_packet_manager_peer.h deleted file mode 100644 index 43a9d2049c2..00000000000 --- a/chromium/net/quic/test_tools/quic_received_packet_manager_peer.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2013 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 NET_QUIC_TEST_TOOLS_QUIC_RECEIVED_PACKET_MANAGER_PEER_H_ -#define NET_QUIC_TEST_TOOLS_QUIC_RECEIVED_PACKET_MANAGER_PEER_H_ - -#include "base/macros.h" -#include "net/quic/core/quic_packets.h" - -namespace net { - -class QuicReceivedPacketManager; - -namespace test { - -class QuicReceivedPacketManagerPeer { - public: - static bool DontWaitForPacketsBefore( - QuicReceivedPacketManager* received_packet_manager, - QuicPacketNumber least_unacked); - - private: - DISALLOW_COPY_AND_ASSIGN(QuicReceivedPacketManagerPeer); -}; - -} // namespace test - -} // namespace net - -#endif // NET_QUIC_TEST_TOOLS_QUIC_RECEIVED_PACKET_MANAGER_PEER_H_ diff --git a/chromium/net/quic/test_tools/quic_sent_packet_manager_peer.cc b/chromium/net/quic/test_tools/quic_sent_packet_manager_peer.cc index d3039726ddd..c9632601f5d 100644 --- a/chromium/net/quic/test_tools/quic_sent_packet_manager_peer.cc +++ b/chromium/net/quic/test_tools/quic_sent_packet_manager_peer.cc @@ -4,10 +4,8 @@ #include "net/quic/test_tools/quic_sent_packet_manager_peer.h" -#include "base/stl_util.h" #include "net/quic/core/congestion_control/loss_detection_interface.h" #include "net/quic/core/congestion_control/send_algorithm_interface.h" -#include "net/quic/core/quic_flags.h" #include "net/quic/core/quic_packets.h" #include "net/quic/core/quic_sent_packet_manager.h" @@ -90,8 +88,8 @@ QuicTime QuicSentPacketManagerPeer::GetSentTime( QuicPacketNumber packet_number) { DCHECK(sent_packet_manager->unacked_packets_.IsUnacked(packet_number)); - return sent_packet_manager->unacked_packets_.GetTransmissionInfo( - packet_number) + return sent_packet_manager->unacked_packets_ + .GetTransmissionInfo(packet_number) .sent_time; } diff --git a/chromium/net/quic/test_tools/quic_sent_packet_manager_peer.h b/chromium/net/quic/test_tools/quic_sent_packet_manager_peer.h index 0ffbafc25ab..93c62e5cac3 100644 --- a/chromium/net/quic/test_tools/quic_sent_packet_manager_peer.h +++ b/chromium/net/quic/test_tools/quic_sent_packet_manager_peer.h @@ -5,8 +5,6 @@ #ifndef NET_QUIC_TEST_TOOLS_QUIC_SENT_PACKET_MANAGER_PEER_H_ #define NET_QUIC_TEST_TOOLS_QUIC_SENT_PACKET_MANAGER_PEER_H_ -#include <stddef.h> - #include "base/macros.h" #include "net/quic/core/quic_packets.h" #include "net/quic/core/quic_sent_packet_manager.h" diff --git a/chromium/net/quic/test_tools/quic_session_peer.cc b/chromium/net/quic/test_tools/quic_session_peer.cc index 6ad8a40ac5d..1e35b9628fc 100644 --- a/chromium/net/quic/test_tools/quic_session_peer.cc +++ b/chromium/net/quic/test_tools/quic_session_peer.cc @@ -4,9 +4,9 @@ #include "net/quic/test_tools/quic_session_peer.h" -#include "base/stl_util.h" #include "net/quic/core/quic_session.h" #include "net/quic/core/quic_stream.h" +#include "net/quic/platform/api/quic_map_util.h" namespace net { namespace test { @@ -90,13 +90,13 @@ bool QuicSessionPeer::IsStreamClosed(QuicSession* session, QuicStreamId id) { // static bool QuicSessionPeer::IsStreamCreated(QuicSession* session, QuicStreamId id) { DCHECK_NE(0u, id); - return base::ContainsKey(session->dynamic_streams(), id); + return QuicContainsKey(session->dynamic_streams(), id); } // static bool QuicSessionPeer::IsStreamAvailable(QuicSession* session, QuicStreamId id) { DCHECK_NE(0u, id); - return base::ContainsKey(session->available_streams_, id); + return QuicContainsKey(session->available_streams_, id); } // static diff --git a/chromium/net/quic/test_tools/quic_session_peer.h b/chromium/net/quic/test_tools/quic_session_peer.h index 8874c7ac961..a5915e8770f 100644 --- a/chromium/net/quic/test_tools/quic_session_peer.h +++ b/chromium/net/quic/test_tools/quic_session_peer.h @@ -5,8 +5,7 @@ #ifndef NET_QUIC_TEST_TOOLS_QUIC_SESSION_PEER_H_ #define NET_QUIC_TEST_TOOLS_QUIC_SESSION_PEER_H_ -#include <stdint.h> - +#include <cstdint> #include <map> #include <memory> diff --git a/chromium/net/quic/test_tools/quic_stream_factory_peer.cc b/chromium/net/quic/test_tools/quic_stream_factory_peer.cc index 03dbff80981..efd35980db4 100644 --- a/chromium/net/quic/test_tools/quic_stream_factory_peer.cc +++ b/chromium/net/quic/test_tools/quic_stream_factory_peer.cc @@ -35,6 +35,11 @@ bool QuicStreamFactoryPeer::HasActiveSession(QuicStreamFactory* factory, return factory->HasActiveSession(server_id); } +bool QuicStreamFactoryPeer::HasActiveJob(QuicStreamFactory* factory, + const QuicServerId& server_id) { + return factory->HasActiveJob(server_id); +} + bool QuicStreamFactoryPeer::HasActiveCertVerifierJob( QuicStreamFactory* factory, const QuicServerId& server_id) { @@ -174,7 +179,9 @@ void QuicStreamFactoryPeer::CacheDummyServerConfig( ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem")); DCHECK(cert); std::string der_bytes; - DCHECK(X509Certificate::GetDEREncoded(cert->os_cert_handle(), &der_bytes)); + bool success = + X509Certificate::GetDEREncoded(cert->os_cert_handle(), &der_bytes); + DCHECK(success); certs.push_back(der_bytes); QuicCryptoClientConfig* crypto_config = &factory->crypto_config_; diff --git a/chromium/net/quic/test_tools/quic_stream_factory_peer.h b/chromium/net/quic/test_tools/quic_stream_factory_peer.h index eeb1dc0907f..3387e1fe691 100644 --- a/chromium/net/quic/test_tools/quic_stream_factory_peer.h +++ b/chromium/net/quic/test_tools/quic_stream_factory_peer.h @@ -37,6 +37,9 @@ class QuicStreamFactoryPeer { static bool HasActiveSession(QuicStreamFactory* factory, const QuicServerId& server_id); + static bool HasActiveJob(QuicStreamFactory* factory, + const QuicServerId& server_id); + static bool HasActiveCertVerifierJob(QuicStreamFactory* factory, const QuicServerId& server_id); diff --git a/chromium/net/quic/test_tools/quic_stream_peer.cc b/chromium/net/quic/test_tools/quic_stream_peer.cc index b35ec1a1273..859bc6ac50c 100644 --- a/chromium/net/quic/test_tools/quic_stream_peer.cc +++ b/chromium/net/quic/test_tools/quic_stream_peer.cc @@ -41,31 +41,11 @@ bool QuicStreamPeer::FinSent(QuicStream* stream) { } // static -bool QuicStreamPeer::FinReceived(QuicStream* stream) { - return stream->fin_received_; -} - -// static bool QuicStreamPeer::RstSent(QuicStream* stream) { return stream->rst_sent_; } // static -bool QuicStreamPeer::RstReceived(QuicStream* stream) { - return stream->rst_received_; -} - -// static -bool QuicStreamPeer::ReadSideClosed(QuicStream* stream) { - return stream->read_side_closed_; -} - -// static -bool QuicStreamPeer::WriteSideClosed(QuicStream* stream) { - return stream->write_side_closed_; -} - -// static uint32_t QuicStreamPeer::SizeOfQueuedData(QuicStream* stream) { uint32_t total = 0; std::list<QuicStream::PendingData>::iterator it = @@ -93,9 +73,14 @@ void QuicStreamPeer::WriteOrBufferData( } // static -net::QuicStreamSequencer* QuicStreamPeer::sequencer(QuicStream* stream) { +QuicStreamSequencer* QuicStreamPeer::sequencer(QuicStream* stream) { return &(stream->sequencer_); } +// static +QuicSession* QuicStreamPeer::session(QuicStream* stream) { + return stream->session(); +} + } // namespace test } // namespace net diff --git a/chromium/net/quic/test_tools/quic_stream_peer.h b/chromium/net/quic/test_tools/quic_stream_peer.h index 3d9b4f439e0..c0fa1063c3e 100644 --- a/chromium/net/quic/test_tools/quic_stream_peer.h +++ b/chromium/net/quic/test_tools/quic_stream_peer.h @@ -5,16 +5,16 @@ #ifndef NET_QUIC_TEST_TOOLS_QUIC_STREAM_PEER_H_ #define NET_QUIC_TEST_TOOLS_QUIC_STREAM_PEER_H_ -#include <stdint.h> +#include <cstdint> #include "base/macros.h" -#include "base/strings/string_piece.h" #include "net/quic/core/quic_packets.h" #include "net/quic/core/quic_stream_sequencer.h" namespace net { class QuicStream; +class QuicSession; namespace test { @@ -27,12 +27,7 @@ class QuicStreamPeer { static void CloseReadSide(QuicStream* stream); static bool FinSent(QuicStream* stream); - static bool FinReceived(QuicStream* stream); static bool RstSent(QuicStream* stream); - static bool RstReceived(QuicStream* stream); - - static bool ReadSideClosed(QuicStream* stream); - static bool WriteSideClosed(QuicStream* stream); static uint32_t SizeOfQueuedData(QuicStream* stream); @@ -44,13 +39,15 @@ class QuicStreamPeer { bool fin, QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener); - static net::QuicStreamSequencer* sequencer(QuicStream* stream); + static QuicStreamSequencer* sequencer(QuicStream* stream); + static QuicSession* session(QuicStream* stream); private: DISALLOW_COPY_AND_ASSIGN(QuicStreamPeer); }; } // namespace test + } // namespace net #endif // NET_QUIC_TEST_TOOLS_QUIC_STREAM_PEER_H_ diff --git a/chromium/net/quic/test_tools/quic_stream_sequencer_buffer_peer.h b/chromium/net/quic/test_tools/quic_stream_sequencer_buffer_peer.h index 68944f52dce..09898436eba 100644 --- a/chromium/net/quic/test_tools/quic_stream_sequencer_buffer_peer.h +++ b/chromium/net/quic/test_tools/quic_stream_sequencer_buffer_peer.h @@ -13,8 +13,7 @@ namespace test { class QuicStreamSequencerBufferPeer { public: - explicit QuicStreamSequencerBufferPeer( - net::QuicStreamSequencerBuffer* buffer); + explicit QuicStreamSequencerBufferPeer(QuicStreamSequencerBuffer* buffer); // Read from this buffer_ into the given destination buffer_ up to the // size of the destination. Returns the number of bytes read. Reading from @@ -33,27 +32,27 @@ class QuicStreamSequencerBufferPeer { size_t GetInBlockOffset(QuicStreamOffset offset); - net::QuicStreamSequencerBuffer::BufferBlock* GetBlock(size_t index); + QuicStreamSequencerBuffer::BufferBlock* GetBlock(size_t index); int GapSize(); - std::list<net::QuicStreamSequencerBuffer::Gap> GetGaps(); + std::list<QuicStreamSequencerBuffer::Gap> GetGaps(); size_t max_buffer_capacity(); size_t ReadableBytes(); - std::map<QuicStreamOffset, net::QuicStreamSequencerBuffer::FrameInfo>* + std::map<QuicStreamOffset, QuicStreamSequencerBuffer::FrameInfo>* frame_arrival_time_map(); void set_total_bytes_read(QuicStreamOffset total_bytes_read); - void set_gaps(const std::list<net::QuicStreamSequencerBuffer::Gap>& gaps); + void set_gaps(const std::list<QuicStreamSequencerBuffer::Gap>& gaps); bool IsBufferAllocated(); private: - net::QuicStreamSequencerBuffer* buffer_; + QuicStreamSequencerBuffer* buffer_; DISALLOW_COPY_AND_ASSIGN(QuicStreamSequencerBufferPeer); }; diff --git a/chromium/net/quic/test_tools/quic_stream_sequencer_peer.h b/chromium/net/quic/test_tools/quic_stream_sequencer_peer.h index cc63e71155c..9982e738977 100644 --- a/chromium/net/quic/test_tools/quic_stream_sequencer_peer.h +++ b/chromium/net/quic/test_tools/quic_stream_sequencer_peer.h @@ -5,8 +5,6 @@ #ifndef NET_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_PEER_H_ #define NET_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_PEER_H_ -#include <stddef.h> - #include "base/macros.h" #include "net/quic/core/quic_packets.h" diff --git a/chromium/net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h b/chromium/net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h index 5dbb4e383ed..594344e7f6b 100644 --- a/chromium/net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h +++ b/chromium/net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h @@ -5,7 +5,7 @@ #ifndef NET_QUIC_TEST_TOOLS_QUIC_SUSTAINED_BANDWIDTH_RECORDER_PEER_H_ #define NET_QUIC_TEST_TOOLS_QUIC_SUSTAINED_BANDWIDTH_RECORDER_PEER_H_ -#include <stdint.h> +#include <cstdint> #include "base/macros.h" #include "net/quic/core/quic_packets.h" diff --git a/chromium/net/quic/test_tools/quic_test_utils.cc b/chromium/net/quic/test_tools/quic_test_utils.cc index eb070011e63..1d2282d5553 100644 --- a/chromium/net/quic/test_tools/quic_test_utils.cc +++ b/chromium/net/quic/test_tools/quic_test_utils.cc @@ -13,6 +13,7 @@ #include "net/quic/core/crypto/quic_decrypter.h" #include "net/quic/core/crypto/quic_encrypter.h" #include "net/quic/core/quic_data_writer.h" +#include "net/quic/core/quic_flags.h" #include "net/quic/core/quic_framer.h" #include "net/quic/core/quic_packet_creator.h" #include "net/quic/core/quic_utils.h" @@ -21,16 +22,16 @@ #include "net/quic/test_tools/crypto_test_utils.h" #include "net/quic/test_tools/quic_connection_peer.h" #include "net/spdy/spdy_frame_builder.h" -#include "net/tools/quic/quic_per_connection_packet_writer.h" #include "third_party/boringssl/src/include/openssl/sha.h" using base::StringPiece; +using std::max; +using std::min; using std::string; -using testing::Invoke; using testing::_; +using testing::Invoke; namespace net { - namespace test { QuicAckFrame MakeAckFrame(QuicPacketNumber largest_observed) { @@ -78,7 +79,6 @@ QuicPacket* BuildUnsizedDataPacket(QuicFramer* framer, return new QuicPacket(buffer, length, /* owns_buffer */ true, header.public_header.connection_id_length, header.public_header.version_flag, - header.public_header.multipath_flag, header.public_header.nonce != nullptr, header.public_header.packet_number_length); } @@ -252,10 +252,9 @@ QuicArenaScopedPtr<QuicAlarm> MockAlarmFactory::CreateAlarm( QuicArenaScopedPtr<QuicAlarm::Delegate> delegate, QuicConnectionArena* arena) { if (arena != nullptr) { - return arena->New<MockAlarmFactory::TestAlarm>(std::move(delegate)); + return arena->New<TestAlarm>(std::move(delegate)); } else { - return QuicArenaScopedPtr<MockAlarmFactory::TestAlarm>( - new TestAlarm(std::move(delegate))); + return QuicArenaScopedPtr<TestAlarm>(new TestAlarm(std::move(delegate))); } } @@ -438,22 +437,6 @@ QuicCryptoServerStream* TestQuicSpdyServerSession::GetCryptoStream() { QuicServerSessionBase::GetCryptoStream()); } -TestPushPromiseDelegate::TestPushPromiseDelegate(bool match) - : match_(match), rendezvous_fired_(false), rendezvous_stream_(nullptr) {} - -bool TestPushPromiseDelegate::CheckVary( - const SpdyHeaderBlock& client_request, - const SpdyHeaderBlock& promise_request, - const SpdyHeaderBlock& promise_response) { - QUIC_DVLOG(1) << "match " << match_; - return match_; -} - -void TestPushPromiseDelegate::OnRendezvousResult(QuicSpdyStream* stream) { - rendezvous_fired_ = true; - rendezvous_stream_ = stream; -} - TestQuicSpdyClientSession::TestQuicSpdyClientSession( QuicConnection* connection, const QuicConfig& config, @@ -461,7 +444,7 @@ TestQuicSpdyClientSession::TestQuicSpdyClientSession( QuicCryptoClientConfig* crypto_config) : QuicClientSessionBase(connection, &push_promise_index_, config) { crypto_stream_.reset(new QuicCryptoClientStream( - server_id, this, CryptoTestUtils::ProofVerifyContextForTesting(), + server_id, this, crypto_test_utils::ProofVerifyContextForTesting(), crypto_config, this)); Initialize(); } @@ -476,6 +459,22 @@ QuicCryptoClientStream* TestQuicSpdyClientSession::GetCryptoStream() { return crypto_stream_.get(); } +TestPushPromiseDelegate::TestPushPromiseDelegate(bool match) + : match_(match), rendezvous_fired_(false), rendezvous_stream_(nullptr) {} + +bool TestPushPromiseDelegate::CheckVary( + const SpdyHeaderBlock& client_request, + const SpdyHeaderBlock& promise_request, + const SpdyHeaderBlock& promise_response) { + QUIC_DVLOG(1) << "match " << match_; + return match_; +} + +void TestPushPromiseDelegate::OnRendezvousResult(QuicSpdyStream* stream) { + rendezvous_fired_ = true; + rendezvous_stream_ = stream; +} + MockPacketWriter::MockPacketWriter() { ON_CALL(*this, GetMaxPacketSize(_)) .WillByDefault(testing::Return(kMaxPacketSize)); @@ -511,8 +510,8 @@ string HexDumpWithMarks(const char* data, const int kSizeLimit = 1024; if (length > kSizeLimit || mark_length > kSizeLimit) { QUIC_LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes."; - length = std::min(length, kSizeLimit); - mark_length = std::min(mark_length, kSizeLimit); + length = min(length, kSizeLimit); + mark_length = min(mark_length, kSizeLimit); } string hex; @@ -555,18 +554,6 @@ QuicVersion QuicVersionMin() { return AllSupportedVersions().back(); } -IPAddress Loopback4() { - return IPAddress::IPv4Localhost(); -} - -IPAddress Loopback6() { - return IPAddress::IPv6Localhost(); -} - -IPAddress Any4() { - return IPAddress::IPv4AllZeros(); -} - QuicEncryptedPacket* ConstructEncryptedPacket(QuicConnectionId connection_id, bool version_flag, bool multipath_flag, @@ -645,7 +632,7 @@ QuicEncryptedPacket* ConstructEncryptedPacket( EXPECT_TRUE(packet != nullptr); char* buffer = new char[kMaxPacketSize]; size_t encrypted_length = framer.EncryptPayload( - ENCRYPTION_NONE, path_id, packet_number, *packet, buffer, kMaxPacketSize); + ENCRYPTION_NONE, packet_number, *packet, buffer, kMaxPacketSize); EXPECT_NE(0u, encrypted_length); return new QuicEncryptedPacket(buffer, encrypted_length, true); } @@ -662,7 +649,6 @@ QuicReceivedPacket* ConstructReceivedPacket( QuicEncryptedPacket* ConstructMisFramedEncryptedPacket( QuicConnectionId connection_id, bool version_flag, - bool multipath_flag, bool reset_flag, QuicPathId path_id, QuicPacketNumber packet_number, @@ -675,7 +661,6 @@ QuicEncryptedPacket* ConstructMisFramedEncryptedPacket( header.public_header.connection_id = connection_id; header.public_header.connection_id_length = connection_id_length; header.public_header.version_flag = version_flag; - header.public_header.multipath_flag = multipath_flag; header.public_header.reset_flag = reset_flag; header.public_header.packet_number_length = packet_number_length; header.path_id = path_id; @@ -694,12 +679,12 @@ QuicEncryptedPacket* ConstructMisFramedEncryptedPacket( // Now set the frame type to 0x1F, which is an invalid frame type. reinterpret_cast<unsigned char*>( packet->mutable_data())[GetStartOfEncryptedData( - framer.version(), connection_id_length, version_flag, multipath_flag, + framer.version(), connection_id_length, version_flag, false /* no diversification nonce */, packet_number_length)] = 0x1F; char* buffer = new char[kMaxPacketSize]; size_t encrypted_length = framer.EncryptPayload( - ENCRYPTION_NONE, path_id, packet_number, *packet, buffer, kMaxPacketSize); + ENCRYPTION_NONE, packet_number, *packet, buffer, kMaxPacketSize); EXPECT_NE(0u, encrypted_length); return new QuicEncryptedPacket(buffer, encrypted_length, true); } @@ -710,8 +695,8 @@ void CompareCharArraysWithHexError(const string& description, const char* expected, const int expected_len) { EXPECT_EQ(actual_len, expected_len); - const int min_len = std::min(actual_len, expected_len); - const int max_len = std::max(actual_len, expected_len); + const int min_len = min(actual_len, expected_len); + const int max_len = max(actual_len, expected_len); std::unique_ptr<bool[]> marks(new bool[max_len]); bool identical = (actual_len == expected_len); for (int i = 0; i < min_len; ++i) { @@ -735,41 +720,8 @@ void CompareCharArraysWithHexError(const string& description, << HexDumpWithMarks(actual, actual_len, marks.get(), max_len); } -static QuicPacket* ConstructPacketFromHandshakeMessage( - QuicConnectionId connection_id, - const CryptoHandshakeMessage& message, - bool should_include_version) { - CryptoFramer crypto_framer; - std::unique_ptr<QuicData> data( - crypto_framer.ConstructHandshakeMessage(message)); - QuicFramer quic_framer(AllSupportedVersions(), QuicTime::Zero(), - Perspective::IS_CLIENT); - - QuicPacketHeader header; - header.public_header.connection_id = connection_id; - header.public_header.reset_flag = false; - header.public_header.version_flag = should_include_version; - header.packet_number = 1; - - QuicStreamFrame stream_frame(kCryptoStreamId, false, 0, - data->AsStringPiece()); - - QuicFrame frame(&stream_frame); - QuicFrames frames; - frames.push_back(frame); - return BuildUnsizedDataPacket(&quic_framer, header, frames); -} - -QuicPacket* ConstructHandshakePacket(QuicConnectionId connection_id, - QuicTag tag) { - CryptoHandshakeMessage message; - message.set_tag(tag); - return ConstructPacketFromHandshakeMessage(connection_id, message, false); -} - size_t GetPacketLengthForOneStream(QuicVersion version, bool include_version, - bool include_path_id, bool include_diversification_nonce, QuicConnectionIdLength connection_id_length, QuicPacketNumberLength packet_number_length, @@ -778,15 +730,14 @@ size_t GetPacketLengthForOneStream(QuicVersion version, const size_t stream_length = NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(*payload_length) + QuicPacketCreator::StreamFramePacketOverhead( - version, PACKET_8BYTE_CONNECTION_ID, include_version, include_path_id, + version, PACKET_8BYTE_CONNECTION_ID, include_version, include_diversification_nonce, packet_number_length, 0u); const size_t ack_length = NullEncrypter(Perspective::IS_CLIENT) .GetCiphertextSize(QuicFramer::GetMinAckFrameSize( version, PACKET_1BYTE_PACKET_NUMBER)) + GetPacketHeaderSize(version, connection_id_length, include_version, - include_path_id, include_diversification_nonce, - packet_number_length); + include_diversification_nonce, packet_number_length); if (stream_length < ack_length) { *payload_length = 1 + ack_length - stream_length; } @@ -794,7 +745,7 @@ size_t GetPacketLengthForOneStream(QuicVersion version, return NullEncrypter(Perspective::IS_CLIENT) .GetCiphertextSize(*payload_length) + QuicPacketCreator::StreamFramePacketOverhead( - version, connection_id_length, include_version, include_path_id, + version, connection_id_length, include_version, include_diversification_nonce, packet_number_length, 0u); } diff --git a/chromium/net/quic/test_tools/quic_test_utils.h b/chromium/net/quic/test_tools/quic_test_utils.h index 2f01fc0a821..5b53b4a6b54 100644 --- a/chromium/net/quic/test_tools/quic_test_utils.h +++ b/chromium/net/quic/test_tools/quic_test_utils.h @@ -7,9 +7,6 @@ #ifndef NET_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_ #define NET_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_ -#include <stddef.h> -#include <stdint.h> - #include <cstdint> #include <memory> #include <string> @@ -18,7 +15,6 @@ #include "base/macros.h" #include "base/strings/string_piece.h" -#include "net/base/ip_address.h" #include "net/quic/core/congestion_control/loss_detection_interface.h" #include "net/quic/core/congestion_control/send_algorithm_interface.h" #include "net/quic/core/quic_client_push_promise_index.h" @@ -26,18 +22,14 @@ #include "net/quic/core/quic_connection_close_delegate_interface.h" #include "net/quic/core/quic_framer.h" #include "net/quic/core/quic_iovector.h" -#include "net/quic/core/quic_packets.h" #include "net/quic/core/quic_sent_packet_manager.h" #include "net/quic/core/quic_server_session_base.h" -#include "net/quic/core/quic_session.h" #include "net/quic/core/quic_simple_buffer_allocator.h" #include "net/quic/test_tools/mock_clock.h" #include "net/quic/test_tools/mock_random.h" -#include "net/spdy/spdy_framer.h" #include "net/test/gtest_util.h" -#include "net/tools/quic/quic_dispatcher.h" #include "net/tools/quic/quic_per_connection_packet_writer.h" -#include "net/tools/quic/test_tools/mock_quic_server_session_visitor.h" +#include "net/tools/quic/test_tools/mock_quic_session_visitor.h" #include "testing/gmock/include/gmock/gmock.h" using base::StringPiece; @@ -73,15 +65,6 @@ QuicVersion QuicVersionMax(); // Lower limit on versions we support. QuicVersion QuicVersionMin(); -// Returns an address for 127.0.0.1. -IPAddress Loopback4(); - -// Returns an address for ::1. -IPAddress Loopback6(); - -// Returns an address for 0.0.0.0. -IPAddress Any4(); - // Create an encrypted packet for testing. // If versions == nullptr, uses &AllSupportedVersions(). // Note that the packet is encrypted with NullEncrypter, so to decrypt the @@ -152,7 +135,6 @@ QuicReceivedPacket* ConstructReceivedPacket( QuicEncryptedPacket* ConstructMisFramedEncryptedPacket( QuicConnectionId connection_id, bool version_flag, - bool multipath_flag, bool reset_flag, QuicPathId path_id, QuicPacketNumber packet_number, @@ -173,7 +155,6 @@ void CompareCharArraysWithHexError(const std::string& description, // of bytes of stream data that will fit in such a packet. size_t GetPacketLengthForOneStream(QuicVersion version, bool include_version, - bool include_path_id, bool include_diversification_nonce, QuicConnectionIdLength connection_id_length, QuicPacketNumberLength packet_number_length, @@ -672,8 +653,11 @@ class TestQuicSpdyServerSession : public QuicServerSessionBase { DISALLOW_COPY_AND_ASSIGN(TestQuicSpdyServerSession); }; +// A test implementation of QuicClientPushPromiseIndex::Delegate. class TestPushPromiseDelegate : public QuicClientPushPromiseIndex::Delegate { public: + // |match| sets the validation result for checking whether designated header + // fields match for promise request and client request. explicit TestPushPromiseDelegate(bool match); bool CheckVary(const SpdyHeaderBlock& client_request, @@ -851,9 +835,8 @@ class MockQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor { MOCK_METHOD1(OnFrameAddedToPacket, void(const QuicFrame&)); - MOCK_METHOD5(OnPacketSent, + MOCK_METHOD4(OnPacketSent, void(const SerializedPacket&, - QuicPathId, QuicPacketNumber, TransmissionType, QuicTime)); diff --git a/chromium/net/quic/test_tools/simple_quic_framer.h b/chromium/net/quic/test_tools/simple_quic_framer.h index d019f2903e6..ba9e988db5d 100644 --- a/chromium/net/quic/test_tools/simple_quic_framer.h +++ b/chromium/net/quic/test_tools/simple_quic_framer.h @@ -5,13 +5,10 @@ #ifndef NET_QUIC_TEST_TOOLS_SIMPLE_QUIC_FRAMER_H_ #define NET_QUIC_TEST_TOOLS_SIMPLE_QUIC_FRAMER_H_ -#include <stddef.h> - #include <memory> #include <vector> #include "base/macros.h" -#include "base/strings/string_piece.h" #include "net/quic/core/quic_framer.h" #include "net/quic/core/quic_packets.h" diff --git a/chromium/net/quic/test_tools/simulator/alarm_factory.cc b/chromium/net/quic/test_tools/simulator/alarm_factory.cc index 43eb54d020d..2f87b59abda 100644 --- a/chromium/net/quic/test_tools/simulator/alarm_factory.cc +++ b/chromium/net/quic/test_tools/simulator/alarm_factory.cc @@ -2,11 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/strings/stringprintf.h" #include "net/quic/core/quic_alarm.h" +#include "net/quic/platform/api/quic_str_cat.h" #include "net/quic/test_tools/simulator/alarm_factory.h" -using base::StringPrintf; using std::string; namespace net { @@ -60,7 +59,7 @@ AlarmFactory::~AlarmFactory() {} string AlarmFactory::GetNewAlarmName() { ++counter_; - return StringPrintf("%s (alarm %i)", name_.c_str(), counter_); + return QuicStringPrintf("%s (alarm %i)", name_.c_str(), counter_); } QuicAlarm* AlarmFactory::CreateAlarm(QuicAlarm::Delegate* delegate) { diff --git a/chromium/net/quic/test_tools/simulator/link.cc b/chromium/net/quic/test_tools/simulator/link.cc index 2ce999e39e4..2bc7499b520 100644 --- a/chromium/net/quic/test_tools/simulator/link.cc +++ b/chromium/net/quic/test_tools/simulator/link.cc @@ -4,10 +4,9 @@ #include "net/quic/test_tools/simulator/link.h" -#include "base/strings/stringprintf.h" +#include "net/quic/platform/api/quic_str_cat.h" #include "net/quic/test_tools/simulator/simulator.h" -using base::StringPrintf; using std::string; namespace net { @@ -92,12 +91,12 @@ SymmetricLink::SymmetricLink(Simulator* simulator, QuicBandwidth bandwidth, QuicTime::Delta propagation_delay) : a_to_b_link_(simulator, - StringPrintf("%s (A-to-B)", name.c_str()), + QuicStringPrintf("%s (A-to-B)", name.c_str()), sink_b, bandwidth, propagation_delay), b_to_a_link_(simulator, - StringPrintf("%s (B-to-A)", name.c_str()), + QuicStringPrintf("%s (B-to-A)", name.c_str()), sink_a, bandwidth, propagation_delay) {} @@ -107,9 +106,9 @@ SymmetricLink::SymmetricLink(Endpoint* endpoint_a, QuicBandwidth bandwidth, QuicTime::Delta propagation_delay) : SymmetricLink(endpoint_a->simulator(), - StringPrintf("Link [%s]<->[%s]", - endpoint_a->name().c_str(), - endpoint_b->name().c_str()), + QuicStringPrintf("Link [%s]<->[%s]", + endpoint_a->name().c_str(), + endpoint_b->name().c_str()), endpoint_a->GetRxPort(), endpoint_b->GetRxPort(), bandwidth, diff --git a/chromium/net/quic/test_tools/simulator/quic_endpoint.cc b/chromium/net/quic/test_tools/simulator/quic_endpoint.cc index 7adb701bae8..638ad2efd4f 100644 --- a/chromium/net/quic/test_tools/simulator/quic_endpoint.cc +++ b/chromium/net/quic/test_tools/simulator/quic_endpoint.cc @@ -5,14 +5,13 @@ #include "net/quic/test_tools/simulator/quic_endpoint.h" #include "base/sha1.h" -#include "base/strings/stringprintf.h" #include "net/quic/core/crypto/crypto_handshake_message.h" #include "net/quic/core/crypto/crypto_protocol.h" #include "net/quic/platform/api/quic_ptr_util.h" +#include "net/quic/platform/api/quic_str_cat.h" #include "net/quic/test_tools/quic_test_utils.h" #include "net/quic/test_tools/simulator/simulator.h" -using base::StringPrintf; using std::string; namespace net { @@ -64,7 +63,7 @@ QuicEndpoint::QuicEndpoint(Simulator* simulator, peer_name_(peer_name), writer_(this), nic_tx_queue_(simulator, - StringPrintf("%s (TX Queue)", name.c_str()), + QuicStringPrintf("%s (TX Queue)", name.c_str()), kMaxPacketSize * kTxQueueSize), connection_(connection_id, GetAddressFromName(peer_name), diff --git a/chromium/net/quic/test_tools/simulator/simulator_test.cc b/chromium/net/quic/test_tools/simulator/simulator_test.cc index 235d64c5f55..577491e4198 100644 --- a/chromium/net/quic/test_tools/simulator/simulator_test.cc +++ b/chromium/net/quic/test_tools/simulator/simulator_test.cc @@ -309,10 +309,9 @@ TEST(SimulatorTest, QueueBottleneck) { saturator.SetTxPort(&local_link); queue.set_tx_port(&bottleneck_link); - const QuicPacketCount packets_received = 1000; - simulator.RunUntil([&counter, packets_received]() { - return counter.packets() == packets_received; - }); + static const QuicPacketCount packets_received = 1000; + simulator.RunUntil( + [&counter]() { return counter.packets() == packets_received; }); const double loss_ratio = 1 - static_cast<double>(packets_received) / saturator.packets_transmitted(); @@ -343,12 +342,12 @@ TEST(SimulatorTest, OnePacketQueue) { saturator.SetTxPort(&local_link); queue.set_tx_port(&bottleneck_link); - const QuicPacketCount packets_received = 10; + static const QuicPacketCount packets_received = 10; // The deadline here is to prevent this tests from looping infinitely in case // the packets never reach the receiver. const QuicTime deadline = simulator.GetClock()->Now() + QuicTime::Delta::FromSeconds(10); - simulator.RunUntil([&simulator, &counter, packets_received, deadline]() { + simulator.RunUntil([&simulator, &counter, deadline]() { return counter.packets() == packets_received || simulator.GetClock()->Now() > deadline; }); @@ -379,8 +378,8 @@ TEST(SimulatorTest, SwitchedNetwork) { base_propagation_delay * 3); const QuicTime start_time = simulator.GetClock()->Now(); - const QuicPacketCount bytes_received = 64 * 1000; - simulator.RunUntil([&saturator1, bytes_received]() { + static const QuicPacketCount bytes_received = 64 * 1000; + simulator.RunUntil([&saturator1]() { return saturator1.counter()->bytes() >= bytes_received; }); const QuicTime end_time = simulator.GetClock()->Now(); @@ -630,9 +629,9 @@ TEST(SimulatorTest, TrafficPolicer) { Switch network_switch(&simulator, "Switch", 8, bandwidth * base_propagation_delay * 10); - const QuicByteCount initial_burst = 1000 * 10; - const QuicByteCount max_bucket_size = 1000 * 100; - const QuicBandwidth target_bandwidth = bandwidth * 0.25; + static const QuicByteCount initial_burst = 1000 * 10; + static const QuicByteCount max_bucket_size = 1000 * 100; + static const QuicBandwidth target_bandwidth = bandwidth * 0.25; TrafficPolicer policer(&simulator, "Policer", initial_burst, max_bucket_size, target_bandwidth, network_switch.port(2)); @@ -642,14 +641,14 @@ TEST(SimulatorTest, TrafficPolicer) { // Ensure the initial burst passes without being dropped at all. bool simulator_result = simulator.RunUntilOrTimeout( - [&saturator1, initial_burst]() { + [&saturator1]() { return saturator1.bytes_transmitted() == initial_burst; }, timeout); ASSERT_TRUE(simulator_result); saturator1.Pause(); simulator_result = simulator.RunUntilOrTimeout( - [&saturator2, initial_burst]() { + [&saturator2]() { return saturator2.counter()->bytes() == initial_burst; }, timeout); diff --git a/chromium/net/quic/test_tools/simulator/switch.cc b/chromium/net/quic/test_tools/simulator/switch.cc index 85c9e3b31c2..a27f6d905ce 100644 --- a/chromium/net/quic/test_tools/simulator/switch.cc +++ b/chromium/net/quic/test_tools/simulator/switch.cc @@ -5,11 +5,10 @@ #include <cinttypes> #include "base/format_macros.h" -#include "base/strings/stringprintf.h" #include "net/quic/platform/api/quic_ptr_util.h" +#include "net/quic/platform/api/quic_str_cat.h" #include "net/quic/test_tools/simulator/switch.h" -using base::StringPrintf; using std::string; namespace net { @@ -20,8 +19,8 @@ Switch::Switch(Simulator* simulator, SwitchPortNumber port_count, QuicByteCount queue_capacity) { for (size_t port_number = 1; port_number <= port_count; port_number++) { - ports_.emplace_back(simulator, StringPrintf("%s (port %" PRIuS ")", - name.c_str(), port_number), + ports_.emplace_back(simulator, QuicStringPrintf("%s (port %" PRIuS ")", + name.c_str(), port_number), this, port_number, queue_capacity); } } @@ -38,7 +37,7 @@ Switch::Port::Port(Simulator* simulator, port_number_(port_number), connected_(false), queue_(simulator, - StringPrintf("%s (queue)", name.c_str()), + QuicStringPrintf("%s (queue)", name.c_str()), queue_capacity) {} void Switch::Port::AcceptPacket(std::unique_ptr<Packet> packet) { diff --git a/chromium/net/quic/test_tools/test_task_runner.cc b/chromium/net/quic/test_tools/test_task_runner.cc index 5e6e647d9c7..aed7b8fc9f0 100644 --- a/chromium/net/quic/test_tools/test_task_runner.cc +++ b/chromium/net/quic/test_tools/test_task_runner.cc @@ -40,9 +40,9 @@ void TestTaskRunner::RunNextTask() { DCHECK(next != tasks_.end()); clock_->AdvanceTime(QuicTime::Delta::FromMicroseconds( (next->GetTimeToRun() - clock_->NowInTicks()).InMicroseconds())); - PostedTask task = *next; + PostedTask task = std::move(*next); tasks_.erase(next); - task.task.Run(); + std::move(task.task).Run(); } namespace { |