123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "net/dns/host_resolver.h"
- #include <set>
- #include <string>
- #include <utility>
- #include <vector>
- #include "base/bind.h"
- #include "base/check.h"
- #include "base/no_destructor.h"
- #include "base/notreached.h"
- #include "base/ranges/algorithm.h"
- #include "base/strings/string_number_conversions.h"
- #include "base/time/time_delta_from_string.h"
- #include "base/values.h"
- #include "net/base/address_list.h"
- #include "net/base/features.h"
- #include "net/base/net_errors.h"
- #include "net/base/network_change_notifier.h"
- #include "net/dns/context_host_resolver.h"
- #include "net/dns/dns_client.h"
- #include "net/dns/dns_util.h"
- #include "net/dns/host_cache.h"
- #include "net/dns/host_resolver_manager.h"
- #include "net/dns/host_resolver_results.h"
- #include "net/dns/mapped_host_resolver.h"
- #include "net/dns/resolve_context.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- #if BUILDFLAG(IS_ANDROID)
- #include "base/android/build_info.h"
- #include "net/android/network_library.h"
- #endif // BUILDFLAG(IS_ANDROID)
- namespace net {
- namespace {
- // The experiment settings of features::kUseDnsHttpsSvcb. See the comments in
- // net/base/features.h for more details.
- const char kUseDnsHttpsSvcbEnable[] = "enable";
- const char kUseDnsHttpsSvcbEnableInsecure[] = "enable_insecure";
- const char kUseDnsHttpsSvcbInsecureExtraTimeMax[] = "insecure_extra_time_max";
- const char kUseDnsHttpsSvcbInsecureExtraTimePercent[] =
- "insecure_extra_time_percent";
- const char kUseDnsHttpsSvcbInsecureExtraTimeMin[] = "insecure_extra_time_min";
- const char kUseDnsHttpsSvcbSecureExtraTimeMax[] = "secure_extra_time_max";
- const char kUseDnsHttpsSvcbSecureExtraTimePercent[] =
- "secure_extra_time_percent";
- const char kUseDnsHttpsSvcbSecureExtraTimeMin[] = "secure_extra_time_min";
- const char kUseDnsHttpsSvcbExtraTimeAbsolute[] = "extra_time_absolute";
- const char kUseDnsHttpsSvcbExtraTimePercent[] = "extra_time_percent";
- class FailingRequestImpl : public HostResolver::ResolveHostRequest,
- public HostResolver::ProbeRequest {
- public:
- explicit FailingRequestImpl(int error) : error_(error) {}
- FailingRequestImpl(const FailingRequestImpl&) = delete;
- FailingRequestImpl& operator=(const FailingRequestImpl&) = delete;
- ~FailingRequestImpl() override = default;
- int Start(CompletionOnceCallback callback) override { return error_; }
- int Start() override { return error_; }
- AddressList* GetAddressResults() const override { return nullptr; }
- std::vector<HostResolverEndpointResult>* GetEndpointResults() const override {
- return nullptr;
- }
- const absl::optional<std::vector<std::string>>& GetTextResults()
- const override {
- static const base::NoDestructor<absl::optional<std::vector<std::string>>>
- nullopt_result;
- return *nullopt_result;
- }
- const absl::optional<std::vector<HostPortPair>>& GetHostnameResults()
- const override {
- static const base::NoDestructor<absl::optional<std::vector<HostPortPair>>>
- nullopt_result;
- return *nullopt_result;
- }
- const std::set<std::string>* GetDnsAliasResults() const override {
- return nullptr;
- }
- ResolveErrorInfo GetResolveErrorInfo() const override {
- return ResolveErrorInfo(error_);
- }
- const absl::optional<HostCache::EntryStaleness>& GetStaleInfo()
- const override {
- static const absl::optional<HostCache::EntryStaleness> nullopt_result;
- return nullopt_result;
- }
- private:
- const int error_;
- };
- bool EndpointResultIsNonProtocol(const HostResolverEndpointResult& result) {
- return result.metadata.supported_protocol_alpns.empty();
- }
- void GetTimeDeltaFromDictString(const base::Value::Dict& args,
- base::StringPiece key,
- base::TimeDelta* out) {
- const std::string* value_string = args.FindString(key);
- if (!value_string)
- return;
- *out = base::TimeDeltaFromString(*value_string).value_or(*out);
- }
- } // namespace
- HostResolver::HttpsSvcbOptions::HttpsSvcbOptions() = default;
- HostResolver::HttpsSvcbOptions::HttpsSvcbOptions(
- const HttpsSvcbOptions& other) = default;
- HostResolver::HttpsSvcbOptions::HttpsSvcbOptions(HttpsSvcbOptions&& other) =
- default;
- HostResolver::HttpsSvcbOptions::~HttpsSvcbOptions() = default;
- // static
- HostResolver::HttpsSvcbOptions HostResolver::HttpsSvcbOptions::FromDict(
- const base::Value::Dict& dict) {
- net::HostResolver::HttpsSvcbOptions options;
- options.enable =
- dict.FindBool(kUseDnsHttpsSvcbEnable).value_or(options.enable);
- options.enable_insecure = dict.FindBool(kUseDnsHttpsSvcbEnableInsecure)
- .value_or(options.enable_insecure);
- GetTimeDeltaFromDictString(dict, kUseDnsHttpsSvcbInsecureExtraTimeMax,
- &options.insecure_extra_time_max);
- options.insecure_extra_time_percent =
- dict.FindInt(kUseDnsHttpsSvcbInsecureExtraTimePercent)
- .value_or(options.insecure_extra_time_percent);
- GetTimeDeltaFromDictString(dict, kUseDnsHttpsSvcbInsecureExtraTimeMin,
- &options.insecure_extra_time_min);
- GetTimeDeltaFromDictString(dict, kUseDnsHttpsSvcbSecureExtraTimeMax,
- &options.secure_extra_time_max);
- options.secure_extra_time_percent =
- dict.FindInt(kUseDnsHttpsSvcbSecureExtraTimePercent)
- .value_or(options.secure_extra_time_percent);
- GetTimeDeltaFromDictString(dict, kUseDnsHttpsSvcbSecureExtraTimeMin,
- &options.secure_extra_time_min);
- GetTimeDeltaFromDictString(dict, kUseDnsHttpsSvcbExtraTimeAbsolute,
- &options.extra_time_absolute);
- options.extra_time_percent = dict.FindInt(kUseDnsHttpsSvcbExtraTimePercent)
- .value_or(options.extra_time_percent);
- return options;
- }
- // static
- HostResolver::HttpsSvcbOptions HostResolver::HttpsSvcbOptions::FromFeatures() {
- net::HostResolver::HttpsSvcbOptions options;
- options.enable = base::FeatureList::IsEnabled(features::kUseDnsHttpsSvcb);
- options.enable_insecure = features::kUseDnsHttpsSvcbEnableInsecure.Get();
- options.insecure_extra_time_max =
- features::kUseDnsHttpsSvcbInsecureExtraTimeMax.Get();
- options.insecure_extra_time_percent =
- features::kUseDnsHttpsSvcbInsecureExtraTimePercent.Get();
- options.insecure_extra_time_min =
- features::kUseDnsHttpsSvcbInsecureExtraTimeMin.Get();
- options.secure_extra_time_max =
- features::kUseDnsHttpsSvcbSecureExtraTimeMax.Get();
- options.secure_extra_time_percent =
- features::kUseDnsHttpsSvcbSecureExtraTimePercent.Get();
- options.secure_extra_time_min =
- features::kUseDnsHttpsSvcbSecureExtraTimeMin.Get();
- options.extra_time_absolute =
- features::kUseDnsHttpsSvcbExtraTimeAbsolute.Get();
- options.extra_time_percent = features::kUseDnsHttpsSvcbExtraTimePercent.Get();
- return options;
- }
- HostResolver::ManagerOptions::ManagerOptions() = default;
- HostResolver::ManagerOptions::ManagerOptions(const ManagerOptions& other) =
- default;
- HostResolver::ManagerOptions::ManagerOptions(ManagerOptions&& other) = default;
- HostResolver::ManagerOptions::~ManagerOptions() = default;
- const std::vector<bool>*
- HostResolver::ResolveHostRequest::GetExperimentalResultsForTesting() const {
- NOTREACHED();
- return nullptr;
- }
- const size_t HostResolver::ManagerOptions::kDefaultRetryAttempts =
- static_cast<size_t>(-1);
- std::unique_ptr<HostResolver> HostResolver::Factory::CreateResolver(
- HostResolverManager* manager,
- base::StringPiece host_mapping_rules,
- bool enable_caching) {
- return HostResolver::CreateResolver(manager, host_mapping_rules,
- enable_caching);
- }
- std::unique_ptr<HostResolver> HostResolver::Factory::CreateStandaloneResolver(
- NetLog* net_log,
- const ManagerOptions& options,
- base::StringPiece host_mapping_rules,
- bool enable_caching) {
- return HostResolver::CreateStandaloneResolver(
- net_log, options, host_mapping_rules, enable_caching);
- }
- HostResolver::ResolveHostParameters::ResolveHostParameters() = default;
- HostResolver::ResolveHostParameters::ResolveHostParameters(
- const ResolveHostParameters& other) = default;
- HostResolver::~HostResolver() = default;
- std::unique_ptr<HostResolver::ProbeRequest>
- HostResolver::CreateDohProbeRequest() {
- // Should be overridden in any HostResolver implementation where this method
- // may be called.
- NOTREACHED();
- return nullptr;
- }
- std::unique_ptr<HostResolver::MdnsListener> HostResolver::CreateMdnsListener(
- const HostPortPair& host,
- DnsQueryType query_type) {
- // Should be overridden in any HostResolver implementation where this method
- // may be called.
- NOTREACHED();
- return nullptr;
- }
- HostCache* HostResolver::GetHostCache() {
- return nullptr;
- }
- base::Value HostResolver::GetDnsConfigAsValue() const {
- return base::Value(base::Value::Type::DICTIONARY);
- }
- void HostResolver::SetRequestContext(URLRequestContext* request_context) {
- // Should be overridden in any HostResolver implementation where this method
- // may be called.
- NOTREACHED();
- }
- HostResolverManager* HostResolver::GetManagerForTesting() {
- // Should be overridden in any HostResolver implementation where this method
- // may be called.
- NOTREACHED();
- return nullptr;
- }
- const URLRequestContext* HostResolver::GetContextForTesting() const {
- // Should be overridden in any HostResolver implementation where this method
- // may be called.
- NOTREACHED();
- return nullptr;
- }
- handles::NetworkHandle HostResolver::GetTargetNetworkForTesting() const {
- return handles::kInvalidNetworkHandle;
- }
- // static
- std::unique_ptr<HostResolver> HostResolver::CreateResolver(
- HostResolverManager* manager,
- base::StringPiece host_mapping_rules,
- bool enable_caching) {
- DCHECK(manager);
- auto resolve_context = std::make_unique<ResolveContext>(
- nullptr /* url_request_context */, enable_caching);
- auto resolver = std::make_unique<ContextHostResolver>(
- manager, std::move(resolve_context));
- if (host_mapping_rules.empty())
- return resolver;
- auto remapped_resolver =
- std::make_unique<MappedHostResolver>(std::move(resolver));
- remapped_resolver->SetRulesFromString(host_mapping_rules);
- return remapped_resolver;
- }
- // static
- std::unique_ptr<HostResolver> HostResolver::CreateStandaloneResolver(
- NetLog* net_log,
- absl::optional<ManagerOptions> options,
- base::StringPiece host_mapping_rules,
- bool enable_caching) {
- std::unique_ptr<ContextHostResolver> resolver =
- CreateStandaloneContextResolver(net_log, std::move(options),
- enable_caching);
- if (host_mapping_rules.empty())
- return resolver;
- auto remapped_resolver =
- std::make_unique<MappedHostResolver>(std::move(resolver));
- remapped_resolver->SetRulesFromString(host_mapping_rules);
- return remapped_resolver;
- }
- // static
- std::unique_ptr<ContextHostResolver>
- HostResolver::CreateStandaloneContextResolver(
- NetLog* net_log,
- absl::optional<ManagerOptions> options,
- bool enable_caching) {
- auto resolve_context = std::make_unique<ResolveContext>(
- nullptr /* url_request_context */, enable_caching);
- return std::make_unique<ContextHostResolver>(
- std::make_unique<HostResolverManager>(
- std::move(options).value_or(ManagerOptions()),
- NetworkChangeNotifier::GetSystemDnsConfigNotifier(), net_log),
- std::move(resolve_context));
- }
- // static
- std::unique_ptr<HostResolver>
- HostResolver::CreateStandaloneNetworkBoundResolver(
- NetLog* net_log,
- handles::NetworkHandle target_network,
- absl::optional<ManagerOptions> options,
- base::StringPiece host_mapping_rules,
- bool enable_caching) {
- #if BUILDFLAG(IS_ANDROID)
- // Note that the logic below uses Android APIs that don't work on a sandboxed
- // process: This is not problematic because this function is used only by
- // Cronet which doesn't enable sandboxing.
- auto resolve_context = std::make_unique<ResolveContext>(
- nullptr /*url_request_context */, enable_caching);
- auto manager_options = std::move(options).value_or(ManagerOptions());
- // Support the use of the built-in resolver when possible.
- bool is_builtin_resolver_supported =
- manager_options.insecure_dns_client_enabled &&
- base::android::BuildInfo::GetInstance()->sdk_int() >=
- base::android::SDK_VERSION_P;
- if (is_builtin_resolver_supported) {
- // Pre-existing DnsConfigOverrides is currently ignored, consider extending
- // if a use case arises.
- DCHECK(manager_options.dns_config_overrides == DnsConfigOverrides());
- std::vector<IPEndPoint> dns_servers;
- bool dns_over_tls_active;
- std::string dns_over_tls_hostname;
- std::vector<std::string> search_suffixes;
- if (android::GetDnsServersForNetwork(&dns_servers, &dns_over_tls_active,
- &dns_over_tls_hostname,
- &search_suffixes, target_network)) {
- DnsConfigOverrides dns_config_overrides =
- DnsConfigOverrides::CreateOverridingEverythingWithDefaults();
- dns_config_overrides.nameservers = dns_servers;
- // Android APIs don't specify whether to use DoT or DoH. So, leave the
- // decision to `DnsConfig::allow_dns_over_https_upgrade` default value.
- dns_config_overrides.dns_over_tls_active = dns_over_tls_active;
- dns_config_overrides.dns_over_tls_hostname = dns_over_tls_hostname;
- dns_config_overrides.search = search_suffixes;
- manager_options.dns_config_overrides = dns_config_overrides;
- // Regardless of DoH vs DoT, the important contract to respect is not to
- // perform insecure DNS lookups if `dns_over_tls_active` == true.
- manager_options.additional_types_via_insecure_dns_enabled =
- !dns_over_tls_active;
- } else {
- // Disable when android::GetDnsServersForNetwork fails.
- is_builtin_resolver_supported = false;
- }
- }
- manager_options.insecure_dns_client_enabled = is_builtin_resolver_supported;
- return std::make_unique<ContextHostResolver>(
- HostResolverManager::CreateNetworkBoundHostResolverManager(
- manager_options, target_network, net_log),
- std::move(resolve_context));
- #else // !BUILDFLAG(IS_ANDROID)
- NOTIMPLEMENTED();
- return nullptr;
- #endif // BUILDFLAG(IS_ANDROID)
- }
- // static
- AddressFamily HostResolver::DnsQueryTypeSetToAddressFamily(
- DnsQueryTypeSet dns_query_types) {
- DCHECK(HasAddressType(dns_query_types));
- // If the set of query types contains A and AAAA, defer the choice of address
- // family. Otherwise, pick the corresponding address family.
- if (dns_query_types.HasAll({DnsQueryType::A, DnsQueryType::AAAA}))
- return ADDRESS_FAMILY_UNSPECIFIED;
- if (dns_query_types.Has(DnsQueryType::AAAA))
- return ADDRESS_FAMILY_IPV6;
- DCHECK(dns_query_types.Has(DnsQueryType::A));
- return ADDRESS_FAMILY_IPV4;
- }
- // static
- HostResolverFlags HostResolver::ParametersToHostResolverFlags(
- const ResolveHostParameters& parameters) {
- HostResolverFlags flags = 0;
- if (parameters.include_canonical_name)
- flags |= HOST_RESOLVER_CANONNAME;
- if (parameters.loopback_only)
- flags |= HOST_RESOLVER_LOOPBACK_ONLY;
- if (parameters.avoid_multicast_resolution)
- flags |= HOST_RESOLVER_AVOID_MULTICAST;
- return flags;
- }
- // static
- int HostResolver::SquashErrorCode(int error) {
- // TODO(crbug.com/1043281): Consider squashing ERR_INTERNET_DISCONNECTED.
- if (error == OK || error == ERR_IO_PENDING ||
- error == ERR_INTERNET_DISCONNECTED || error == ERR_NAME_NOT_RESOLVED ||
- error == ERR_DNS_NAME_HTTPS_ONLY) {
- return error;
- } else {
- return ERR_NAME_NOT_RESOLVED;
- }
- }
- // static
- std::vector<HostResolverEndpointResult>
- HostResolver::AddressListToEndpointResults(const AddressList& address_list) {
- HostResolverEndpointResult connection_endpoint;
- connection_endpoint.ip_endpoints = address_list.endpoints();
- std::vector<HostResolverEndpointResult> list;
- list.push_back(std::move(connection_endpoint));
- return list;
- }
- // static
- AddressList HostResolver::EndpointResultToAddressList(
- const std::vector<HostResolverEndpointResult>& endpoints,
- const std::set<std::string>& aliases) {
- AddressList list;
- auto non_protocol_endpoint =
- base::ranges::find_if(endpoints, &EndpointResultIsNonProtocol);
- if (non_protocol_endpoint == endpoints.end())
- return list;
- list.endpoints() = non_protocol_endpoint->ip_endpoints;
- std::vector<std::string> aliases_vector(aliases.begin(), aliases.end());
- list.SetDnsAliases(std::move(aliases_vector));
- return list;
- }
- HostResolver::HostResolver() = default;
- // static
- std::unique_ptr<HostResolver::ResolveHostRequest>
- HostResolver::CreateFailingRequest(int error) {
- return std::make_unique<FailingRequestImpl>(error);
- }
- // static
- std::unique_ptr<HostResolver::ProbeRequest>
- HostResolver::CreateFailingProbeRequest(int error) {
- return std::make_unique<FailingRequestImpl>(error);
- }
- } // namespace net
|