123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef NET_DNS_HOST_RESOLVER_H_
- #define NET_DNS_HOST_RESOLVER_H_
- #include <stddef.h>
- #include <stdint.h>
- #include <memory>
- #include <set>
- #include <string>
- #include <vector>
- #include "base/strings/string_piece.h"
- #include "net/base/address_family.h"
- #include "net/base/completion_once_callback.h"
- #include "net/base/host_port_pair.h"
- #include "net/base/network_handle.h"
- #include "net/base/network_isolation_key.h"
- #include "net/base/request_priority.h"
- #include "net/dns/host_cache.h"
- #include "net/dns/host_resolver_results.h"
- #include "net/dns/public/dns_config_overrides.h"
- #include "net/dns/public/dns_query_type.h"
- #include "net/dns/public/host_resolver_source.h"
- #include "net/dns/public/mdns_listener_update_type.h"
- #include "net/dns/public/resolve_error_info.h"
- #include "net/dns/public/secure_dns_policy.h"
- #include "net/log/net_log_with_source.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- #include "url/scheme_host_port.h"
- namespace base {
- class Value;
- }
- namespace net {
- class AddressList;
- class ContextHostResolver;
- class DnsClient;
- struct DnsConfigOverrides;
- class HostResolverManager;
- class NetLog;
- class URLRequestContext;
- // This class represents the task of resolving hostnames (or IP address
- // literal) to an AddressList object (or other DNS-style results).
- //
- // Typically implemented by ContextHostResolver or wrappers thereof. See
- // HostResolver::Create[...]() methods for construction or URLRequestContext for
- // retrieval.
- //
- // See mock_host_resolver.h for test implementations.
- class NET_EXPORT HostResolver {
- public:
- using Host = absl::variant<url::SchemeHostPort, HostPortPair>;
- // Handler for an individual host resolution request. Created by
- // HostResolver::CreateRequest().
- class ResolveHostRequest {
- public:
- // Destruction cancels the request if running asynchronously, causing the
- // callback to never be invoked.
- virtual ~ResolveHostRequest() = default;
- // Starts the request and returns a network error code.
- //
- // If the request could not be handled synchronously, returns
- // |ERR_IO_PENDING|, and completion will be signaled later via |callback|.
- // On any other returned value, the request was handled synchronously and
- // |callback| will not be invoked.
- //
- // Results in ERR_NAME_NOT_RESOLVED if the hostname is not resolved. More
- // detail about the underlying error can be retrieved using
- // GetResolveErrorInfo().
- //
- // The parent HostResolver must still be alive when Start() is called, but
- // if it is destroyed before an asynchronous result completes, the request
- // will be automatically cancelled.
- //
- // If cancelled before |callback| is invoked, it will never be invoked.
- virtual int Start(CompletionOnceCallback callback) = 0;
- // Address record (A or AAAA) results of the request. Should only be called
- // after Start() signals completion, either by invoking the callback or by
- // returning a result other than |ERR_IO_PENDING|.
- //
- // TODO(crbug.com/1264933): Remove and replace all usage with
- // GetEndpointResults().
- virtual const AddressList* GetAddressResults() const = 0;
- // Endpoint results for `A`, `AAAA`, `UNSPECIFIED`, or `HTTPS` requests.
- // Should only be called after Start() signals completion, either by
- // invoking the callback or by returning a result other than
- // `ERR_IO_PENDING`.
- virtual const std::vector<HostResolverEndpointResult>* GetEndpointResults()
- const = 0;
- // Text record (TXT) results of the request. Should only be called after
- // Start() signals completion, either by invoking the callback or by
- // returning a result other than |ERR_IO_PENDING|.
- virtual const absl::optional<std::vector<std::string>>& GetTextResults()
- const = 0;
- // Hostname record (SRV or PTR) results of the request. For SRV results,
- // hostnames are ordered acording to their priorities and weights. See RFC
- // 2782.
- //
- // Should only be called after Start() signals completion, either by
- // invoking the callback or by returning a result other than
- // |ERR_IO_PENDING|.
- virtual const absl::optional<std::vector<HostPortPair>>&
- GetHostnameResults() const = 0;
- // Any DNS record aliases, such as CNAME aliases, found as a result of an
- // address query. Includes all known aliases, e.g. from A, AAAA, or HTTPS,
- // not just from the address used for the connection, in no particular
- // order. Should only be called after Start() signals completion, either by
- // invoking the callback or by returning a result other than
- // `ERR_IO_PENDING`. Returns a list of aliases that has been fixed up and
- // canonicalized (as URL hostnames), and thus may differ from the results
- // stored directly in the AddressList.
- //
- // If `ResolveHostParameters::include_canonical_name` was true, alias
- // results will always be the single "canonical name" received from the
- // system resolver without URL hostname canonicalization (or an empty set or
- // `nullptr` in the unusual case that the system resolver did not give a
- // canonical name).
- virtual const std::set<std::string>* GetDnsAliasResults() const = 0;
- // Result of an experimental query. Meaning depends on the specific query
- // type, but each boolean value generally refers to a valid or invalid
- // record of the experimental type.
- NET_EXPORT virtual const std::vector<bool>*
- GetExperimentalResultsForTesting() const;
- // Error info for the request.
- //
- // Should only be called after Start() signals completion, either by
- // invoking the callback or by returning a result other than
- // |ERR_IO_PENDING|.
- virtual ResolveErrorInfo GetResolveErrorInfo() const = 0;
- // Information about the result's staleness in the host cache. Only
- // available if results were received from the host cache.
- //
- // Should only be called after Start() signals completion, either by
- // invoking the callback or by returning a result other than
- // |ERR_IO_PENDING|.
- virtual const absl::optional<HostCache::EntryStaleness>& GetStaleInfo()
- const = 0;
- // Changes the priority of the specified request. Can only be called while
- // the request is running (after Start() returns |ERR_IO_PENDING| and before
- // the callback is invoked).
- virtual void ChangeRequestPriority(RequestPriority priority) {}
- };
- // Handler for an activation of probes controlled by a HostResolver. Created
- // by HostResolver::CreateDohProbeRequest().
- class ProbeRequest {
- public:
- // Destruction cancels the request and all probes.
- virtual ~ProbeRequest() = default;
- // Activates async running of probes. Always returns ERR_IO_PENDING or an
- // error from activating probes. No callback as probes will never "complete"
- // until cancellation.
- virtual int Start() = 0;
- };
- // The options for features::kUseDnsHttpsSvcb experiment. See the comments
- // in net/base/features.h for more details.
- struct NET_EXPORT HttpsSvcbOptions {
- HttpsSvcbOptions();
- HttpsSvcbOptions(const HttpsSvcbOptions&);
- HttpsSvcbOptions(HttpsSvcbOptions&&);
- HttpsSvcbOptions& operator=(const HttpsSvcbOptions&) = default;
- HttpsSvcbOptions& operator=(HttpsSvcbOptions&&) = default;
- ~HttpsSvcbOptions();
- static HttpsSvcbOptions FromDict(const base::Value::Dict& dict);
- static HttpsSvcbOptions FromFeatures();
- bool enable = false;
- bool enable_insecure = false;
- base::TimeDelta insecure_extra_time_max;
- int insecure_extra_time_percent = 0;
- base::TimeDelta insecure_extra_time_min;
- base::TimeDelta secure_extra_time_max;
- int secure_extra_time_percent = 0;
- base::TimeDelta secure_extra_time_min;
- base::TimeDelta extra_time_absolute;
- int extra_time_percent = 0;
- };
- // Parameter-grouping struct for additional optional parameters for creation
- // of HostResolverManagers and stand-alone HostResolvers.
- struct NET_EXPORT ManagerOptions {
- ManagerOptions();
- ManagerOptions(const ManagerOptions&);
- ManagerOptions(ManagerOptions&&);
- ManagerOptions& operator=(const ManagerOptions&) = default;
- ManagerOptions& operator=(ManagerOptions&&) = default;
- ~ManagerOptions();
- // Set |max_concurrent_resolves| to this to select a default level
- // of concurrency.
- static const size_t kDefaultParallelism = 0;
- // Set |max_system_retry_attempts| to this to select a default retry value.
- static const size_t kDefaultRetryAttempts;
- // How many resolve requests will be allowed to run in parallel.
- // |kDefaultParallelism| for the resolver to choose a default value.
- size_t max_concurrent_resolves = kDefaultParallelism;
- // The maximum number of times to retry for host resolution if using the
- // system resolver. No effect when the system resolver is not used.
- // |kDefaultRetryAttempts| for the resolver to choose a default value.
- size_t max_system_retry_attempts = kDefaultRetryAttempts;
- // Initial setting for whether the insecure portion of the built-in
- // asynchronous DnsClient is enabled or disabled. See HostResolverManager::
- // SetInsecureDnsClientEnabled() for details.
- bool insecure_dns_client_enabled = false;
- // Initial setting for whether additional DNS types (e.g. HTTPS) may be
- // queried when using the built-in resolver for insecure DNS.
- bool additional_types_via_insecure_dns_enabled = true;
- // Initial configuration overrides for the built-in asynchronous DnsClient.
- // See HostResolverManager::SetDnsConfigOverrides() for details.
- DnsConfigOverrides dns_config_overrides;
- // If set to |false|, when on a WiFi connection, IPv6 will be assumed to be
- // unreachable without actually checking. See https://crbug.com/696569 for
- // further context.
- bool check_ipv6_on_wifi = true;
- // An experimental options for features::kUseDnsHttpsSvcb
- // and features::kUseDnsHttpsSvcbAlpn.
- absl::optional<HostResolver::HttpsSvcbOptions> https_svcb_options;
- };
- // Factory class. Useful for classes that need to inject and override resolver
- // creation for tests.
- class NET_EXPORT Factory {
- public:
- virtual ~Factory() = default;
- // See HostResolver::CreateResolver.
- virtual std::unique_ptr<HostResolver> CreateResolver(
- HostResolverManager* manager,
- base::StringPiece host_mapping_rules,
- bool enable_caching);
- // See HostResolver::CreateStandaloneResolver.
- virtual std::unique_ptr<HostResolver> CreateStandaloneResolver(
- NetLog* net_log,
- const ManagerOptions& options,
- base::StringPiece host_mapping_rules,
- bool enable_caching);
- };
- // Parameter-grouping struct for additional optional parameters for
- // CreateRequest() calls. All fields are optional and have a reasonable
- // default.
- struct NET_EXPORT ResolveHostParameters {
- ResolveHostParameters();
- ResolveHostParameters(const ResolveHostParameters& other);
- // Requested DNS query type. If UNSPECIFIED, the resolver will select a set
- // of queries automatically. It will select A, AAAA, or both as the address
- // queries, depending on IPv4/IPv6 settings and reachability. It may also
- // replace UNSPECIFIED with additional queries, such as HTTPS.
- DnsQueryType dns_query_type = DnsQueryType::UNSPECIFIED;
- // The initial net priority for the host resolution request.
- RequestPriority initial_priority = RequestPriority::DEFAULT_PRIORITY;
- // The source to use for resolved addresses. Default allows the resolver to
- // pick an appropriate source. Only affects use of big external sources (eg
- // calling the system for resolution or using DNS). Even if a source is
- // specified, results can still come from cache, resolving "localhost" or
- // IP literals, etc.
- HostResolverSource source = HostResolverSource::ANY;
- enum class CacheUsage {
- // Results may come from the host cache if non-stale.
- ALLOWED,
- // Results may come from the host cache even if stale (by expiration or
- // network changes). In secure dns AUTOMATIC mode, the cache is checked
- // for both secure and insecure results prior to any secure DNS lookups to
- // minimize response time.
- STALE_ALLOWED,
- // Results will not come from the host cache.
- DISALLOWED,
- };
- CacheUsage cache_usage = CacheUsage::ALLOWED;
- // If |true|, requests special behavior that the "canonical name" be
- // requested from the system and be returned as the only entry in
- // `ResolveHostRequest::GetDnsAliasResults()` results. Setting this
- // parameter is disallowed for any requests that cannot be resolved using
- // the system resolver, e.g. non-address requests or requests specifying a
- // non-`SYSTEM` `source`.
- //
- // TODO(crbug.com/1282281): Consider allowing the built-in resolver to still
- // be used with this parameter. Would then function as a request to just
- // keep the single final name from the alias chain instead of all aliases,
- // and also skip the canonicalization unless that canonicalization is found
- // to be fine for usage.
- bool include_canonical_name = false;
- // Hint to the resolver that resolution is only being requested for loopback
- // hosts.
- bool loopback_only = false;
- // Set |true| iff the host resolve request is only being made speculatively
- // to fill the cache and the result addresses will not be used. The request
- // will receive special logging/observer treatment, and the result addresses
- // will always be |absl::nullopt|.
- bool is_speculative = false;
- // If `true`, resolver may (but is not guaranteed to) take steps to avoid
- // the name being resolved via LLMNR or mDNS. Useful for requests where it
- // is not desired to wait for longer timeouts on potential negative results,
- // as is typically the case for LLMNR or mDNS queries without any results.
- bool avoid_multicast_resolution = false;
- // Controls the resolver's Secure DNS behavior for this request.
- SecureDnsPolicy secure_dns_policy = SecureDnsPolicy::kAllow;
- };
- // Handler for an ongoing MDNS listening operation. Created by
- // HostResolver::CreateMdnsListener().
- class MdnsListener {
- public:
- // Delegate type for result update notifications from MdnsListener. All
- // methods have a |result_type| field to allow a single delegate to be
- // passed to multiple MdnsListeners and be used to listen for updates for
- // multiple types for the same host.
- class Delegate {
- public:
- virtual ~Delegate() = default;
- virtual void OnAddressResult(MdnsListenerUpdateType update_type,
- DnsQueryType result_type,
- IPEndPoint address) = 0;
- virtual void OnTextResult(MdnsListenerUpdateType update_type,
- DnsQueryType result_type,
- std::vector<std::string> text_records) = 0;
- virtual void OnHostnameResult(MdnsListenerUpdateType update_type,
- DnsQueryType result_type,
- HostPortPair host) = 0;
- // For results which may be valid MDNS but are not handled/parsed by
- // HostResolver, e.g. pointers to the root domain.
- virtual void OnUnhandledResult(MdnsListenerUpdateType update_type,
- DnsQueryType result_type) = 0;
- };
- // Destruction cancels the listening operation.
- virtual ~MdnsListener() = default;
- // Begins the listening operation, invoking |delegate| whenever results are
- // updated. |delegate| will no longer be called once the listening operation
- // is cancelled (via destruction of |this|).
- virtual int Start(Delegate* delegate) = 0;
- };
- HostResolver(const HostResolver&) = delete;
- HostResolver& operator=(const HostResolver&) = delete;
- // If any completion callbacks are pending when the resolver is destroyed,
- // the host resolutions are cancelled, and the completion callbacks will not
- // be called.
- virtual ~HostResolver();
- // Cancels any pending requests without calling callbacks, same as
- // destruction, except also leaves the resolver in a mostly-noop state. Any
- // future request Start() calls (for requests created before or after
- // OnShutdown()) will immediately fail with ERR_CONTEXT_SHUT_DOWN.
- virtual void OnShutdown() = 0;
- // Creates a request to resolve the given hostname (or IP address literal).
- // Profiling information for the request is saved to |net_log| if non-NULL.
- //
- // Additional parameters may be set using |optional_parameters|. Reasonable
- // defaults will be used if passed |nullptr|.
- virtual std::unique_ptr<ResolveHostRequest> CreateRequest(
- url::SchemeHostPort host,
- NetworkIsolationKey network_isolation_key,
- NetLogWithSource net_log,
- absl::optional<ResolveHostParameters> optional_parameters) = 0;
- // Create requests when scheme is unknown or non-standard.
- // TODO(crbug.com/1206799): Rename to discourage use when scheme is known.
- virtual std::unique_ptr<ResolveHostRequest> CreateRequest(
- const HostPortPair& host,
- const NetworkIsolationKey& network_isolation_key,
- const NetLogWithSource& net_log,
- const absl::optional<ResolveHostParameters>& optional_parameters) = 0;
- // Creates a request to probe configured DoH servers to find which can be used
- // successfully.
- virtual std::unique_ptr<ProbeRequest> CreateDohProbeRequest();
- // Create a listener to watch for updates to an MDNS result.
- virtual std::unique_ptr<MdnsListener> CreateMdnsListener(
- const HostPortPair& host,
- DnsQueryType query_type);
- // Returns the HostResolverCache |this| uses, or NULL if there isn't one.
- // Used primarily to clear the cache and for getting debug information.
- virtual HostCache* GetHostCache();
- // Returns the current DNS configuration |this| is using, as a Value.
- virtual base::Value GetDnsConfigAsValue() const;
- // Set the associated URLRequestContext, generally expected to be called by
- // URLRequestContextBuilder on passing ownership of |this| to a context. May
- // only be called once.
- virtual void SetRequestContext(URLRequestContext* request_context);
- virtual HostResolverManager* GetManagerForTesting();
- virtual const URLRequestContext* GetContextForTesting() const;
- virtual handles::NetworkHandle GetTargetNetworkForTesting() const;
- // Creates a new HostResolver. |manager| must outlive the returned resolver.
- //
- // If |mapping_rules| is non-empty, the mapping rules will be applied to
- // requests. See MappedHostResolver for details.
- static std::unique_ptr<HostResolver> CreateResolver(
- HostResolverManager* manager,
- base::StringPiece host_mapping_rules = "",
- bool enable_caching = true);
- // Creates a HostResolver independent of any global HostResolverManager. Only
- // for tests and standalone tools not part of the browser.
- //
- // If |mapping_rules| is non-empty, the mapping rules will be applied to
- // requests. See MappedHostResolver for details.
- static std::unique_ptr<HostResolver> CreateStandaloneResolver(
- NetLog* net_log,
- absl::optional<ManagerOptions> options = absl::nullopt,
- base::StringPiece host_mapping_rules = "",
- bool enable_caching = true);
- // Same, but explicitly returns the implementing ContextHostResolver. Only
- // used by tests and by StaleHostResolver in Cronet. No mapping rules can be
- // applied because doing so requires wrapping the ContextHostResolver.
- static std::unique_ptr<ContextHostResolver> CreateStandaloneContextResolver(
- NetLog* net_log,
- absl::optional<ManagerOptions> options = absl::nullopt,
- bool enable_caching = true);
- // Same, but bind the resolver to `target_network`: all lookups will be
- // performed exclusively for `target_network`, lookups will fail if
- // `target_network` disconnects. This can only be used by network-bound
- // URLRequestContexts.
- // Due to the current implementation, if `options` is specified, its
- // DnsConfigOverrides parameter must be empty.
- // Only implemented for Android starting from Marshmallow.
- static std::unique_ptr<HostResolver> CreateStandaloneNetworkBoundResolver(
- NetLog* net_log,
- handles::NetworkHandle network,
- absl::optional<ManagerOptions> options = absl::nullopt,
- base::StringPiece host_mapping_rules = "",
- bool enable_caching = true);
- // Helpers for interacting with HostCache and ProcResolver.
- static AddressFamily DnsQueryTypeSetToAddressFamily(
- DnsQueryTypeSet query_types);
- static HostResolverFlags ParametersToHostResolverFlags(
- const ResolveHostParameters& parameters);
- // Helper for squashing error code to a small set of DNS error codes.
- static int SquashErrorCode(int error);
- // Utility to convert an AddressList to an equivalent list of
- // `HostResolverEndpointResults`. Assumes all addresses in the input list
- // represent the default non-protocol endpoint.
- //
- // TODO(crbug.com/1264933): Delete once `AddressList` usage is fully replaced
- // in `HostResolver` and results.
- static std::vector<HostResolverEndpointResult> AddressListToEndpointResults(
- const AddressList& address_list);
- // Opposite conversion of `AddressListToEndpointResults()`. Builds an
- // AddressList from the first non-protocol endpoint found in `endpoints`.
- //
- // TODO(crbug.com/1264933): Delete once `AddressList` usage is fully replaced
- // in `HostResolver` and results.
- static AddressList EndpointResultToAddressList(
- const std::vector<HostResolverEndpointResult>& endpoints,
- const std::set<std::string>& aliases);
- protected:
- HostResolver();
- // Utility to create a request implementation that always fails with |error|
- // immediately on start.
- static std::unique_ptr<ResolveHostRequest> CreateFailingRequest(int error);
- static std::unique_ptr<ProbeRequest> CreateFailingProbeRequest(int error);
- };
- } // namespace net
- #endif // NET_DNS_HOST_RESOLVER_H_
|