Cleanup HostResolverManager handling of DnsConfig
Various cleanups to simplify things in preparation to convert
config-change listening to SystemDnsConfigChangeNotifier:
*Now that we always have a DnsClient from the start, as long as
defined(ENABLE_BUILT_IN_DNS), moved a bunch of DnsClient-specific
properties including ownership of the DnsConfig and overrides into
DnsClient itself. Figure anything we can move out of the
overcomplicated HostResolverManager is an improvement.
*Removed assumptions that NetworkChangeNotifier would hold a base
config, mostly only reading from NCN on change notifications or on
init (essentially the times SystemDnsConfigChangeNotifier will give
the manager a config).
*Removed a bunch of unnecessary abstractions for updating and reading
configuration and secondary state based on the configuration. Most of
these have become less necessary and more overcomplicated in all the
recent code churn. More code now more directly updates or reads config
as necessary.
*Removed some test methods for reading/modifying config now that
testing code can always interact with a mocked DnsClient or soon
SystemDnsConfigChangeNotifier.
Bug: 971411
Change-Id: Ia74580c40c6b399da2ab848a4b05854f5f232e81
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1742305
Commit-Queue: Eric Orth <[email protected]>
Reviewed-by: Matt Menke <[email protected]>
Cr-Commit-Position: refs/heads/master@{#690856}
diff --git a/net/dns/BUILD.gn b/net/dns/BUILD.gn
index 514dbac..8c23dc94 100644
--- a/net/dns/BUILD.gn
+++ b/net/dns/BUILD.gn
@@ -396,7 +396,10 @@
}
if (enable_built_in_dns) {
- sources += [ "address_sorter_unittest.cc" ]
+ sources += [
+ "address_sorter_unittest.cc",
+ "dns_client_unittest.cc",
+ ]
if (is_posix || is_fuchsia) {
sources += [ "address_sorter_posix_unittest.cc" ]
}
diff --git a/net/dns/context_host_resolver.cc b/net/dns/context_host_resolver.cc
index 34ce64e..2d32399d 100644
--- a/net/dns/context_host_resolver.cc
+++ b/net/dns/context_host_resolver.cc
@@ -168,11 +168,6 @@
manager_->set_proc_params_for_test(proc_params);
}
-void ContextHostResolver::SetBaseDnsConfigForTesting(
- const DnsConfig& base_config) {
- manager_->SetBaseDnsConfigForTesting(base_config);
-}
-
void ContextHostResolver::SetTickClockForTesting(
const base::TickClock* tick_clock) {
manager_->SetTickClockForTesting(tick_clock);
diff --git a/net/dns/context_host_resolver.h b/net/dns/context_host_resolver.h
index 722bdcb7..efc1813 100644
--- a/net/dns/context_host_resolver.h
+++ b/net/dns/context_host_resolver.h
@@ -19,7 +19,6 @@
namespace net {
-struct DnsConfig;
class HostCache;
class HostResolverManager;
struct ProcTaskParams;
@@ -64,7 +63,6 @@
size_t CacheSize() const;
void SetProcParamsForTesting(const ProcTaskParams& proc_params);
- void SetBaseDnsConfigForTesting(const DnsConfig& base_config);
void SetTickClockForTesting(const base::TickClock* tick_clock);
size_t GetNumActiveRequestsForTesting() const {
diff --git a/net/dns/context_host_resolver_unittest.cc b/net/dns/context_host_resolver_unittest.cc
index e519d4c..6d696a6 100644
--- a/net/dns/context_host_resolver_unittest.cc
+++ b/net/dns/context_host_resolver_unittest.cc
@@ -15,7 +15,6 @@
#include "net/base/ip_address.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
-#include "net/base/network_change_notifier.h"
#include "net/base/test_completion_callback.h"
#include "net/dns/dns_config.h"
#include "net/dns/dns_test_util.h"
@@ -45,23 +44,26 @@
}
void SetMockDnsRules(MockDnsClientRuleList rules) {
- // HostResolver expects DnsConfig to get set after setting DnsClient, so
- // create first with an empty config and then update the config.
- auto dns_client =
- std::make_unique<MockDnsClient>(DnsConfig(), std::move(rules));
- dns_client_ = dns_client.get();
- manager_->SetDnsClientForTesting(std::move(dns_client));
- manager_->SetInsecureDnsClientEnabled(true);
-
- scoped_refptr<HostResolverProc> proc = CreateCatchAllHostResolverProc();
- manager_->set_proc_params_for_test(ProcTaskParams(proc.get(), 1u));
-
IPAddress dns_ip(192, 168, 1, 0);
DnsConfig config;
config.nameservers.push_back(
IPEndPoint(dns_ip, dns_protocol::kDefaultPort));
EXPECT_TRUE(config.IsValid());
- manager_->SetBaseDnsConfigForTesting(config);
+
+ auto dns_client =
+ std::make_unique<MockDnsClient>(std::move(config), std::move(rules));
+ dns_client->set_ignore_system_config_changes(true);
+ dns_client_ = dns_client.get();
+ manager_->SetDnsClientForTesting(std::move(dns_client));
+ manager_->SetInsecureDnsClientEnabled(true);
+
+ // Ensure DnsClient is fully usable.
+ EXPECT_TRUE(dns_client_->CanUseInsecureDnsTransactions());
+ EXPECT_FALSE(dns_client_->FallbackFromInsecureTransactionPreferred());
+ EXPECT_TRUE(dns_client_->GetEffectiveConfig());
+
+ scoped_refptr<HostResolverProc> proc = CreateCatchAllHostResolverProc();
+ manager_->set_proc_params_for_test(ProcTaskParams(proc.get(), 1u));
}
MockDnsClient* dns_client_;
@@ -274,8 +276,12 @@
std::make_unique<ContextHostResolver>(manager_.get(), std::move(cache));
resolver->SetTickClockForTesting(&clock);
+ // Allow stale results and then confirm the result is not stale in order to
+ // make the issue more clear if something is invalidating the cache.
HostResolver::ResolveHostParameters parameters;
parameters.source = HostResolverSource::LOCAL_ONLY;
+ parameters.cache_usage =
+ HostResolver::ResolveHostParameters::CacheUsage::STALE_ALLOWED;
std::unique_ptr<HostResolver::ResolveHostRequest> request =
resolver->CreateRequest(HostPortPair("example.com", 100),
NetLogWithSource(), parameters);
@@ -285,6 +291,9 @@
EXPECT_THAT(callback.GetResult(rv), test::IsOk());
EXPECT_THAT(request->GetAddressResults().value().endpoints(),
testing::ElementsAre(kEndpoint));
+ ASSERT_TRUE(request->GetStaleInfo());
+ EXPECT_EQ(0, request->GetStaleInfo().value().network_changes);
+ EXPECT_FALSE(request->GetStaleInfo().value().is_stale());
}
TEST_F(ContextHostResolverTest, ResultsAddedToCache) {
diff --git a/net/dns/dns_client.cc b/net/dns/dns_client.cc
index 7de02c7..20a940b 100644
--- a/net/dns/dns_client.cc
+++ b/net/dns/dns_client.cc
@@ -8,44 +8,96 @@
#include "base/bind.h"
#include "base/rand_util.h"
+#include "base/values.h"
#include "net/dns/address_sorter.h"
-#include "net/dns/dns_config.h"
#include "net/dns/dns_session.h"
#include "net/dns/dns_socket_pool.h"
#include "net/dns/dns_transaction.h"
+#include "net/log/net_log.h"
+#include "net/log/net_log_event_type.h"
#include "net/socket/client_socket_factory.h"
namespace net {
namespace {
+// Creates NetLog parameters for the DNS_CONFIG_CHANGED event.
+base::Value NetLogDnsConfigParams(const DnsConfig* config) {
+ if (!config)
+ return base::DictionaryValue();
+
+ return base::Value::FromUniquePtrValue(config->ToValue());
+}
+
+bool IsEqual(const base::Optional<DnsConfig>& c1, const DnsConfig* c2) {
+ if (!c1.has_value() && c2 == nullptr)
+ return true;
+
+ if (!c1.has_value() || c2 == nullptr)
+ return false;
+
+ return c1.value() == *c2;
+}
+
class DnsClientImpl : public DnsClient {
public:
DnsClientImpl(NetLog* net_log,
ClientSocketFactory* socket_factory,
const RandIntCallback& rand_int_callback)
- : address_sorter_(AddressSorter::CreateAddressSorter()),
- net_log_(net_log),
+ : net_log_(net_log),
socket_factory_(socket_factory),
rand_int_callback_(rand_int_callback) {}
- void SetConfig(const DnsConfig& config) override {
- factory_.reset();
- session_ = nullptr;
- if (config.IsValid() && !config.unhandled_options) {
- std::unique_ptr<DnsSocketPool> socket_pool(
- config.randomize_ports
- ? DnsSocketPool::CreateDefault(socket_factory_,
- rand_int_callback_)
- : DnsSocketPool::CreateNull(socket_factory_, rand_int_callback_));
- session_ = new DnsSession(config, std::move(socket_pool),
- rand_int_callback_, net_log_);
- factory_ = DnsTransactionFactory::CreateFactory(session_.get());
- }
+ bool CanUseSecureDnsTransactions() const override {
+ return HasAvailableDohServer();
}
- const DnsConfig* GetConfig() const override {
- return session_.get() ? &session_->config() : nullptr;
+ bool CanUseInsecureDnsTransactions() const override {
+ return session_ != nullptr && insecure_enabled_ &&
+ !GetEffectiveConfig()->dns_over_tls_active;
+ }
+
+ void SetInsecureEnabled(bool enabled) override {
+ insecure_enabled_ = enabled;
+ }
+
+ bool FallbackFromInsecureTransactionPreferred() const override {
+ return !CanUseInsecureDnsTransactions() ||
+ insecure_fallback_failures_ >= kMaxInsecureFallbackFailures;
+ }
+
+ bool SetSystemConfig(base::Optional<DnsConfig> system_config) override {
+ if (system_config == system_config_)
+ return false;
+
+ system_config_ = std::move(system_config);
+
+ return UpdateDnsConfig();
+ }
+
+ bool SetConfigOverrides(DnsConfigOverrides config_overrides) override {
+ if (config_overrides == config_overrides_)
+ return false;
+
+ config_overrides_ = std::move(config_overrides);
+
+ return UpdateDnsConfig();
+ }
+
+ const DnsConfig* GetEffectiveConfig() const override {
+ if (!session_)
+ return nullptr;
+
+ DCHECK(session_->config().IsValid());
+ return &session_->config();
+ }
+
+ const DnsHosts* GetHosts() const override {
+ const DnsConfig* config = GetEffectiveConfig();
+ if (!config)
+ return nullptr;
+
+ return &config->hosts;
}
DnsTransactionFactory* GetTransactionFactory() override {
@@ -54,10 +106,95 @@
AddressSorter* GetAddressSorter() override { return address_sorter_.get(); }
+ void IncrementInsecureFallbackFailures() override {
+ ++insecure_fallback_failures_;
+ }
+
+ void ClearInsecureFallbackFailures() override {
+ insecure_fallback_failures_ = 0;
+ }
+
+ base::Optional<DnsConfig> GetSystemConfigForTesting() const override {
+ return system_config_;
+ }
+
+ DnsConfigOverrides GetConfigOverridesForTesting() const override {
+ return config_overrides_;
+ }
+
private:
+ base::Optional<DnsConfig> BuildEffectiveConfig() const {
+ DnsConfig config;
+ if (config_overrides_.OverridesEverything()) {
+ config = config_overrides_.ApplyOverrides(DnsConfig());
+ } else {
+ if (!system_config_)
+ return base::nullopt;
+
+ config = config_overrides_.ApplyOverrides(system_config_.value());
+ }
+
+ if (!config.IsValid() || config.unhandled_options)
+ return base::nullopt;
+
+ return config;
+ }
+
+ bool UpdateDnsConfig() {
+ base::Optional<DnsConfig> new_effective_config = BuildEffectiveConfig();
+
+ if (IsEqual(new_effective_config, GetEffectiveConfig()))
+ return false;
+
+ insecure_fallback_failures_ = 0;
+ UpdateSession(std::move(new_effective_config));
+
+ if (net_log_) {
+ net_log_->AddGlobalEntry(NetLogEventType::DNS_CONFIG_CHANGED, [&] {
+ return NetLogDnsConfigParams(GetEffectiveConfig());
+ });
+ }
+
+ return true;
+ }
+
+ void UpdateSession(base::Optional<DnsConfig> new_effective_config) {
+ factory_.reset();
+ session_ = nullptr;
+
+ if (new_effective_config) {
+ DCHECK(new_effective_config.value().IsValid());
+ DCHECK(!new_effective_config.value().unhandled_options);
+
+ std::unique_ptr<DnsSocketPool> socket_pool(
+ new_effective_config.value().randomize_ports
+ ? DnsSocketPool::CreateDefault(socket_factory_,
+ rand_int_callback_)
+ : DnsSocketPool::CreateNull(socket_factory_, rand_int_callback_));
+ session_ =
+ new DnsSession(std::move(new_effective_config).value(),
+ std::move(socket_pool), rand_int_callback_, net_log_);
+ factory_ = DnsTransactionFactory::CreateFactory(session_.get());
+ }
+ }
+
+ bool HasAvailableDohServer() const {
+ // TODO(crbug.com/985589): Once DoH probes are sent, update this such that a
+ // DoH server is considered successful if it has a successful probe state.
+ const DnsConfig* config = GetEffectiveConfig();
+ return config && config->dns_over_https_servers.size() > 0;
+ }
+
+ bool insecure_enabled_ = false;
+ int insecure_fallback_failures_ = 0;
+
+ base::Optional<DnsConfig> system_config_;
+ DnsConfigOverrides config_overrides_;
+
scoped_refptr<DnsSession> session_;
std::unique_ptr<DnsTransactionFactory> factory_;
- std::unique_ptr<AddressSorter> address_sorter_;
+ std::unique_ptr<AddressSorter> address_sorter_ =
+ AddressSorter::CreateAddressSorter();
NetLog* net_log_;
diff --git a/net/dns/dns_client.h b/net/dns/dns_client.h
index 57f823e..9914ef9e 100644
--- a/net/dns/dns_client.h
+++ b/net/dns/dns_client.h
@@ -7,37 +7,68 @@
#include <memory>
+#include "base/optional.h"
#include "net/base/net_export.h"
#include "net/base/rand_callback.h"
+#include "net/dns/dns_config.h"
+#include "net/dns/dns_config_overrides.h"
+#include "net/dns/dns_hosts.h"
namespace net {
class AddressSorter;
class ClientSocketFactory;
-struct DnsConfig;
class DnsTransactionFactory;
class NetLog;
-// Convenience wrapper which allows easy injection of DnsTransaction into
-// HostResolverImpl. Pointers returned by the Get* methods are only guaranteed
-// to remain valid until next time SetConfig is called.
+// Entry point for HostResolverManager to interact with the built-in async
+// resolver, as implemented by DnsTransactionFactory. Manages configuration and
+// status of the resolver.
class NET_EXPORT DnsClient {
public:
+ static const int kMaxInsecureFallbackFailures = 16;
+
virtual ~DnsClient() {}
- // Destroys the current DnsTransactionFactory and creates a new one
- // according to |config|, unless it is invalid or has |unhandled_options|.
- virtual void SetConfig(const DnsConfig& config) = 0;
+ // Returns true if the DnsClient is able and allowed to make secure DNS
+ // transactions. If false, secure transactions should not be created.
+ virtual bool CanUseSecureDnsTransactions() const = 0;
- // Returns NULL if the current config is not valid.
- virtual const DnsConfig* GetConfig() const = 0;
+ // Returns true if the DnsClient is able and allowed to make insecure DNS
+ // transactions. If false, insecure transactions should not be created. Will
+ // always be false unless SetInsecureEnabled(true) has been called.
+ virtual bool CanUseInsecureDnsTransactions() const = 0;
+ virtual void SetInsecureEnabled(bool enabled) = 0;
- // Returns NULL if the current config is not valid.
+ // When true, insecure DNS transactions should not be used when reasonable
+ // fallback alternatives, e.g. system resolution can be used instead.
+ virtual bool FallbackFromInsecureTransactionPreferred() const = 0;
+
+ // Updates DNS config. If effective config has changed, destroys the current
+ // DnsTransactionFactory and creates a new one according to the effective
+ // config, unless it is invalid or has |unhandled_options|.
+ //
+ // Returns whether or not the effective config changed.
+ virtual bool SetSystemConfig(base::Optional<DnsConfig> system_config) = 0;
+ virtual bool SetConfigOverrides(DnsConfigOverrides config_overrides) = 0;
+
+ // Retrieve the current DNS configuration that would be used if transactions
+ // were otherwise currently allowed. Returns null if configuration is
+ // invalid or a configuration has not yet been read from the system.
+ virtual const DnsConfig* GetEffectiveConfig() const = 0;
+ virtual const DnsHosts* GetHosts() const = 0;
+
+ // Returns null if the current config is not valid.
virtual DnsTransactionFactory* GetTransactionFactory() = 0;
- // Returns NULL if the current config is not valid.
virtual AddressSorter* GetAddressSorter() = 0;
+ virtual void IncrementInsecureFallbackFailures() = 0;
+ virtual void ClearInsecureFallbackFailures() = 0;
+
+ virtual base::Optional<DnsConfig> GetSystemConfigForTesting() const = 0;
+ virtual DnsConfigOverrides GetConfigOverridesForTesting() const = 0;
+
// Creates default client.
static std::unique_ptr<DnsClient> CreateClient(NetLog* net_log);
diff --git a/net/dns/dns_client_unittest.cc b/net/dns/dns_client_unittest.cc
new file mode 100644
index 0000000..2f969f9
--- /dev/null
+++ b/net/dns/dns_client_unittest.cc
@@ -0,0 +1,225 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/dns/dns_client.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/rand_util.h"
+#include "net/base/ip_address.h"
+#include "net/base/ip_endpoint.h"
+#include "net/dns/dns_config.h"
+#include "net/socket/socket_test_util.h"
+#include "net/test/test_with_task_environment.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+class AlwaysFailSocketFactory : public MockClientSocketFactory {
+ public:
+ std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
+ DatagramSocket::BindType bind_type,
+ NetLog* net_log,
+ const NetLogSource& source) override {
+ return std::make_unique<MockUDPClientSocket>();
+ }
+};
+
+class DnsClientTest : public TestWithTaskEnvironment {
+ protected:
+ void SetUp() override {
+ client_ = DnsClient::CreateClientForTesting(
+ nullptr /* net_log */, &socket_factory_, base::Bind(&base::RandInt));
+ }
+
+ DnsConfig BasicValidConfig() {
+ DnsConfig config;
+ config.nameservers = {IPEndPoint(IPAddress(2, 3, 4, 5), 123)};
+ return config;
+ }
+
+ DnsConfig ValidConfigWithDoh() {
+ DnsConfig config = BasicValidConfig();
+ config.dns_over_https_servers = {DnsConfig::DnsOverHttpsServerConfig(
+ "www.doh.com", true /* use_post */)};
+ return config;
+ }
+
+ DnsConfigOverrides BasicValidOverrides() {
+ DnsConfigOverrides config;
+ config.nameservers.emplace({IPEndPoint(IPAddress(1, 2, 3, 4), 123)});
+ return config;
+ }
+
+ std::unique_ptr<DnsClient> client_;
+ AlwaysFailSocketFactory socket_factory_;
+
+ private:
+};
+
+TEST_F(DnsClientTest, NoConfig) {
+ client_->SetInsecureEnabled(true);
+
+ EXPECT_FALSE(client_->CanUseSecureDnsTransactions());
+ EXPECT_FALSE(client_->CanUseInsecureDnsTransactions());
+ EXPECT_TRUE(client_->FallbackFromInsecureTransactionPreferred());
+
+ EXPECT_FALSE(client_->GetEffectiveConfig());
+ EXPECT_FALSE(client_->GetHosts());
+ EXPECT_FALSE(client_->GetTransactionFactory());
+}
+
+TEST_F(DnsClientTest, InvalidConfig) {
+ client_->SetInsecureEnabled(true);
+ client_->SetSystemConfig(DnsConfig());
+
+ EXPECT_FALSE(client_->CanUseSecureDnsTransactions());
+ EXPECT_FALSE(client_->CanUseInsecureDnsTransactions());
+ EXPECT_TRUE(client_->FallbackFromInsecureTransactionPreferred());
+
+ EXPECT_FALSE(client_->GetEffectiveConfig());
+ EXPECT_FALSE(client_->GetHosts());
+ EXPECT_FALSE(client_->GetTransactionFactory());
+}
+
+TEST_F(DnsClientTest, CanUseSecureDnsTransactions_NoDohServers) {
+ client_->SetInsecureEnabled(true);
+ client_->SetSystemConfig(BasicValidConfig());
+
+ EXPECT_FALSE(client_->CanUseSecureDnsTransactions());
+ EXPECT_TRUE(client_->CanUseInsecureDnsTransactions());
+ EXPECT_FALSE(client_->FallbackFromInsecureTransactionPreferred());
+
+ EXPECT_THAT(client_->GetEffectiveConfig(),
+ testing::Pointee(BasicValidConfig()));
+ EXPECT_TRUE(client_->GetHosts());
+ EXPECT_TRUE(client_->GetTransactionFactory());
+}
+
+TEST_F(DnsClientTest, InsecureNotEnabled) {
+ client_->SetInsecureEnabled(false);
+ client_->SetSystemConfig(ValidConfigWithDoh());
+
+ EXPECT_TRUE(client_->CanUseSecureDnsTransactions());
+ EXPECT_FALSE(client_->CanUseInsecureDnsTransactions());
+ EXPECT_TRUE(client_->FallbackFromInsecureTransactionPreferred());
+
+ EXPECT_THAT(client_->GetEffectiveConfig(),
+ testing::Pointee(ValidConfigWithDoh()));
+ EXPECT_TRUE(client_->GetHosts());
+ EXPECT_TRUE(client_->GetTransactionFactory());
+}
+
+TEST_F(DnsClientTest, DnsOverTlsActive) {
+ client_->SetInsecureEnabled(true);
+ DnsConfig config = ValidConfigWithDoh();
+ config.dns_over_tls_active = true;
+ client_->SetSystemConfig(config);
+
+ EXPECT_TRUE(client_->CanUseSecureDnsTransactions());
+ EXPECT_FALSE(client_->CanUseInsecureDnsTransactions());
+ EXPECT_TRUE(client_->FallbackFromInsecureTransactionPreferred());
+
+ EXPECT_THAT(client_->GetEffectiveConfig(), testing::Pointee(config));
+ EXPECT_TRUE(client_->GetHosts());
+ EXPECT_TRUE(client_->GetTransactionFactory());
+}
+
+TEST_F(DnsClientTest, AllAllowed) {
+ client_->SetInsecureEnabled(true);
+ client_->SetSystemConfig(ValidConfigWithDoh());
+
+ EXPECT_TRUE(client_->CanUseSecureDnsTransactions());
+ EXPECT_TRUE(client_->CanUseInsecureDnsTransactions());
+ EXPECT_FALSE(client_->FallbackFromInsecureTransactionPreferred());
+
+ EXPECT_THAT(client_->GetEffectiveConfig(),
+ testing::Pointee(ValidConfigWithDoh()));
+ EXPECT_TRUE(client_->GetHosts());
+ EXPECT_TRUE(client_->GetTransactionFactory());
+}
+
+TEST_F(DnsClientTest, FallbackFromInsecureTransactionPreferred_Failures) {
+ client_->SetInsecureEnabled(true);
+ client_->SetSystemConfig(ValidConfigWithDoh());
+
+ for (int i = 0; i < DnsClient::kMaxInsecureFallbackFailures; ++i) {
+ EXPECT_TRUE(client_->CanUseSecureDnsTransactions());
+ EXPECT_TRUE(client_->CanUseInsecureDnsTransactions());
+ EXPECT_FALSE(client_->FallbackFromInsecureTransactionPreferred());
+
+ client_->IncrementInsecureFallbackFailures();
+ }
+
+ EXPECT_TRUE(client_->CanUseSecureDnsTransactions());
+ EXPECT_TRUE(client_->CanUseInsecureDnsTransactions());
+ EXPECT_TRUE(client_->FallbackFromInsecureTransactionPreferred());
+
+ client_->ClearInsecureFallbackFailures();
+
+ EXPECT_TRUE(client_->CanUseSecureDnsTransactions());
+ EXPECT_TRUE(client_->CanUseInsecureDnsTransactions());
+ EXPECT_FALSE(client_->FallbackFromInsecureTransactionPreferred());
+}
+
+TEST_F(DnsClientTest, Override) {
+ client_->SetSystemConfig(BasicValidConfig());
+ EXPECT_THAT(client_->GetEffectiveConfig(),
+ testing::Pointee(BasicValidConfig()));
+
+ client_->SetConfigOverrides(BasicValidOverrides());
+ EXPECT_THAT(client_->GetEffectiveConfig(),
+ testing::Pointee(
+ BasicValidOverrides().ApplyOverrides(BasicValidConfig())));
+
+ client_->SetConfigOverrides(DnsConfigOverrides());
+ EXPECT_THAT(client_->GetEffectiveConfig(),
+ testing::Pointee(BasicValidConfig()));
+}
+
+// Cannot apply overrides without a system config unless everything is
+// overridden
+TEST_F(DnsClientTest, OverrideNoConfig) {
+ client_->SetConfigOverrides(BasicValidOverrides());
+ EXPECT_FALSE(client_->GetEffectiveConfig());
+
+ auto override_everything =
+ DnsConfigOverrides::CreateOverridingEverythingWithDefaults();
+ override_everything.nameservers.emplace(
+ {IPEndPoint(IPAddress(1, 2, 3, 4), 123)});
+ client_->SetConfigOverrides(override_everything);
+ EXPECT_THAT(
+ client_->GetEffectiveConfig(),
+ testing::Pointee(override_everything.ApplyOverrides(DnsConfig())));
+}
+
+TEST_F(DnsClientTest, OverrideInvalidConfig) {
+ client_->SetSystemConfig(DnsConfig());
+ EXPECT_FALSE(client_->GetEffectiveConfig());
+
+ client_->SetConfigOverrides(BasicValidOverrides());
+ EXPECT_THAT(client_->GetEffectiveConfig(),
+ testing::Pointee(
+ BasicValidOverrides().ApplyOverrides(BasicValidConfig())));
+}
+
+TEST_F(DnsClientTest, OverrideToInvalid) {
+ client_->SetSystemConfig(BasicValidConfig());
+ EXPECT_THAT(client_->GetEffectiveConfig(),
+ testing::Pointee(BasicValidConfig()));
+
+ DnsConfigOverrides overrides;
+ overrides.nameservers.emplace();
+ client_->SetConfigOverrides(std::move(overrides));
+
+ EXPECT_FALSE(client_->GetEffectiveConfig());
+}
+
+} // namespace
+
+} // namespace net
diff --git a/net/dns/dns_config.cc b/net/dns/dns_config.cc
index 5e2a769..96b162d0 100644
--- a/net/dns/dns_config.cc
+++ b/net/dns/dns_config.cc
@@ -46,6 +46,10 @@
return Equals(d);
}
+bool DnsConfig::operator!=(const DnsConfig& d) const {
+ return !Equals(d);
+}
+
bool DnsConfig::EqualsIgnoreHosts(const DnsConfig& d) const {
return (nameservers == d.nameservers) &&
(dns_over_tls_active == d.dns_over_tls_active) &&
diff --git a/net/dns/dns_config.h b/net/dns/dns_config.h
index c7125ae..4d5a882 100644
--- a/net/dns/dns_config.h
+++ b/net/dns/dns_config.h
@@ -36,6 +36,7 @@
bool Equals(const DnsConfig& d) const;
bool operator==(const DnsConfig& d) const;
+ bool operator!=(const DnsConfig& d) const;
bool EqualsIgnoreHosts(const DnsConfig& d) const;
diff --git a/net/dns/dns_config_overrides.cc b/net/dns/dns_config_overrides.cc
index 1d203412..9f8f5e4 100644
--- a/net/dns/dns_config_overrides.cc
+++ b/net/dns/dns_config_overrides.cc
@@ -11,11 +11,16 @@
DnsConfigOverrides::DnsConfigOverrides(const DnsConfigOverrides& other) =
default;
+DnsConfigOverrides::DnsConfigOverrides(DnsConfigOverrides&& other) = default;
+
DnsConfigOverrides::~DnsConfigOverrides() = default;
DnsConfigOverrides& DnsConfigOverrides::operator=(
const DnsConfigOverrides& other) = default;
+DnsConfigOverrides& DnsConfigOverrides::operator=(DnsConfigOverrides&& other) =
+ default;
+
bool DnsConfigOverrides::operator==(const DnsConfigOverrides& other) const {
return nameservers == other.nameservers && search == other.search &&
hosts == other.hosts &&
diff --git a/net/dns/dns_config_overrides.h b/net/dns/dns_config_overrides.h
index 3e274c1..bd96265f 100644
--- a/net/dns/dns_config_overrides.h
+++ b/net/dns/dns_config_overrides.h
@@ -21,9 +21,11 @@
struct NET_EXPORT DnsConfigOverrides {
DnsConfigOverrides();
DnsConfigOverrides(const DnsConfigOverrides& other);
+ DnsConfigOverrides(DnsConfigOverrides&& other);
~DnsConfigOverrides();
DnsConfigOverrides& operator=(const DnsConfigOverrides& other);
+ DnsConfigOverrides& operator=(DnsConfigOverrides&& other);
bool operator==(const DnsConfigOverrides& other) const;
bool operator!=(const DnsConfigOverrides& other) const;
diff --git a/net/dns/dns_test_util.cc b/net/dns/dns_test_util.cc
index 1910a80..42cd367 100644
--- a/net/dns/dns_test_util.cc
+++ b/net/dns/dns_test_util.cc
@@ -16,6 +16,7 @@
#include "net/base/ip_address.h"
#include "net/base/net_errors.h"
#include "net/dns/address_sorter.h"
+#include "net/dns/dns_hosts.h"
#include "net/dns/dns_query.h"
#include "net/dns/dns_transaction.h"
#include "net/dns/dns_util.h"
@@ -493,32 +494,99 @@
DelayedTransactionList delayed_transactions_;
};
-MockDnsClient::MockDnsClient(const DnsConfig& config,
- MockDnsClientRuleList rules)
- : config_(config),
+MockDnsClient::MockDnsClient(DnsConfig config, MockDnsClientRuleList rules)
+ : config_(std::move(config)),
factory_(new MockTransactionFactory(std::move(rules))),
- address_sorter_(new MockAddressSorter()) {}
+ address_sorter_(new MockAddressSorter()) {
+ effective_config_ = BuildEffectiveConfig();
+}
MockDnsClient::~MockDnsClient() = default;
-void MockDnsClient::SetConfig(const DnsConfig& config) {
- config_ = config;
+bool MockDnsClient::CanUseSecureDnsTransactions() const {
+ const DnsConfig* config = GetEffectiveConfig();
+ return config && config->IsValid() && !config->dns_over_https_servers.empty();
}
-const DnsConfig* MockDnsClient::GetConfig() const {
- return config_.IsValid() ? &config_ : nullptr;
+bool MockDnsClient::CanUseInsecureDnsTransactions() const {
+ const DnsConfig* config = GetEffectiveConfig();
+ return config && config->IsValid() && insecure_enabled_ &&
+ !config->dns_over_tls_active;
+}
+
+void MockDnsClient::SetInsecureEnabled(bool enabled) {
+ insecure_enabled_ = enabled;
+}
+
+bool MockDnsClient::FallbackFromInsecureTransactionPreferred() const {
+ return !CanUseInsecureDnsTransactions() ||
+ fallback_failures_ >= max_fallback_failures_;
+}
+
+bool MockDnsClient::SetSystemConfig(base::Optional<DnsConfig> system_config) {
+ if (ignore_system_config_changes_)
+ return false;
+
+ base::Optional<DnsConfig> before = effective_config_;
+ config_ = std::move(system_config);
+ effective_config_ = BuildEffectiveConfig();
+ return before != effective_config_;
+}
+
+bool MockDnsClient::SetConfigOverrides(DnsConfigOverrides config_overrides) {
+ base::Optional<DnsConfig> before = effective_config_;
+ overrides_ = std::move(config_overrides);
+ effective_config_ = BuildEffectiveConfig();
+ return before != effective_config_;
+}
+
+const DnsConfig* MockDnsClient::GetEffectiveConfig() const {
+ return effective_config_.has_value() ? &effective_config_.value() : nullptr;
+}
+
+const DnsHosts* MockDnsClient::GetHosts() const {
+ const DnsConfig* config = GetEffectiveConfig();
+ if (!config)
+ return nullptr;
+
+ return &config->hosts;
}
DnsTransactionFactory* MockDnsClient::GetTransactionFactory() {
- return config_.IsValid() ? factory_.get() : nullptr;
+ return GetEffectiveConfig() ? factory_.get() : nullptr;
}
AddressSorter* MockDnsClient::GetAddressSorter() {
- return address_sorter_.get();
+ return GetEffectiveConfig() ? address_sorter_.get() : nullptr;
+}
+
+void MockDnsClient::IncrementInsecureFallbackFailures() {
+ ++fallback_failures_;
+}
+
+void MockDnsClient::ClearInsecureFallbackFailures() {
+ fallback_failures_ = 0;
+}
+
+base::Optional<DnsConfig> MockDnsClient::GetSystemConfigForTesting() const {
+ return config_;
+}
+
+DnsConfigOverrides MockDnsClient::GetConfigOverridesForTesting() const {
+ return overrides_;
}
void MockDnsClient::CompleteDelayedTransactions() {
factory_->CompleteDelayedTransactions();
}
+base::Optional<DnsConfig> MockDnsClient::BuildEffectiveConfig() {
+ if (overrides_.OverridesEverything())
+ return overrides_.ApplyOverrides(DnsConfig());
+ if (!config_ || !config_.value().IsValid())
+ return base::nullopt;
+
+ return overrides_.ApplyOverrides(config_.value());
+}
+
} // namespace net
diff --git a/net/dns/dns_test_util.h b/net/dns/dns_test_util.h
index b5f73d4..0d2596d 100644
--- a/net/dns/dns_test_util.h
+++ b/net/dns/dns_test_util.h
@@ -242,22 +242,49 @@
// MockDnsClient provides MockTransactionFactory.
class MockDnsClient : public DnsClient {
public:
- MockDnsClient(const DnsConfig& config, MockDnsClientRuleList rules);
+ MockDnsClient(DnsConfig config, MockDnsClientRuleList rules);
~MockDnsClient() override;
// DnsClient interface:
- void SetConfig(const DnsConfig& config) override;
- const DnsConfig* GetConfig() const override;
+ bool CanUseSecureDnsTransactions() const override;
+ bool CanUseInsecureDnsTransactions() const override;
+ void SetInsecureEnabled(bool enabled) override;
+ bool FallbackFromInsecureTransactionPreferred() const override;
+ bool SetSystemConfig(base::Optional<DnsConfig> system_config) override;
+ bool SetConfigOverrides(DnsConfigOverrides config_overrides) override;
+ const DnsConfig* GetEffectiveConfig() const override;
+ const DnsHosts* GetHosts() const override;
DnsTransactionFactory* GetTransactionFactory() override;
AddressSorter* GetAddressSorter() override;
+ void IncrementInsecureFallbackFailures() override;
+ void ClearInsecureFallbackFailures() override;
+ base::Optional<DnsConfig> GetSystemConfigForTesting() const override;
+ DnsConfigOverrides GetConfigOverridesForTesting() const override;
// Completes all DnsTransactions that were delayed by a rule.
void CompleteDelayedTransactions();
+ void set_max_fallback_failures(int max_fallback_failures) {
+ max_fallback_failures_ = max_fallback_failures;
+ }
+
+ void set_ignore_system_config_changes(bool ignore_system_config_changes) {
+ ignore_system_config_changes_ = ignore_system_config_changes;
+ }
+
private:
class MockTransactionFactory;
- DnsConfig config_;
+ base::Optional<DnsConfig> BuildEffectiveConfig();
+
+ bool insecure_enabled_ = false;
+ int fallback_failures_ = 0;
+ int max_fallback_failures_ = DnsClient::kMaxInsecureFallbackFailures;
+ bool ignore_system_config_changes_ = false;
+
+ base::Optional<DnsConfig> config_;
+ DnsConfigOverrides overrides_;
+ base::Optional<DnsConfig> effective_config_;
std::unique_ptr<MockTransactionFactory> factory_;
std::unique_ptr<AddressSorter> address_sorter_;
};
diff --git a/net/dns/fuzzed_host_resolver_util.cc b/net/dns/fuzzed_host_resolver_util.cc
index b76c880..c46c3060 100644
--- a/net/dns/fuzzed_host_resolver_util.cc
+++ b/net/dns/fuzzed_host_resolver_util.cc
@@ -380,7 +380,7 @@
net_log_, &socket_factory_,
base::Bind(&FuzzedDataProvider::ConsumeIntegralInRange<int32_t>,
base::Unretained(data_provider_)));
- dns_client->SetConfig(GetFuzzedDnsConfig(data_provider_));
+ dns_client->SetSystemConfig(GetFuzzedDnsConfig(data_provider_));
HostResolverManager::SetDnsClientForTesting(std::move(dns_client));
}
diff --git a/net/dns/host_resolver_manager.cc b/net/dns/host_resolver_manager.cc
index 174932e..9e87406 100644
--- a/net/dns/host_resolver_manager.cc
+++ b/net/dns/host_resolver_manager.cc
@@ -343,11 +343,6 @@
return std::move(dict);
}
-// Creates NetLog parameters for the DNS_CONFIG_CHANGED event.
-base::Value NetLogDnsConfigParams(const DnsConfig* config) {
- return base::Value::FromUniquePtrValue(config->ToValue());
-}
-
base::Value NetLogIPv6AvailableParams(bool ipv6_available, bool cached) {
base::DictionaryValue dict;
dict.SetBoolean("ipv6_available", ipv6_available);
@@ -557,8 +552,6 @@
return true;
}
-const unsigned HostResolverManager::kMaximumInsecureDnsTaskFailures = 16;
-
// Holds the callback and request parameters for an outstanding request.
//
// The RequestImpl is owned by the end user of host resolution. Deletion prior
@@ -1035,6 +1028,12 @@
num_completed_transactions_(0),
tick_clock_(tick_clock),
task_start_time_(tick_clock_->NowTicks()) {
+ DCHECK(client_);
+ if (secure_)
+ DCHECK(client_->CanUseSecureDnsTransactions());
+ else
+ DCHECK(client_->CanUseInsecureDnsTransactions());
+
DCHECK(delegate_);
}
@@ -1049,7 +1048,6 @@
bool secure() const { return secure_; }
void StartFirstTransaction() {
- DCHECK(client_);
DCHECK_EQ(0u, num_completed_transactions_);
DCHECK(!transaction1_);
@@ -1061,7 +1059,6 @@
}
void StartSecondTransaction() {
- DCHECK(client_);
DCHECK(needs_another_transaction());
transaction2_ = CreateTransaction(DnsQueryType::AAAA);
transaction2_->Start();
@@ -1076,7 +1073,6 @@
std::unique_ptr<DnsTransaction> CreateTransaction(
DnsQueryType dns_query_type) {
- DCHECK(client_);
DCHECK_NE(DnsQueryType::UNSPECIFIED, dns_query_type);
std::unique_ptr<DnsTransaction> trans =
client_->GetTransactionFactory()->CreateTransaction(
@@ -1944,7 +1940,6 @@
void StartDnsTask(bool secure) {
DCHECK_EQ(secure, !dispatcher_);
DCHECK_EQ(dispatcher_ ? 1u : 0, num_occupied_job_slots_);
- DCHECK(resolver_->HaveDnsConfig());
DCHECK(!resolver_->HaveTestProcOverride());
// Need to create the task even if we're going to post a failure instead of
// running it, as a "started" job needs a task to be properly cleaned up.
@@ -2026,7 +2021,7 @@
// Reset the insecure DNS failure counter if an insecure DnsTask completed
// successfully.
if (!secure)
- resolver_->num_insecure_dns_task_failures_ = 0;
+ resolver_->dns_client_->ClearInsecureFallbackFailures();
base::TimeDelta bounded_ttl = std::max(
results.ttl(), base::TimeDelta::FromSeconds(kMinimumTTLSeconds));
@@ -2392,16 +2387,10 @@
: max_queued_jobs_(0),
proc_params_(nullptr, options.max_system_retry_attempts),
net_log_(net_log),
- received_dns_config_(false),
- dns_config_overrides_(options.dns_config_overrides),
- num_insecure_dns_task_failures_(0),
check_ipv6_on_wifi_(options.check_ipv6_on_wifi),
- use_local_ipv6_(false),
last_ipv6_probe_result_(true),
additional_resolver_flags_(0),
allow_fallback_to_proctask_(true),
- bypass_insecure_dns_client_(false),
- insecure_dns_client_enabled_(false),
tick_clock_(base::DefaultTickClock::GetInstance()),
invalidation_in_progress_(false) {
PrioritizedDispatcher::Limits job_limits = GetDispatcherLimits(options);
@@ -2431,17 +2420,19 @@
OnConnectionTypeChanged(NetworkChangeNotifier::GetConnectionType());
- DnsConfig dns_config = GetBaseDnsConfig(false);
-
#if defined(ENABLE_BUILT_IN_DNS)
dns_client_ = DnsClient::CreateClient(net_log_);
- DCHECK(dns_client_);
- if (!dns_client_->GetConfig())
- dns_client_->SetConfig(dns_config);
+
+ DnsConfig system_config;
+ NetworkChangeNotifier::GetDnsConfig(&system_config);
+ dns_client_->SetSystemConfig(std::move(system_config));
+
+ dns_client_->SetInsecureEnabled(options.insecure_dns_client_enabled);
+ dns_client_->SetConfigOverrides(options.dns_config_overrides);
+#else
+ DCHECK(options.dns_config_overrides == DnsConfigOverrides());
#endif
- use_local_ipv6_ = !dns_config.IsValid() || dns_config.use_local_ipv6;
- SetInsecureDnsClientEnabled(options.insecure_dns_client_enabled);
allow_fallback_to_proctask_ = !ConfigureAsyncDnsNoFallbackFieldTrial();
}
@@ -2502,14 +2493,15 @@
void HostResolverManager::SetInsecureDnsClientEnabled(bool enabled) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (insecure_dns_client_enabled_ != enabled) {
- insecure_dns_client_enabled_ = enabled;
+
+ if (!dns_client_)
+ return;
+
+ bool enabled_before = dns_client_->CanUseInsecureDnsTransactions();
+ dns_client_->SetInsecureEnabled(enabled);
+
+ if (dns_client_->CanUseInsecureDnsTransactions() != enabled_before)
AbortInsecureDnsTasks(ERR_NETWORK_CHANGED, false /* fallback_only */);
- }
- // The histogram mode may need to be set even if the insecure dns client state
- // has not changed.
- DnsConfig dns_config = GetBaseDnsConfig(false);
- UpdateModeForHistogram(dns_config);
}
std::unique_ptr<base::Value> HostResolverManager::GetDnsConfigAsValue() const {
@@ -2517,23 +2509,37 @@
if (!dns_client_.get())
return nullptr;
- const DnsConfig* dns_config = dns_client_->GetConfig();
+ const DnsConfig* dns_config = dns_client_->GetEffectiveConfig();
if (!dns_config)
return std::make_unique<base::DictionaryValue>();
return dns_config->ToValue();
}
-void HostResolverManager::SetDnsConfigOverrides(
- const DnsConfigOverrides& overrides) {
+void HostResolverManager::SetDnsConfigOverrides(DnsConfigOverrides overrides) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (dns_config_overrides_ == overrides)
+ if (!dns_client_ && overrides == DnsConfigOverrides())
return;
- dns_config_overrides_ = overrides;
- if (dns_client_.get())
- UpdateDNSConfig(true);
+ // Not allowed to set overrides if compiled without DnsClient.
+ DCHECK(dns_client_);
+
+ bool transactions_allowed_before =
+ dns_client_->CanUseSecureDnsTransactions() ||
+ dns_client_->CanUseInsecureDnsTransactions();
+ bool changed = dns_client_->SetConfigOverrides(std::move(overrides));
+
+ if (changed) {
+ // Only invalidate cache if new overrides have resulted in a config change.
+ InvalidateCaches();
+
+ // Need to update jobs iff transactions were previously allowed because
+ // in-progress jobs may be running using a now-invalid configuration.
+ if (transactions_allowed_before) {
+ UpdateJobsForChangedConfig();
+ }
+ }
}
void HostResolverManager::AddHostCacheInvalidator(
@@ -2546,26 +2552,6 @@
host_cache_invalidators_.RemoveObserver(invalidator);
}
-bool HostResolverManager::GetInsecureDnsClientEnabledForTesting() {
- return insecure_dns_client_enabled_;
-}
-
-DnsConfig::SecureDnsMode HostResolverManager::GetSecureDnsModeForTesting() {
- if (!HaveDnsConfig())
- return DnsConfig::SecureDnsMode::OFF;
-
- return dns_client_->GetConfig()->secure_dns_mode;
-}
-
-const std::vector<DnsConfig::DnsOverHttpsServerConfig>*
-HostResolverManager::GetDnsOverHttpsServersForTesting() const {
- if (!dns_config_overrides_.dns_over_https_servers ||
- dns_config_overrides_.dns_over_https_servers.value().empty()) {
- return nullptr;
- }
- return &dns_config_overrides_.dns_over_https_servers.value();
-}
-
void HostResolverManager::SetTickClockForTesting(
const base::TickClock* tick_clock) {
tick_clock_ = tick_clock;
@@ -2596,15 +2582,14 @@
mdns_client_ = std::move(client);
}
-void HostResolverManager::SetBaseDnsConfigForTesting(
- const DnsConfig& base_config) {
- test_base_config_ = base_config;
- UpdateDNSConfig(true);
-}
-
void HostResolverManager::SetDnsClientForTesting(
std::unique_ptr<DnsClient> dns_client) {
DCHECK(dns_client);
+ if (dns_client_) {
+ if (!dns_client->GetSystemConfigForTesting())
+ dns_client->SetSystemConfig(dns_client_->GetSystemConfigForTesting());
+ dns_client->SetConfigOverrides(dns_client_->GetConfigOverridesForTesting());
+ }
dns_client_ = std::move(dns_client);
}
@@ -2880,15 +2865,17 @@
const std::deque<TaskType>& tasks) {
// Don't attempt a HOSTS lookup if there is no DnsConfig or the HOSTS lookup
// is going to be done next as part of a system lookup.
- if (!HaveDnsConfig() || !IsAddressType(query_type) ||
+ if (!dns_client_ || !IsAddressType(query_type) ||
(!tasks.empty() && tasks.front() == TaskType::PROC))
return base::nullopt;
+ const DnsHosts* hosts = dns_client_->GetHosts();
+
+ if (!hosts || hosts->empty())
+ return base::nullopt;
// HOSTS lookups are case-insensitive.
std::string effective_hostname = base::ToLowerASCII(hostname);
- const DnsHosts& hosts = dns_client_->GetConfig()->hosts;
-
// If |address_family| is ADDRESS_FAMILY_UNSPECIFIED other implementations
// (glibc and c-ares) return the first matching line. We have more
// flexibility, but lose implicit ordering.
@@ -2897,15 +2884,15 @@
AddressList addresses;
if (query_type == DnsQueryType::AAAA ||
query_type == DnsQueryType::UNSPECIFIED) {
- auto it = hosts.find(DnsHostsKey(effective_hostname, ADDRESS_FAMILY_IPV6));
- if (it != hosts.end())
+ auto it = hosts->find(DnsHostsKey(effective_hostname, ADDRESS_FAMILY_IPV6));
+ if (it != hosts->end())
addresses.push_back(IPEndPoint(it->second, 0));
}
if (query_type == DnsQueryType::A ||
query_type == DnsQueryType::UNSPECIFIED) {
- auto it = hosts.find(DnsHostsKey(effective_hostname, ADDRESS_FAMILY_IPV4));
- if (it != hosts.end())
+ auto it = hosts->find(DnsHostsKey(effective_hostname, ADDRESS_FAMILY_IPV4));
+ if (it != hosts->end())
addresses.push_back(IPEndPoint(it->second, 0));
}
@@ -2970,7 +2957,7 @@
if (!speculative) {
UMA_HISTOGRAM_LONG_TIMES_100("Net.DNS.TotalTime", duration);
- switch (mode_for_histogram_) {
+ switch (DetermineModeForHistogram()) {
case MODE_FOR_HISTOGRAM_SYSTEM:
UMA_HISTOGRAM_MEDIUM_TIMES("Net.DNS.TotalTimeTyped.System", duration);
break;
@@ -3014,20 +3001,17 @@
return job;
}
-bool HostResolverManager::HasAvailableDohServer() {
- // TODO(crbug.com/985589): Once DoH probes are sent, update this such that a
- // DoH server is considered successful if it has a successful probe state.
- return dns_client_->GetConfig()->dns_over_https_servers.size() > 0;
-}
-
DnsConfig::SecureDnsMode HostResolverManager::GetEffectiveSecureDnsMode(
const std::string& hostname,
base::Optional<DnsConfig::SecureDnsMode> secure_dns_mode_override) {
+ const DnsConfig* config =
+ dns_client_ ? dns_client_->GetEffectiveConfig() : nullptr;
+
DnsConfig::SecureDnsMode secure_dns_mode = DnsConfig::SecureDnsMode::OFF;
if (secure_dns_mode_override) {
secure_dns_mode = secure_dns_mode_override.value();
- } else if (HaveDnsConfig()) {
- secure_dns_mode = dns_client_->GetConfig()->secure_dns_mode;
+ } else if (config) {
+ secure_dns_mode = config->secure_dns_mode;
}
// If the query name matches one of the DoH server names, downgrade to OFF to
@@ -3038,8 +3022,8 @@
// improvement will prevent us from unnecessarily skipping DoH when a
// connection to the DoH server has been established but the query happens to
// be for a DoH server hostname.
- if (HaveDnsConfig()) {
- for (auto& server : dns_client_->GetConfig()->dns_over_https_servers) {
+ if (config) {
+ for (auto& server : config->dns_over_https_servers) {
if (hostname.compare(
GURL(GetURLFromTemplateWithoutParameters(server.server_template))
.host()) == 0) {
@@ -3062,7 +3046,9 @@
bool allow_cache,
bool prioritize_local_lookups,
std::deque<TaskType>* out_tasks) {
- DCHECK(HaveDnsConfig());
+ DCHECK(dns_client_);
+ DCHECK(dns_client_->GetEffectiveConfig());
+
// If a catch-all DNS block has been set for unit tests, we shouldn't send
// DnsTasks. It is still necessary to call this method, however, so that the
// correct cache tasks for the secure dns mode are added.
@@ -3072,13 +3058,13 @@
case DnsConfig::SecureDnsMode::SECURE:
DCHECK(!allow_cache ||
out_tasks->front() == TaskType::SECURE_CACHE_LOOKUP);
- DCHECK(dns_client_->GetConfig()->dns_over_https_servers.size() != 0);
+ DCHECK(dns_client_->CanUseSecureDnsTransactions());
if (dns_tasks_allowed)
out_tasks->push_back(TaskType::SECURE_DNS);
break;
case DnsConfig::SecureDnsMode::AUTOMATIC:
DCHECK(!allow_cache || out_tasks->front() == TaskType::CACHE_LOOKUP);
- if (!HasAvailableDohServer()) {
+ if (!dns_client_->CanUseSecureDnsTransactions()) {
// Don't run a secure DnsTask if there are no available DoH servers.
if (dns_tasks_allowed && insecure_tasks_allowed)
out_tasks->push_back(TaskType::DNS);
@@ -3158,9 +3144,6 @@
bool prioritize_local_lookups =
cache_usage ==
HostResolver::ResolveHostParameters::CacheUsage::STALE_ALLOWED;
- bool insecure_dns_tasks_allowed =
- insecure_dns_client_enabled_ && HaveDnsConfig() &&
- !dns_client_->GetConfig()->dns_over_tls_active;
switch (source) {
case HostResolverSource::ANY:
// Force address queries with canonname to use ProcTask to counter poor
@@ -3176,11 +3159,13 @@
bool proc_task_allowed =
IsAddressType(dns_query_type) &&
*out_effective_secure_dns_mode != DnsConfig::SecureDnsMode::SECURE;
- if (HaveDnsConfig()) {
- PushDnsTasks(
- proc_task_allowed, *out_effective_secure_dns_mode,
- insecure_dns_tasks_allowed && !bypass_insecure_dns_client_,
- allow_cache, prioritize_local_lookups, out_tasks);
+ if (dns_client_ && dns_client_->GetEffectiveConfig()) {
+ bool insecure_allowed =
+ dns_client_->CanUseInsecureDnsTransactions() &&
+ !dns_client_->FallbackFromInsecureTransactionPreferred();
+ PushDnsTasks(proc_task_allowed, *out_effective_secure_dns_mode,
+ insecure_allowed, allow_cache, prioritize_local_lookups,
+ out_tasks);
} else if (proc_task_allowed) {
out_tasks->push_back(TaskType::PROC);
}
@@ -3197,10 +3182,11 @@
out_tasks->push_back(TaskType::PROC);
break;
case HostResolverSource::DNS:
- if (HaveDnsConfig()) {
+ if (dns_client_ && dns_client_->GetEffectiveConfig()) {
PushDnsTasks(false /* proc_task_allowed */,
- *out_effective_secure_dns_mode, insecure_dns_tasks_allowed,
- allow_cache, prioritize_local_lookups, out_tasks);
+ *out_effective_secure_dns_mode,
+ dns_client_->CanUseInsecureDnsTransactions(), allow_cache,
+ prioritize_local_lookups, out_tasks);
}
break;
case HostResolverSource::MULTICAST_DNS:
@@ -3227,6 +3213,14 @@
std::deque<TaskType>* out_tasks) {
*out_effective_flags = flags | additional_resolver_flags_;
*out_effective_type = dns_query_type;
+
+ bool use_local_ipv6 = true;
+ if (dns_client_) {
+ const DnsConfig* config = dns_client_->GetEffectiveConfig();
+ if (config)
+ use_local_ipv6 = config->use_local_ipv6;
+ }
+
if (*out_effective_type == DnsQueryType::UNSPECIFIED &&
// When resolving IPv4 literals, there's no need to probe for IPv6.
// When resolving IPv6 literals, there's no benefit to artificially
@@ -3234,7 +3228,7 @@
// that this query is UNSPECIFIED (see effective_query_type check above)
// so the code requesting the resolution should be amenable to receiving a
// IPv6 resolution.
- !use_local_ipv6_ && ip_address == nullptr && !IsIPv6Reachable(net_log)) {
+ !use_local_ipv6 && ip_address == nullptr && !IsIPv6Reachable(net_log)) {
*out_effective_type = DnsQueryType::A;
*out_effective_flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
}
@@ -3363,8 +3357,9 @@
dispatcher_->SetLimits(limits);
}
+// TODO(crbug.com/995984): Consider removing this and its usage.
void HostResolverManager::TryServingAllJobsFromHosts() {
- if (!HaveDnsConfig())
+ if (!dns_client_ || !dns_client_->GetEffectiveConfig())
return;
// TODO(szym): Do not do this if nsswitch.conf instructs not to.
@@ -3403,101 +3398,64 @@
}
void HostResolverManager::OnInitialDNSConfigRead() {
- UpdateDNSConfig(false);
+ if (!dns_client_)
+ return;
+
+ DnsConfig config;
+ NetworkChangeNotifier::GetDnsConfig(&config);
+
+ dns_client_->SetSystemConfig(std::move(config));
}
void HostResolverManager::OnDNSChanged() {
- // Ignore changes if we're using a test config or if we have overriding
- // configuration that overrides everything from the base config.
- if (test_base_config_ || dns_config_overrides_.OverridesEverything())
- return;
+ bool changed = false;
+ bool transactions_allowed_before = false;
+ if (dns_client_) {
+ DnsConfig config;
+ NetworkChangeNotifier::GetDnsConfig(&config);
- UpdateDNSConfig(true);
-}
-
-DnsConfig HostResolverManager::GetBaseDnsConfig(bool log_to_net_log) {
- DnsConfig dns_config;
-
- // Skip retrieving the base config if all values will be overridden.
- if (!dns_config_overrides_.OverridesEverything()) {
- if (test_base_config_) {
- dns_config = test_base_config_.value();
- } else {
- NetworkChangeNotifier::GetDnsConfig(&dns_config);
- }
-
- if (log_to_net_log && net_log_) {
- net_log_->AddGlobalEntry(NetLogEventType::DNS_CONFIG_CHANGED, [&] {
- return NetLogDnsConfigParams(&dns_config);
- });
- }
-
- // TODO(szym): Remove once http://crbug.com/137914 is resolved.
- received_dns_config_ = dns_config.IsValid();
+ transactions_allowed_before = dns_client_->CanUseSecureDnsTransactions() ||
+ dns_client_->CanUseInsecureDnsTransactions();
+ changed = dns_client_->SetSystemConfig(std::move(config));
}
- // TODO(crbug.com/985589): Upgrade DoH servers for automatic mode here.
- return dns_config_overrides_.ApplyOverrides(dns_config);
+ // Always invalidate cache, even if no change is seen.
+ InvalidateCaches();
+
+ // Need to update jobs iff transactions were previously allowed because
+ // in-progress jobs may be running using a now-invalid configuration.
+ if (changed && transactions_allowed_before) {
+ UpdateJobsForChangedConfig();
+ }
}
-void HostResolverManager::UpdateDNSConfig(bool config_changed) {
- DnsConfig dns_config = GetBaseDnsConfig(true);
+void HostResolverManager::UpdateJobsForChangedConfig() {
+ // Life check to bail once |this| is deleted.
+ base::WeakPtr<HostResolverManager> self = weak_ptr_factory_.GetWeakPtr();
- // Conservatively assume local IPv6 is needed when DnsConfig is not valid.
- use_local_ipv6_ = !dns_config.IsValid() || dns_config.use_local_ipv6;
+ // Existing jobs that were set up using the nameservers and secure dns mode
+ // from the original config need to be aborted.
+ AbortAllJobs(false /* in_progress_only */);
- // We want a new DnsSession in place, before we Abort running Jobs, so that
- // the newly started jobs use the new config.
- if (dns_client_.get()) {
- // Make sure that if the update is an initial read, not a change, there
- // wasn't already a DnsConfig or it's the same one.
- DCHECK(config_changed || !dns_client_->GetConfig() ||
- dns_client_->GetConfig()->Equals(dns_config));
- dns_client_->SetConfig(dns_config);
- }
-
- if (config_changed) {
- InvalidateCaches();
-
- // Reset the insecure DNS task failure counter.
- num_insecure_dns_task_failures_ = 0;
- bypass_insecure_dns_client_ = false;
-
- // Life check to bail once |this| is deleted.
- base::WeakPtr<HostResolverManager> self = weak_ptr_factory_.GetWeakPtr();
-
- // Existing jobs that were set up using the nameservers and secure dns mode
- // from the original config need to be aborted.
- AbortAllJobs(false /* in_progress_only */);
-
- // |this| may be deleted inside AbortAllJobs().
- if (self.get())
- TryServingAllJobsFromHosts();
- }
-
- UpdateModeForHistogram(dns_config);
-}
-
-bool HostResolverManager::HaveDnsConfig() const {
- return dns_client_ && dns_client_->GetConfig();
+ // |this| may be deleted inside AbortAllJobs().
+ if (self.get())
+ TryServingAllJobsFromHosts();
}
void HostResolverManager::OnFallbackResolve(int dns_task_error) {
DCHECK(dns_client_);
DCHECK_NE(OK, dns_task_error);
- ++num_insecure_dns_task_failures_;
- if (num_insecure_dns_task_failures_ < kMaximumInsecureDnsTaskFailures)
+ // Nothing to do if DnsTask is already not preferred.
+ if (dns_client_->FallbackFromInsecureTransactionPreferred())
return;
- // Skip insecure DNS lookups until the next DNS config change. Must be done
- // before aborting DnsTasks, since doing so may start new jobs. Do not fully
- // clear out or disable the DnsClient as some requests (e.g. those specifying
- // DNS source) are not allowed to fallback and will continue using DnsTask.
- bypass_insecure_dns_client_ = true;
+ dns_client_->IncrementInsecureFallbackFailures();
- // Fallback all fallback-allowed insecure DnsTasks to ProcTasks.
- AbortInsecureDnsTasks(ERR_FAILED, true /* fallback_only */);
+ // If DnsClient became not preferred, fallback all fallback-allowed insecure
+ // DnsTasks to ProcTasks.
+ if (dns_client_->FallbackFromInsecureTransactionPreferred())
+ AbortInsecureDnsTasks(ERR_FAILED, true /* fallback_only */);
}
int HostResolverManager::GetOrCreateMdnsClient(MDnsClient** out_client) {
@@ -3525,30 +3483,33 @@
}
// TODO(crbug.com/985589): Update these metrics when DoH upgrade starts
-// starts happening in practice.
-void HostResolverManager::UpdateModeForHistogram(const DnsConfig& dns_config) {
- if (HaveDnsConfig()) {
- const DnsConfig* config = dns_client_->GetConfig();
- if (config->dns_over_tls_active) {
- mode_for_histogram_ = MODE_FOR_HISTOGRAM_SYSTEM_PRIVATE_DNS;
- if ((config->dns_over_tls_hostname.empty() &&
- HasDoHUpgradeableServer(config->nameservers)) ||
- DotServerSupportsDoh(config->dns_over_tls_hostname))
- mode_for_histogram_ =
- MODE_FOR_HISTOGRAM_SYSTEM_PRIVATE_DNS_SUPPORTS_DOH;
- return;
+// happening in practice.
+HostResolverManager::ModeForHistogram
+HostResolverManager::DetermineModeForHistogram() const {
+ if (!dns_client_)
+ return MODE_FOR_HISTOGRAM_SYSTEM;
+
+ const DnsConfig* config = dns_client_->GetEffectiveConfig();
+
+ if (config && config->dns_over_tls_active) {
+ if ((config->dns_over_tls_hostname.empty() &&
+ HasDoHUpgradeableServer(config->nameservers)) ||
+ DotServerSupportsDoh(config->dns_over_tls_hostname)) {
+ return MODE_FOR_HISTOGRAM_SYSTEM_PRIVATE_DNS_SUPPORTS_DOH;
}
- if (insecure_dns_client_enabled_) {
- mode_for_histogram_ = MODE_FOR_HISTOGRAM_ASYNC_DNS;
- if (HasDoHUpgradeableServer(config->nameservers))
- mode_for_histogram_ = MODE_FOR_HISTOGRAM_ASYNC_DNS_PRIVATE_SUPPORTS_DOH;
- return;
- }
+ return MODE_FOR_HISTOGRAM_SYSTEM_PRIVATE_DNS;
}
- mode_for_histogram_ = MODE_FOR_HISTOGRAM_SYSTEM;
- if (HasDoHUpgradeableServer(dns_config.nameservers))
- mode_for_histogram_ = MODE_FOR_HISTOGRAM_SYSTEM_SUPPORTS_DOH;
+ if (dns_client_->CanUseInsecureDnsTransactions()) {
+ if (HasDoHUpgradeableServer(config->nameservers))
+ return MODE_FOR_HISTOGRAM_ASYNC_DNS_PRIVATE_SUPPORTS_DOH;
+ return MODE_FOR_HISTOGRAM_ASYNC_DNS;
+ }
+
+ if (config && HasDoHUpgradeableServer(config->nameservers))
+ return MODE_FOR_HISTOGRAM_SYSTEM_SUPPORTS_DOH;
+
+ return MODE_FOR_HISTOGRAM_SYSTEM;
}
void HostResolverManager::InvalidateCaches() {
diff --git a/net/dns/host_resolver_manager.h b/net/dns/host_resolver_manager.h
index 90afe88f..c7b9237 100644
--- a/net/dns/host_resolver_manager.h
+++ b/net/dns/host_resolver_manager.h
@@ -8,6 +8,7 @@
#include <stddef.h>
#include <stdint.h>
+#include <deque>
#include <map>
#include <memory>
#include <set>
@@ -146,7 +147,7 @@
// Sets overriding configuration that will replace or add to configuration
// read from the system for DnsClient resolution.
- void SetDnsConfigOverrides(const DnsConfigOverrides& overrides);
+ void SetDnsConfigOverrides(DnsConfigOverrides overrides);
// Support for invalidating HostCaches on changes to network or DNS
// configuration. HostCaches should register/deregister invalidators here
@@ -162,18 +163,6 @@
void AddHostCacheInvalidator(HostCache::Invalidator* invalidator);
void RemoveHostCacheInvalidator(const HostCache::Invalidator* invalidator);
- // Returns the state of the insecure part of the DnsClient.
- bool GetInsecureDnsClientEnabledForTesting();
-
- // Returns the currently configured secure dns mode. Returns OFF if there is
- // not a valid config.
- SecureDnsMode GetSecureDnsModeForTesting();
-
- // Returns the currently configured DNS over HTTPS servers. Returns nullptr if
- // DNS over HTTPS is not enabled.
- const std::vector<DnsConfig::DnsOverHttpsServerConfig>*
- GetDnsOverHttpsServersForTesting() const;
-
void set_proc_params_for_test(const ProcTaskParams& proc_params) {
proc_params_ = proc_params;
}
@@ -190,8 +179,12 @@
std::unique_ptr<MDnsSocketFactory> socket_factory);
void SetMdnsClientForTesting(std::unique_ptr<MDnsClient> client);
- void SetBaseDnsConfigForTesting(const DnsConfig& base_config);
-
+ // To simulate modifications it would have received if |dns_client| had been
+ // in place before calling this, DnsConfig will be set with the configuration
+ // from the previous DnsClient being replaced (including system config if
+ // |dns_client| does not already contain a system config). This means tests do
+ // not normally need to worry about ordering between setting a test client and
+ // setting DnsConfig.
void SetDnsClientForTesting(std::unique_ptr<DnsClient> dns_client);
// Allows the tests to catch slots leaking out of the dispatcher. One
@@ -254,11 +247,6 @@
SECURE_CACHE_LOOKUP,
};
- // Number of consecutive failures of an insecure DnsTask (with successful
- // fallback to ProcTask) before the insecure portion of the DnsClient is
- // disabled until the next DNS change.
- static const unsigned kMaximumInsecureDnsTaskFailures;
-
// Attempts host resolution for |request|. Generally only expected to be
// called from RequestImpl::Start().
int Resolve(RequestImpl* request);
@@ -337,10 +325,6 @@
DnsQueryType query_type,
bool default_family_due_to_no_ipv6);
- // When no DoH servers are in an "available" state, no DoH requests should
- // be sent.
- bool HasAvailableDohServer();
-
// Returns the secure dns mode to use for a job, taking into account the
// global DnsConfig mode and any per-request override. Requests matching DoH
// server hostnames are downgraded to off mode to avoid infinite loops.
@@ -444,13 +428,7 @@
void OnDNSChanged() override;
void OnInitialDNSConfigRead() override;
- // Returns DNS configuration including applying overrides. |log_to_net_log|
- // indicates whether the config should be logged to the netlog.
- DnsConfig GetBaseDnsConfig(bool log_to_net_log);
- void UpdateDNSConfig(bool config_changed);
-
- // True if have a DnsClient with a valid DnsConfig.
- bool HaveDnsConfig() const;
+ void UpdateJobsForChangedConfig();
// Called on successful resolve after falling back to ProcTask after a failed
// DnsTask resolve.
@@ -458,9 +436,7 @@
int GetOrCreateMdnsClient(MDnsClient** out_client);
- // Update |mode_for_histogram_|. Called when DNS config changes. |dns_config|
- // is the current DNS config and is only used if !HaveDnsConfig().
- void UpdateModeForHistogram(const DnsConfig& dns_config);
+ ModeForHistogram DetermineModeForHistogram() const;
void InvalidateCaches();
@@ -486,31 +462,10 @@
// If present, used by DnsTask and ServeFromHosts to resolve requests.
std::unique_ptr<DnsClient> dns_client_;
- // True if received valid config from |dns_config_service_|. Temporary, used
- // to measure performance of DnsConfigService: http://crbug.com/125599
- bool received_dns_config_;
-
- // If set, used instead of getting DNS configuration from
- // NetworkChangeNotifier. Changes sent from NetworkChangeNotifier will also be
- // ignored and not cancel any pending requests.
- base::Optional<DnsConfig> test_base_config_;
-
- // Overrides or adds to DNS configuration read from the system for DnsClient
- // resolution.
- DnsConfigOverrides dns_config_overrides_;
-
- // Number of consecutive failures of insecure DnsTask, counted when fallback
- // succeeds.
- unsigned num_insecure_dns_task_failures_;
-
// False if IPv6 should not be attempted and assumed unreachable when on a
// WiFi connection. See https://crbug.com/696569 for further context.
bool check_ipv6_on_wifi_;
- // True if DnsConfigService detected that system configuration depends on
- // local IPv6 connectivity. Disables probing.
- bool use_local_ipv6_;
-
base::TimeTicks last_ipv6_probe_time_;
bool last_ipv6_probe_result_;
@@ -520,25 +475,10 @@
// Allow fallback to ProcTask if DnsTask fails.
bool allow_fallback_to_proctask_;
- // Whether insecure DnsTasks should not be added to the task sequence even if
- // the insecure part of the DnsClient is enabled. This is set to true when
- // there are too many successive insecure DnsTask failures.
- bool bypass_insecure_dns_client_;
-
// Task runner used for DNS lookups using the system resolver. Normally a
// ThreadPool task runner, but can be overridden for tests.
scoped_refptr<base::TaskRunner> proc_task_runner_;
- // Current resolver mode, useful for breaking down histogram data.
- ModeForHistogram mode_for_histogram_;
-
- // Whether insecure requests should be issued by DnsClient. This field is
- // complementary to the SecureDnsMode in DnsConfig. If we're in AUTOMATIC
- // mode, |insecure_dns_client_enabled_| will determine whether or not we
- // fallback to the insecure part of DnsClient before falling back to the
- // system resolver.
- bool insecure_dns_client_enabled_;
-
// Shared tick clock, overridden for testing.
const base::TickClock* tick_clock_;
diff --git a/net/dns/host_resolver_manager_unittest.cc b/net/dns/host_resolver_manager_unittest.cc
index 75a74655..d8d5be19 100644
--- a/net/dns/host_resolver_manager_unittest.cc
+++ b/net/dns/host_resolver_manager_unittest.cc
@@ -17,6 +17,7 @@
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/rand_util.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
@@ -53,6 +54,7 @@
#include "net/log/net_log_with_source.h"
#include "net/log/test_net_log.h"
#include "net/log/test_net_log_util.h"
+#include "net/socket/socket_test_util.h"
#include "net/test/gtest_util.h"
#include "net/test/test_with_task_environment.h"
#include "net/url_request/url_request_context.h"
@@ -563,14 +565,14 @@
}
static unsigned maximum_insecure_dns_task_failures() {
- return HostResolverManager::kMaximumInsecureDnsTaskFailures;
+ return DnsClient::kMaxInsecureFallbackFailures;
}
bool IsIPv6Reachable(const NetLogWithSource& net_log) {
return resolver_->IsIPv6Reachable(net_log);
}
- void PopulateCache(HostCache::Key& key, IPEndPoint endpoint) {
+ void PopulateCache(const HostCache::Key& key, IPEndPoint endpoint) {
resolver_->CacheResult(host_cache_.get(), key,
HostCache::Entry(OK, AddressList(endpoint),
HostCache::Entry::SOURCE_UNKNOWN),
@@ -3413,6 +3415,7 @@
std::make_unique<MockDnsClient>(DnsConfig(), CreateDefaultDnsRules());
dns_client_ = dns_client.get();
resolver_->SetDnsClientForTesting(std::move(dns_client));
+ resolver_->SetInsecureDnsClientEnabled(options.insecure_dns_client_enabled);
resolver_->set_proc_params_for_test(params);
if (host_cache_)
@@ -4343,10 +4346,73 @@
EXPECT_THAT(final_response.result_error(), IsOk());
}
+TEST_F(HostResolverManagerDnsTest, Ipv6Unreachable) {
+ CreateResolverWithLimitsAndParams(kMaxJobs, DefaultParams(proc_.get()),
+ false /* ipv6_reachable */,
+ true /* check_ipv6_on_wifi */);
+ ChangeDnsConfig(CreateValidDnsConfig());
+
+ ResolveHostResponseHelper response(resolver_->CreateRequest(
+ HostPortPair("ok", 500), NetLogWithSource(), base::nullopt,
+ request_context_.get(), host_cache_.get()));
+ EXPECT_THAT(response.result_error(), IsOk());
+
+ // Only expect IPv4 results.
+ EXPECT_THAT(response.request()->GetAddressResults().value().endpoints(),
+ testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 500)));
+}
+
+// Without a valid DnsConfig, assume IPv6 is needed and ignore prober.
+TEST_F(HostResolverManagerDnsTest, Ipv6Unreachable_InvalidConfig) {
+ CreateResolverWithLimitsAndParams(kMaxJobs, DefaultParams(proc_.get()),
+ false /* ipv6_reachable */,
+ true /* check_ipv6_on_wifi */);
+
+ proc_->AddRule("example.com", ADDRESS_FAMILY_UNSPECIFIED, "1.2.3.4,::5");
+ proc_->SignalMultiple(1u);
+
+ ResolveHostResponseHelper response(resolver_->CreateRequest(
+ HostPortPair("example.com", 500), NetLogWithSource(), base::nullopt,
+ request_context_.get(), host_cache_.get()));
+ EXPECT_THAT(response.result_error(), IsOk());
+ EXPECT_THAT(response.request()->GetAddressResults().value().endpoints(),
+ testing::UnorderedElementsAre(CreateExpected("1.2.3.4", 500),
+ CreateExpected("::5", 500)));
+}
+
+TEST_F(HostResolverManagerDnsTest, Ipv6Unreachable_UseLocalIpv6) {
+ CreateResolverWithLimitsAndParams(kMaxJobs, DefaultParams(proc_.get()),
+ false /* ipv6_reachable */,
+ true /* check_ipv6_on_wifi */);
+
+ DnsConfig config = CreateValidDnsConfig();
+ config.use_local_ipv6 = true;
+ ChangeDnsConfig(config);
+
+ ResolveHostResponseHelper response1(resolver_->CreateRequest(
+ HostPortPair("ok", 500), NetLogWithSource(), base::nullopt,
+ request_context_.get(), host_cache_.get()));
+ EXPECT_THAT(response1.result_error(), IsOk());
+ EXPECT_THAT(response1.request()->GetAddressResults().value().endpoints(),
+ testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 500),
+ CreateExpected("::1", 500)));
+
+ // Set |use_local_ipv6| to false. Expect only IPv4 results.
+ config.use_local_ipv6 = false;
+ ChangeDnsConfig(config);
+
+ ResolveHostResponseHelper response2(resolver_->CreateRequest(
+ HostPortPair("ok", 500), NetLogWithSource(), base::nullopt,
+ request_context_.get(), host_cache_.get()));
+ EXPECT_THAT(response2.result_error(), IsOk());
+ EXPECT_THAT(response2.request()->GetAddressResults().value().endpoints(),
+ testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 500)));
+}
+
// Confirm that resolving "localhost" is unrestricted even if there are no
// global IPv6 address. See SystemHostResolverCall for rationale.
// Test both the DnsClient and system host resolver paths.
-TEST_F(HostResolverManagerDnsTest, DualFamilyLocalhost) {
+TEST_F(HostResolverManagerDnsTest, Ipv6Unreachable_Localhost) {
CreateResolverWithLimitsAndParams(kMaxJobs, DefaultParams(proc_.get()),
false /* ipv6_reachable */,
true /* check_ipv6_on_wifi */);
@@ -5463,7 +5529,7 @@
request_context_.get(), host_cache_.get()));
EXPECT_FALSE(response_secure.complete());
- proc_->SignalMultiple(maximum_insecure_dns_task_failures() + 6);
+ proc_->SignalMultiple(maximum_insecure_dns_task_failures() + 4);
for (size_t i = 0u; i < maximum_insecure_dns_task_failures(); ++i) {
EXPECT_THAT(failure_responses[i]->result_error(), IsOk());
@@ -6211,12 +6277,33 @@
static_cast<int>(DnsConfig::SecureDnsMode::OFF));
}
+// Basic test socket factory that allows creation of UDP sockets, but those
+// sockets are mocks with no data and are not expected to be usable.
+class AlwaysFailSocketFactory : public MockClientSocketFactory {
+ public:
+ std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
+ DatagramSocket::BindType bind_type,
+ NetLog* net_log,
+ const NetLogSource& source) override {
+ return std::make_unique<MockUDPClientSocket>();
+ }
+};
+
+// Built-in client and config overrides not available on iOS.
+#if !defined(OS_IOS)
TEST_F(HostResolverManagerDnsTest, SetDnsConfigOverrides) {
+ // Use a real DnsClient to test config-handling behavior.
+ AlwaysFailSocketFactory socket_factory;
+ auto client = DnsClient::CreateClientForTesting(
+ nullptr /* net_log */, &socket_factory, base::Bind(&base::RandInt));
+ DnsClient* client_ptr = client.get();
+ resolver_->SetDnsClientForTesting(std::move(client));
+
DnsConfig original_config = CreateValidDnsConfig();
ChangeDnsConfig(original_config);
// Confirm pre-override state.
- ASSERT_TRUE(original_config.Equals(*dns_client_->GetConfig()));
+ ASSERT_EQ(original_config, *client_ptr->GetEffectiveConfig());
DnsConfigOverrides overrides;
const std::vector<IPEndPoint> nameservers = {
@@ -6250,7 +6337,8 @@
resolver_->SetDnsConfigOverrides(overrides);
- const DnsConfig* overridden_config = dns_client_->GetConfig();
+ const DnsConfig* overridden_config = client_ptr->GetEffectiveConfig();
+ ASSERT_TRUE(overridden_config);
EXPECT_EQ(nameservers, overridden_config->nameservers);
EXPECT_EQ(search, overridden_config->search);
EXPECT_EQ(hosts, overridden_config->hosts);
@@ -6267,11 +6355,18 @@
TEST_F(HostResolverManagerDnsTest,
SetDnsConfigOverrides_OverrideEverythingCreation) {
+ // Use a real DnsClient to test config-handling behavior.
+ AlwaysFailSocketFactory socket_factory;
+ auto client = DnsClient::CreateClientForTesting(
+ nullptr /* net_log */, &socket_factory, base::Bind(&base::RandInt));
+ DnsClient* client_ptr = client.get();
+ resolver_->SetDnsClientForTesting(std::move(client));
+
DnsConfig original_config = CreateValidDnsConfig();
ChangeDnsConfig(original_config);
// Confirm pre-override state.
- ASSERT_TRUE(original_config.Equals(*dns_client_->GetConfig()));
+ ASSERT_EQ(original_config, *client_ptr->GetEffectiveConfig());
ASSERT_FALSE(original_config.Equals(DnsConfig()));
DnsConfigOverrides overrides =
@@ -6287,15 +6382,22 @@
DnsConfig expected;
expected.nameservers = nameservers;
- EXPECT_TRUE(dns_client_->GetConfig()->Equals(DnsConfig(expected)));
+ EXPECT_THAT(client_ptr->GetEffectiveConfig(), testing::Pointee(expected));
}
TEST_F(HostResolverManagerDnsTest, SetDnsConfigOverrides_PartialOverride) {
+ // Use a real DnsClient to test config-handling behavior.
+ AlwaysFailSocketFactory socket_factory;
+ auto client = DnsClient::CreateClientForTesting(
+ nullptr /* net_log */, &socket_factory, base::Bind(&base::RandInt));
+ DnsClient* client_ptr = client.get();
+ resolver_->SetDnsClientForTesting(std::move(client));
+
DnsConfig original_config = CreateValidDnsConfig();
ChangeDnsConfig(original_config);
// Confirm pre-override state.
- ASSERT_TRUE(original_config.Equals(*dns_client_->GetConfig()));
+ ASSERT_EQ(original_config, *client_ptr->GetEffectiveConfig());
DnsConfigOverrides overrides;
const std::vector<IPEndPoint> nameservers = {
@@ -6306,7 +6408,8 @@
resolver_->SetDnsConfigOverrides(overrides);
- const DnsConfig* overridden_config = dns_client_->GetConfig();
+ const DnsConfig* overridden_config = client_ptr->GetEffectiveConfig();
+ ASSERT_TRUE(overridden_config);
EXPECT_EQ(nameservers, overridden_config->nameservers);
EXPECT_EQ(original_config.search, overridden_config->search);
EXPECT_EQ(original_config.hosts, overridden_config->hosts);
@@ -6326,11 +6429,18 @@
// Test that overridden configs are reapplied over a changed underlying system
// config.
TEST_F(HostResolverManagerDnsTest, SetDnsConfigOverrides_NewConfig) {
+ // Use a real DnsClient to test config-handling behavior.
+ AlwaysFailSocketFactory socket_factory;
+ auto client = DnsClient::CreateClientForTesting(
+ nullptr /* net_log */, &socket_factory, base::Bind(&base::RandInt));
+ DnsClient* client_ptr = client.get();
+ resolver_->SetDnsClientForTesting(std::move(client));
+
DnsConfig original_config = CreateValidDnsConfig();
ChangeDnsConfig(original_config);
// Confirm pre-override state.
- ASSERT_TRUE(original_config.Equals(*dns_client_->GetConfig()));
+ ASSERT_EQ(original_config, *client_ptr->GetEffectiveConfig());
DnsConfigOverrides overrides;
const std::vector<IPEndPoint> nameservers = {
@@ -6338,19 +6448,28 @@
overrides.nameservers = nameservers;
resolver_->SetDnsConfigOverrides(overrides);
- ASSERT_EQ(nameservers, dns_client_->GetConfig()->nameservers);
+ ASSERT_TRUE(client_ptr->GetEffectiveConfig());
+ ASSERT_EQ(nameservers, client_ptr->GetEffectiveConfig()->nameservers);
DnsConfig new_config = original_config;
new_config.attempts = 103;
ASSERT_NE(nameservers, new_config.nameservers);
ChangeDnsConfig(new_config);
- const DnsConfig* overridden_config = dns_client_->GetConfig();
+ const DnsConfig* overridden_config = client_ptr->GetEffectiveConfig();
+ ASSERT_TRUE(overridden_config);
EXPECT_EQ(nameservers, overridden_config->nameservers);
EXPECT_EQ(new_config.attempts, overridden_config->attempts);
}
TEST_F(HostResolverManagerDnsTest, SetDnsConfigOverrides_ClearOverrides) {
+ // Use a real DnsClient to test config-handling behavior.
+ AlwaysFailSocketFactory socket_factory;
+ auto client = DnsClient::CreateClientForTesting(
+ nullptr /* net_log */, &socket_factory, base::Bind(&base::RandInt));
+ DnsClient* client_ptr = client.get();
+ resolver_->SetDnsClientForTesting(std::move(client));
+
DnsConfig original_config = CreateValidDnsConfig();
ChangeDnsConfig(original_config);
@@ -6358,11 +6477,14 @@
overrides.attempts = 245;
resolver_->SetDnsConfigOverrides(overrides);
- ASSERT_FALSE(original_config.Equals(*dns_client_->GetConfig()));
+ ASSERT_THAT(client_ptr->GetEffectiveConfig(),
+ testing::Not(testing::Pointee(original_config)));
resolver_->SetDnsConfigOverrides(DnsConfigOverrides());
- EXPECT_TRUE(original_config.Equals(*dns_client_->GetConfig()));
+ EXPECT_THAT(client_ptr->GetEffectiveConfig(),
+ testing::Pointee(original_config));
}
+#endif // !defined(OS_IOS)
TEST_F(HostResolverManagerDnsTest, FlushCacheOnDnsConfigOverridesChange) {
ChangeDnsConfig(CreateValidDnsConfig());
@@ -6517,7 +6639,7 @@
TEST_F(HostResolverManagerDnsTest, ModeForHistogram) {
// Test Async resolver is detected.
ChangeDnsConfig(CreateValidDnsConfig());
- EXPECT_EQ(resolver_->mode_for_histogram_,
+ EXPECT_EQ(resolver_->DetermineModeForHistogram(),
HostResolverManager::MODE_FOR_HISTOGRAM_ASYNC_DNS);
// Test upgradability is detected for async DNS.
@@ -6536,14 +6658,14 @@
IPEndPoint(ip_address, dns_protocol::kDefaultPort));
ChangeDnsConfig(dns_config);
EXPECT_EQ(
- resolver_->mode_for_histogram_,
+ resolver_->DetermineModeForHistogram(),
HostResolverManager::MODE_FOR_HISTOGRAM_ASYNC_DNS_PRIVATE_SUPPORTS_DOH);
}
// Test system resolver is detected.
resolver_->SetInsecureDnsClientEnabled(false);
ChangeDnsConfig(CreateValidDnsConfig());
- EXPECT_EQ(resolver_->mode_for_histogram_,
+ EXPECT_EQ(resolver_->DetermineModeForHistogram(),
HostResolverManager::MODE_FOR_HISTOGRAM_SYSTEM);
// Test upgradability is detected for system resolver.
@@ -6554,7 +6676,7 @@
dns_config.nameservers.push_back(
IPEndPoint(ip_address, dns_protocol::kDefaultPort));
ChangeDnsConfig(dns_config);
- EXPECT_EQ(resolver_->mode_for_histogram_,
+ EXPECT_EQ(resolver_->DetermineModeForHistogram(),
HostResolverManager::MODE_FOR_HISTOGRAM_SYSTEM_SUPPORTS_DOH);
}
@@ -6562,7 +6684,7 @@
DnsConfig config = CreateValidDnsConfig();
config.dns_over_tls_active = true;
ChangeDnsConfig(config);
- EXPECT_EQ(resolver_->mode_for_histogram_,
+ EXPECT_EQ(resolver_->DetermineModeForHistogram(),
HostResolverManager::MODE_FOR_HISTOGRAM_SYSTEM_PRIVATE_DNS);
// Test upgradeability from IP addresses when private DNS is active.
@@ -6574,7 +6696,7 @@
dns_config.nameservers.push_back(
IPEndPoint(ip_address, dns_protocol::kDefaultPort));
ChangeDnsConfig(dns_config);
- EXPECT_EQ(resolver_->mode_for_histogram_,
+ EXPECT_EQ(resolver_->DetermineModeForHistogram(),
HostResolverManager::
MODE_FOR_HISTOGRAM_SYSTEM_PRIVATE_DNS_SUPPORTS_DOH);
}
@@ -6594,7 +6716,7 @@
dns_config.nameservers.push_back(
IPEndPoint(IPAddress(1, 2, 3, 4), dns_protocol::kDefaultPort));
ChangeDnsConfig(dns_config);
- EXPECT_EQ(resolver_->mode_for_histogram_,
+ EXPECT_EQ(resolver_->DetermineModeForHistogram(),
HostResolverManager::
MODE_FOR_HISTOGRAM_SYSTEM_PRIVATE_DNS_SUPPORTS_DOH);
}
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index 85901884..a382d0a 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -1681,9 +1681,10 @@
pending_read_buf_(nullptr),
pending_read_buf_len_(0),
net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::NONE)) {
- DCHECK(data_);
- data_->Initialize(this);
- peer_addr_ = data->connect_data().peer_addr;
+ if (data_) {
+ data_->Initialize(this);
+ peer_addr_ = data->connect_data().peer_addr;
+ }
}
MockUDPClientSocket::~MockUDPClientSocket() {
@@ -1845,6 +1846,9 @@
}
int MockUDPClientSocket::GetPeerAddress(IPEndPoint* address) const {
+ if (!data_)
+ return ERR_UNEXPECTED;
+
*address = peer_addr_;
return OK;
}
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h
index 94f9905..f46123e 100644
--- a/net/socket/socket_test_util.h
+++ b/net/socket/socket_test_util.h
@@ -1001,7 +1001,8 @@
class MockUDPClientSocket : public DatagramClientSocket, public AsyncSocket {
public:
- MockUDPClientSocket(SocketDataProvider* data, net::NetLog* net_log);
+ MockUDPClientSocket(SocketDataProvider* data = nullptr,
+ net::NetLog* net_log = nullptr);
~MockUDPClientSocket() override;
// Socket implementation.
diff --git a/net/url_request/http_with_dns_over_https_unittest.cc b/net/url_request/http_with_dns_over_https_unittest.cc
index 214bced..7b6bce9983 100644
--- a/net/url_request/http_with_dns_over_https_unittest.cc
+++ b/net/url_request/http_with_dns_over_https_unittest.cc
@@ -71,16 +71,26 @@
EXPECT_TRUE(test_server_.Start());
GURL url(doh_server_.GetURL("/dns_query"));
std::unique_ptr<DnsClient> dns_client(DnsClient::CreateClient(nullptr));
+
DnsConfig config;
config.nameservers.push_back(IPEndPoint());
- config.dns_over_https_servers.emplace_back(url.spec(), true /* use_post */);
- config.secure_dns_mode = DnsConfig::SecureDnsMode::AUTOMATIC;
- dns_client->SetConfig(config);
+ EXPECT_TRUE(config.IsValid());
+ dns_client->SetSystemConfig(std::move(config));
+
resolver_->SetRequestContext(&request_context_);
resolver_->SetProcParamsForTesting(
ProcTaskParams(new TestHostResolverProc(), 1));
resolver_->GetManagerForTesting()->SetDnsClientForTesting(
std::move(dns_client));
+
+ DnsConfigOverrides overrides;
+ overrides.dns_over_https_servers.emplace(
+ {DnsConfig::DnsOverHttpsServerConfig(url.spec(), true /* use_post */)});
+ overrides.secure_dns_mode = DnsConfig::SecureDnsMode::AUTOMATIC;
+ overrides.use_local_ipv6 = true;
+ resolver_->GetManagerForTesting()->SetDnsConfigOverrides(
+ std::move(overrides));
+
request_context_.set_host_resolver(resolver_.get());
request_context_.Init();
}
diff --git a/services/network/host_resolver_unittest.cc b/services/network/host_resolver_unittest.cc
index 7249aeb8..8bce68e 100644
--- a/services/network/host_resolver_unittest.cc
+++ b/services/network/host_resolver_unittest.cc
@@ -1168,8 +1168,9 @@
"example.com", {std::vector<std::string>(std::begin(kTextRecords),
std::end(kTextRecords))})),
false /* delay */);
- auto dns_client =
- std::make_unique<net::MockDnsClient>(net::DnsConfig(), std::move(rules));
+ auto dns_client = std::make_unique<net::MockDnsClient>(CreateValidDnsConfig(),
+ std::move(rules));
+ dns_client->set_ignore_system_config_changes(true);
net::NetLog net_log;
std::unique_ptr<net::ContextHostResolver> inner_resolver =
@@ -1177,7 +1178,6 @@
inner_resolver->GetManagerForTesting()->SetDnsClientForTesting(
std::move(dns_client));
inner_resolver->GetManagerForTesting()->SetInsecureDnsClientEnabled(true);
- inner_resolver->SetBaseDnsConfigForTesting(CreateValidDnsConfig());
HostResolver resolver(inner_resolver.get(), &net_log);
@@ -1208,8 +1208,9 @@
net::MockDnsClientRule::Result(net::BuildTestDnsPointerResponse(
"example.com", {"google.com", "chromium.org"})),
false /* delay */);
- auto dns_client =
- std::make_unique<net::MockDnsClient>(net::DnsConfig(), std::move(rules));
+ auto dns_client = std::make_unique<net::MockDnsClient>(CreateValidDnsConfig(),
+ std::move(rules));
+ dns_client->set_ignore_system_config_changes(true);
net::NetLog net_log;
std::unique_ptr<net::ContextHostResolver> inner_resolver =
@@ -1217,7 +1218,6 @@
inner_resolver->GetManagerForTesting()->SetDnsClientForTesting(
std::move(dns_client));
inner_resolver->GetManagerForTesting()->SetInsecureDnsClientEnabled(true);
- inner_resolver->SetBaseDnsConfigForTesting(CreateValidDnsConfig());
HostResolver resolver(inner_resolver.get(), &net_log);
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc
index b389114..ca8eb84 100644
--- a/services/network/network_context_unittest.cc
+++ b/services/network/network_context_unittest.cc
@@ -3161,6 +3161,8 @@
EXPECT_TRUE(resolver_closed);
}
+// Config overrides are not supported on iOS.
+#if !defined(OS_IOS)
TEST_F(NetworkContextTest, CreateHostResolverWithConfigOverrides) {
// Inject a factory to control and capture created net::HostResolvers.
TestResolverFactory* factory =
@@ -3184,11 +3186,12 @@
// enablable for the build config).
ASSERT_EQ(1u, factory->resolvers().size());
net::ContextHostResolver* internal_resolver = factory->resolvers().front();
-#if defined(ENABLE_BUILT_IN_DNS)
+
EXPECT_TRUE(internal_resolver->GetDnsConfigAsValue());
-#endif
// Override DnsClient with a basic mock.
+ net::DnsConfig base_configuration;
+ base_configuration.nameservers = {CreateExpectedEndPoint("12.12.12.12", 53)};
const std::string kQueryHostname = "example.com";
const std::string kResult = "1.2.3.4";
net::IPAddress result;
@@ -3203,20 +3206,17 @@
kQueryHostname, net::dns_protocol::kTypeAAAA, false /* secure */,
net::MockDnsClientRule::Result(net::MockDnsClientRule::ResultType::EMPTY),
false /* delay */);
- auto mock_dns_client =
- std::make_unique<net::MockDnsClient>(net::DnsConfig(), std::move(rules));
+ auto mock_dns_client = std::make_unique<net::MockDnsClient>(
+ base_configuration, std::move(rules));
+ mock_dns_client->SetInsecureEnabled(true);
+ mock_dns_client->set_ignore_system_config_changes(true);
auto* mock_dns_client_ptr = mock_dns_client.get();
internal_resolver->GetManagerForTesting()->SetDnsClientForTesting(
std::move(mock_dns_client));
- // Force the base configuration to ensure consistent overriding.
- net::DnsConfig base_configuration;
- base_configuration.nameservers = {CreateExpectedEndPoint("12.12.12.12", 53)};
- internal_resolver->SetBaseDnsConfigForTesting(base_configuration);
-
// Test that the DnsClient is getting the overridden configuration.
EXPECT_TRUE(overrides.ApplyOverrides(base_configuration)
- .Equals(*mock_dns_client_ptr->GetConfig()));
+ .Equals(*mock_dns_client_ptr->GetEffectiveConfig()));
// Ensure we are using the private resolver by testing that we get results
// from the overridden DnsClient.
@@ -3236,6 +3236,7 @@
EXPECT_THAT(response_client.result_addresses().value().endpoints(),
testing::ElementsAre(CreateExpectedEndPoint(kResult, 80)));
}
+#endif // defined(OS_IOS)
TEST_F(NetworkContextTest, PrivacyModeDisabledByDefault) {
std::unique_ptr<NetworkContext> network_context =
diff --git a/services/network/network_service_unittest.cc b/services/network/network_service_unittest.cc
index 38beab2..2db0a317 100644
--- a/services/network/network_service_unittest.cc
+++ b/services/network/network_service_unittest.cc
@@ -24,7 +24,10 @@
#include "net/base/ip_endpoint.h"
#include "net/base/mock_network_change_notifier.h"
#include "net/base/url_util.h"
+#include "net/dns/dns_client.h"
+#include "net/dns/dns_config.h"
#include "net/dns/dns_config_service.h"
+#include "net/dns/dns_test_util.h"
#include "net/dns/host_resolver.h"
#include "net/dns/host_resolver_manager.h"
#include "net/http/http_auth_handler_factory.h"
@@ -441,40 +444,39 @@
#if !defined(OS_IOS)
TEST_F(NetworkServiceTest, DnsClientEnableDisable) {
- // Set valid DnsConfig.
+ // Create valid DnsConfig.
net::DnsConfig config;
config.nameservers.push_back(net::IPEndPoint());
- service()->host_resolver_manager()->SetBaseDnsConfigForTesting(config);
+ auto dns_client = std::make_unique<net::MockDnsClient>(
+ std::move(config), net::MockDnsClientRuleList());
+ dns_client->set_ignore_system_config_changes(true);
+ net::DnsClient* dns_client_ptr = dns_client.get();
+ service()->host_resolver_manager()->SetDnsClientForTesting(
+ std::move(dns_client));
service()->ConfigureStubHostResolver(
true /* insecure_dns_client_enabled */,
net::DnsConfig::SecureDnsMode::OFF,
base::nullopt /* dns_over_https_servers */);
- EXPECT_TRUE(service()
- ->host_resolver_manager()
- ->GetInsecureDnsClientEnabledForTesting());
+ EXPECT_TRUE(dns_client_ptr->CanUseInsecureDnsTransactions());
EXPECT_EQ(net::DnsConfig::SecureDnsMode::OFF,
- service()->host_resolver_manager()->GetSecureDnsModeForTesting());
+ dns_client_ptr->GetEffectiveConfig()->secure_dns_mode);
service()->ConfigureStubHostResolver(
false /* insecure_dns_client_enabled */,
net::DnsConfig::SecureDnsMode::OFF,
base::nullopt /* dns_over_https_servers */);
- EXPECT_FALSE(service()
- ->host_resolver_manager()
- ->GetInsecureDnsClientEnabledForTesting());
+ EXPECT_FALSE(dns_client_ptr->CanUseInsecureDnsTransactions());
EXPECT_EQ(net::DnsConfig::SecureDnsMode::OFF,
- service()->host_resolver_manager()->GetSecureDnsModeForTesting());
+ dns_client_ptr->GetEffectiveConfig()->secure_dns_mode);
service()->ConfigureStubHostResolver(
false /* insecure_dns_client_enabled */,
net::DnsConfig::SecureDnsMode::AUTOMATIC,
base::nullopt /* dns_over_https_servers */);
- EXPECT_FALSE(service()
- ->host_resolver_manager()
- ->GetInsecureDnsClientEnabledForTesting());
+ EXPECT_FALSE(dns_client_ptr->CanUseInsecureDnsTransactions());
EXPECT_EQ(net::DnsConfig::SecureDnsMode::OFF,
- service()->host_resolver_manager()->GetSecureDnsModeForTesting());
+ dns_client_ptr->GetEffectiveConfig()->secure_dns_mode);
std::vector<mojom::DnsOverHttpsServerPtr> dns_over_https_servers_ptr;
mojom::DnsOverHttpsServerPtr dns_over_https_server =
@@ -485,11 +487,9 @@
service()->ConfigureStubHostResolver(false /* insecure_dns_client_enabled */,
net::DnsConfig::SecureDnsMode::AUTOMATIC,
std::move(dns_over_https_servers_ptr));
- EXPECT_FALSE(service()
- ->host_resolver_manager()
- ->GetInsecureDnsClientEnabledForTesting());
+ EXPECT_FALSE(dns_client_ptr->CanUseInsecureDnsTransactions());
EXPECT_EQ(net::DnsConfig::SecureDnsMode::AUTOMATIC,
- service()->host_resolver_manager()->GetSecureDnsModeForTesting());
+ dns_client_ptr->GetEffectiveConfig()->secure_dns_mode);
}
TEST_F(NetworkServiceTest, DnsOverHttpsEnableDisable) {
@@ -507,6 +507,16 @@
service()->CreateNetworkContext(mojo::MakeRequest(&network_context),
std::move(context_params));
+ // Create valid DnsConfig.
+ net::DnsConfig config;
+ config.nameservers.push_back(net::IPEndPoint());
+ auto dns_client = std::make_unique<net::MockDnsClient>(
+ std::move(config), net::MockDnsClientRuleList());
+ dns_client->set_ignore_system_config_changes(true);
+ net::DnsClient* dns_client_ptr = dns_client.get();
+ service()->host_resolver_manager()->SetDnsClientForTesting(
+ std::move(dns_client));
+
// Enable DNS over HTTPS for one server.
std::vector<mojom::DnsOverHttpsServerPtr> dns_over_https_servers_ptr;
@@ -521,12 +531,11 @@
net::DnsConfig::SecureDnsMode::AUTOMATIC,
std::move(dns_over_https_servers_ptr));
EXPECT_TRUE(service()->host_resolver_manager()->GetDnsConfigAsValue());
- const auto* dns_over_https_servers =
- service()->host_resolver_manager()->GetDnsOverHttpsServersForTesting();
- ASSERT_TRUE(dns_over_https_servers);
- ASSERT_EQ(1u, dns_over_https_servers->size());
- EXPECT_EQ(kServer1, (*dns_over_https_servers)[0].server_template);
- EXPECT_EQ(kServer1UsePost, (*dns_over_https_servers)[0].use_post);
+ std::vector<net::DnsConfig::DnsOverHttpsServerConfig> dns_over_https_servers =
+ dns_client_ptr->GetEffectiveConfig()->dns_over_https_servers;
+ ASSERT_EQ(1u, dns_over_https_servers.size());
+ EXPECT_EQ(kServer1, dns_over_https_servers[0].server_template);
+ EXPECT_EQ(kServer1UsePost, dns_over_https_servers[0].use_post);
// Enable DNS over HTTPS for two servers.
@@ -546,13 +555,12 @@
std::move(dns_over_https_servers_ptr));
EXPECT_TRUE(service()->host_resolver_manager()->GetDnsConfigAsValue());
dns_over_https_servers =
- service()->host_resolver_manager()->GetDnsOverHttpsServersForTesting();
- ASSERT_TRUE(dns_over_https_servers);
- ASSERT_EQ(2u, dns_over_https_servers->size());
- EXPECT_EQ(kServer2, (*dns_over_https_servers)[0].server_template);
- EXPECT_EQ(kServer2UsePost, (*dns_over_https_servers)[0].use_post);
- EXPECT_EQ(kServer3, (*dns_over_https_servers)[1].server_template);
- EXPECT_EQ(kServer3UsePost, (*dns_over_https_servers)[1].use_post);
+ dns_client_ptr->GetEffectiveConfig()->dns_over_https_servers;
+ ASSERT_EQ(2u, dns_over_https_servers.size());
+ EXPECT_EQ(kServer2, dns_over_https_servers[0].server_template);
+ EXPECT_EQ(kServer2UsePost, dns_over_https_servers[0].use_post);
+ EXPECT_EQ(kServer3, dns_over_https_servers[1].server_template);
+ EXPECT_EQ(kServer3UsePost, dns_over_https_servers[1].use_post);
// Destroying the primary NetworkContext should disable DNS over HTTPS.
network_context.reset();
@@ -560,8 +568,9 @@
// DnsClient is still enabled.
EXPECT_TRUE(service()->host_resolver_manager()->GetDnsConfigAsValue());
// DNS over HTTPS is not.
- EXPECT_FALSE(
- service()->host_resolver_manager()->GetDnsOverHttpsServersForTesting());
+ dns_over_https_servers =
+ dns_client_ptr->GetEffectiveConfig()->dns_over_https_servers;
+ EXPECT_TRUE(dns_over_https_servers.empty());
}
#endif // !defined(OS_IOS)