• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_DNS_HOST_RESOLVER_H_
6 #define NET_DNS_HOST_RESOLVER_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <memory>
12 #include <optional>
13 #include <set>
14 #include <string>
15 #include <string_view>
16 #include <type_traits>
17 #include <vector>
18 
19 #include "base/containers/span.h"
20 #include "base/values.h"
21 #include "net/base/address_family.h"
22 #include "net/base/completion_once_callback.h"
23 #include "net/base/connection_endpoint_metadata.h"
24 #include "net/base/host_port_pair.h"
25 #include "net/base/network_anonymization_key.h"
26 #include "net/base/network_handle.h"
27 #include "net/base/request_priority.h"
28 #include "net/dns/host_cache.h"
29 #include "net/dns/host_resolver_system_task.h"
30 #include "net/dns/public/dns_config_overrides.h"
31 #include "net/dns/public/dns_query_type.h"
32 #include "net/dns/public/host_resolver_results.h"
33 #include "net/dns/public/host_resolver_source.h"
34 #include "net/dns/public/mdns_listener_update_type.h"
35 #include "net/dns/public/resolve_error_info.h"
36 #include "net/dns/public/secure_dns_policy.h"
37 #include "net/log/net_log_with_source.h"
38 #include "third_party/abseil-cpp/absl/types/variant.h"
39 #include "url/scheme_host_port.h"
40 
41 namespace net {
42 
43 class AddressList;
44 class ContextHostResolver;
45 class DnsClient;
46 struct DnsConfigOverrides;
47 class HostResolverManager;
48 class NetLog;
49 class URLRequestContext;
50 
51 template <typename T>
requires(T t)52 concept HasConnectionEndpointMetadata = requires(T t) {
53   { t.metadata } -> std::same_as<ConnectionEndpointMetadata&>;
54 };
55 
56 // This class represents the task of resolving hostnames (or IP address
57 // literal) to an AddressList object (or other DNS-style results).
58 //
59 // Typically implemented by ContextHostResolver or wrappers thereof. See
60 // HostResolver::Create[...]() methods for construction or URLRequestContext for
61 // retrieval.
62 //
63 // See mock_host_resolver.h for test implementations.
64 class NET_EXPORT HostResolver {
65  public:
66   class NET_EXPORT Host {
67    public:
68     explicit Host(absl::variant<url::SchemeHostPort, HostPortPair> host);
69     ~Host();
70 
71     Host(const Host&);
72     Host& operator=(const Host&);
73     Host(Host&&);
74     Host& operator=(Host&&);
75 
76     bool HasScheme() const;
77     const std::string& GetScheme() const;
78     std::string GetHostname() const;  // With brackets for IPv6 literals.
79     std::string_view GetHostnameWithoutBrackets() const;
80     uint16_t GetPort() const;
81 
82     std::string ToString() const;
83 
84     const url::SchemeHostPort& AsSchemeHostPort() const;
85 
86     bool operator==(const Host& other) const { return host_ == other.host_; }
87 
88     bool operator<(const Host& other) const { return host_ < other.host_; }
89 
90    private:
91     absl::variant<url::SchemeHostPort, HostPortPair> host_;
92   };
93 
94   // Handler for an individual host resolution request. Created by
95   // HostResolver::CreateRequest().
96   //
97   // TODO(crbug.com/40212535): Most result retrieval here follows a pattern
98   // where it may return null or empty for requests where that result type is
99   // not available. Clean this up to always return empty for such cases and
100   // remove nullability from the return types.
101   class ResolveHostRequest {
102    public:
103     // Destruction cancels the request if running asynchronously, causing the
104     // callback to never be invoked.
105     virtual ~ResolveHostRequest() = default;
106 
107     // Starts the request and returns a network error code.
108     //
109     // If the request could not be handled synchronously, returns
110     // |ERR_IO_PENDING|, and completion will be signaled later via |callback|.
111     // On any other returned value, the request was handled synchronously and
112     // |callback| will not be invoked.
113     //
114     // Results in ERR_NAME_NOT_RESOLVED if the hostname is not resolved. More
115     // detail about the underlying error can be retrieved using
116     // GetResolveErrorInfo().
117     //
118     // The parent HostResolver must still be alive when Start() is called,  but
119     // if it is destroyed before an asynchronous result completes, the request
120     // will be automatically cancelled.
121     //
122     // If cancelled before |callback| is invoked, it will never be invoked.
123     virtual int Start(CompletionOnceCallback callback) = 0;
124 
125     // Address record (A or AAAA) results of the request. Should only be called
126     // after Start() signals completion, either by invoking the callback or by
127     // returning a result other than |ERR_IO_PENDING|. May return nullptr or
128     // empty for non-address requests.
129     //
130     // TODO(crbug.com/40203587): Remove and replace all usage with
131     // GetEndpointResults().
132     virtual const AddressList* GetAddressResults() const = 0;
133 
134     // Endpoint results for `A`, `AAAA`, `UNSPECIFIED`, or `HTTPS` requests.
135     // Should only be called after Start() signals completion, either by
136     // invoking the callback or by returning a result other than
137     // `ERR_IO_PENDING`. May return nullptr or empty for non-address/HTTPS
138     // requests.
139     virtual const std::vector<HostResolverEndpointResult>* GetEndpointResults()
140         const = 0;
141 
142     // Text record (TXT) results of the request. Should only be called after
143     // Start() signals completion, either by invoking the callback or by
144     // returning a result other than |ERR_IO_PENDING|. May return nullptr or
145     // empty for non-TXT requests.
146     virtual const std::vector<std::string>* GetTextResults() const = 0;
147 
148     // Hostname record (SRV or PTR) results of the request. For SRV results,
149     // hostnames are ordered according to their priorities and weights. See RFC
150     // 2782. May return nullptr or empty for non-SRV/PTR requests.
151     //
152     // Should only be called after Start() signals completion, either by
153     // invoking the callback or by returning a result other than
154     // |ERR_IO_PENDING|.
155     virtual const std::vector<HostPortPair>* GetHostnameResults() const = 0;
156 
157     // Any DNS record aliases, such as CNAME aliases, found as a result of an
158     // address query. Includes all known aliases, e.g. from A, AAAA, or HTTPS,
159     // not just from the address used for the connection, in no particular
160     // order. Should only be called after Start() signals completion, either by
161     // invoking the callback or by returning a result other than
162     // `ERR_IO_PENDING`. Returns a list of aliases that has been fixed up and
163     // canonicalized (as URL hostnames), and thus may differ from the results
164     // stored directly in the AddressList. May return nullptr or empty for
165     // non-address/HTTPS requests.
166     //
167     // If `ResolveHostParameters::include_canonical_name` was true, alias
168     // results will always be the single "canonical name" received from the
169     // system resolver without URL hostname canonicalization (or an empty set or
170     // `nullptr` in the unusual case that the system resolver did not give a
171     // canonical name).
172     virtual const std::set<std::string>* GetDnsAliasResults() const = 0;
173 
174     // Result of an experimental query. Meaning depends on the specific query
175     // type, but each boolean value generally refers to a valid or invalid
176     // record of the experimental type. May return nullptr or empty for requests
177     // without experimental result behavior.
178     NET_EXPORT virtual const std::vector<bool>*
179     GetExperimentalResultsForTesting() const;
180 
181     // Error info for the request.
182     //
183     // Should only be called after Start() signals completion, either by
184     // invoking the callback or by returning a result other than
185     // |ERR_IO_PENDING|.
186     virtual ResolveErrorInfo GetResolveErrorInfo() const = 0;
187 
188     // Information about the result's staleness in the host cache. Only
189     // available if results were received from the host cache, otherwise
190     // returns nullopt.
191     //
192     // Should only be called after Start() signals completion, either by
193     // invoking the callback or by returning a result other than
194     // |ERR_IO_PENDING|.
195     virtual const std::optional<HostCache::EntryStaleness>& GetStaleInfo()
196         const = 0;
197 
198     // Changes the priority of the specified request. Can only be called while
199     // the request is running (after Start() returns |ERR_IO_PENDING| and before
200     // the callback is invoked).
ChangeRequestPriority(RequestPriority priority)201     virtual void ChangeRequestPriority(RequestPriority priority) {}
202   };
203 
204   // Handler for a service endpoint resolution request. Unlike
205   // ResolveHostRequest, which waits for all responses, this could provide
206   // intermediate endpoint candidates in the middle of the resolution.
207   //
208   // A client owns an instance of this class. Destruction cancels the request.
209   class ServiceEndpointRequest {
210    public:
211     class Delegate {
212      public:
213       virtual ~Delegate() = default;
214 
215       // Called when the request has updated endpoints.
216       virtual void OnServiceEndpointsUpdated() = 0;
217 
218       // Called when all queries are responded or an error occurred.
219       // Note that this can be called without OnServiceEndpointsUpdated().
220       virtual void OnServiceEndpointRequestFinished(int rv) = 0;
221     };
222 
223     virtual ~ServiceEndpointRequest() = default;
224 
225     // Starts resolving service endpoints. `delegate` is used only when this
226     // method returns ERR_IO_PENDING. When the return value is other than
227     // ERR_IO_PENDING, resolution completed (or an error occurred)
228     // synchronously, and GetEndpointResults() will return finalized results.
229     virtual int Start(Delegate* delegate) = 0;
230 
231     // The current available service endpoints. These can be changed over time
232     // while resolution is still ongoing. Changes are signaled by a call to the
233     // delegate's OnServiceEndpointsUpdated(). Results are finalized when
234     // Start() finished synchronously (returning other than ERR_IO_PENDING), or
235     // delegate's OnServiceEndpointRequestFinished() is called.
236     virtual const std::vector<ServiceEndpoint>& GetEndpointResults() = 0;
237 
238     // Any DNS record aliases, such as CNAME aliases, found as a result of
239     // addresses and HTTPS queries. These can be changed over time while
240     // resolution is still ongoing. See also the comment on
241     // Request::GetDnsAliasResults() for details.
242     virtual const std::set<std::string>& GetDnsAliasResults() = 0;
243 
244     // True if the client of this request can attempt cryptographic handshakes.
245     // If false, the provided service endpoints via GetEndpointResults() are not
246     // finalized to the point to allow completing transactions, and data or
247     // cryptographic handshakes must not be sent. This can be changed over time
248     // while resolution is still ongoing.
249     // TODO(crbug.com/41493696): Consider renaming this to
250     // `IsSvcbResolutionCompleted()` when Chrome supports HTTPS follow-up
251     // queries.
252     virtual bool EndpointsCryptoReady() = 0;
253 
254     // Returns the error info of this request. This can be changed over time
255     // while resolution is still ongoing. In general, should be called only
256     // after resolution completed.
257     virtual ResolveErrorInfo GetResolveErrorInfo() = 0;
258 
259     // Change the priority of this request.
260     virtual void ChangeRequestPriority(RequestPriority priority) = 0;
261   };
262 
263   // Handler for an activation of probes controlled by a HostResolver. Created
264   // by HostResolver::CreateDohProbeRequest().
265   class ProbeRequest {
266    public:
267     // Destruction cancels the request and all probes.
268     virtual ~ProbeRequest() = default;
269 
270     // Activates async running of probes. Always returns ERR_IO_PENDING or an
271     // error from activating probes. No callback as probes will never "complete"
272     // until cancellation.
273     virtual int Start() = 0;
274   };
275 
276   // The options for features::kUseDnsHttpsSvcb experiment. See the comments
277   // in net/base/features.h for more details.
278   struct NET_EXPORT HttpsSvcbOptions {
279     HttpsSvcbOptions();
280     HttpsSvcbOptions(const HttpsSvcbOptions&);
281     HttpsSvcbOptions(HttpsSvcbOptions&&);
282     HttpsSvcbOptions& operator=(const HttpsSvcbOptions&) = default;
283     HttpsSvcbOptions& operator=(HttpsSvcbOptions&&) = default;
284     ~HttpsSvcbOptions();
285 
286     static HttpsSvcbOptions FromDict(const base::Value::Dict& dict);
287     static HttpsSvcbOptions FromFeatures();
288 
289     bool enable = false;
290     base::TimeDelta insecure_extra_time_max;
291     int insecure_extra_time_percent = 0;
292     base::TimeDelta insecure_extra_time_min;
293     base::TimeDelta secure_extra_time_max;
294     int secure_extra_time_percent = 0;
295     base::TimeDelta secure_extra_time_min;
296   };
297 
298   // Parameter-grouping struct for additional optional parameters for creation
299   // of HostResolverManagers and stand-alone HostResolvers.
300   struct NET_EXPORT ManagerOptions {
301     ManagerOptions();
302     ManagerOptions(const ManagerOptions&);
303     ManagerOptions(ManagerOptions&&);
304     ManagerOptions& operator=(const ManagerOptions&) = default;
305     ManagerOptions& operator=(ManagerOptions&&) = default;
306     ~ManagerOptions();
307 
308     // Set |max_concurrent_resolves| to this to select a default level
309     // of concurrency.
310     static const size_t kDefaultParallelism = 0;
311 
312     // How many resolve requests will be allowed to run in parallel.
313     // |kDefaultParallelism| for the resolver to choose a default value.
314     size_t max_concurrent_resolves = kDefaultParallelism;
315 
316     // The maximum number of times to retry for host resolution if using the
317     // system resolver. No effect when the system resolver is not used.
318     // |kDefaultRetryAttempts| for the resolver to choose a default value.
319     size_t max_system_retry_attempts =
320         HostResolverSystemTask::Params::kDefaultRetryAttempts;
321 
322     // Initial setting for whether the insecure portion of the built-in
323     // asynchronous DnsClient is enabled or disabled. See HostResolverManager::
324     // SetInsecureDnsClientEnabled() for details.
325     bool insecure_dns_client_enabled = false;
326 
327     // Initial setting for whether additional DNS types (e.g. HTTPS) may be
328     // queried when using the built-in resolver for insecure DNS.
329     bool additional_types_via_insecure_dns_enabled = true;
330 
331     // Initial configuration overrides for the built-in asynchronous DnsClient.
332     // See HostResolverManager::SetDnsConfigOverrides() for details.
333     DnsConfigOverrides dns_config_overrides;
334 
335     // If set to |false|, when on a WiFi connection, IPv6 will be assumed to be
336     // unreachable without actually checking. See https://crbug.com/696569 for
337     // further context.
338     bool check_ipv6_on_wifi = true;
339 
340     // An experimental options for features::kUseDnsHttpsSvcb
341     // and features::kUseDnsHttpsSvcbAlpn.
342     std::optional<HostResolver::HttpsSvcbOptions> https_svcb_options;
343   };
344 
345   // Factory class. Useful for classes that need to inject and override resolver
346   // creation for tests.
347   class NET_EXPORT Factory {
348    public:
349     virtual ~Factory() = default;
350 
351     // See HostResolver::CreateResolver.
352     virtual std::unique_ptr<HostResolver> CreateResolver(
353         HostResolverManager* manager,
354         std::string_view host_mapping_rules,
355         bool enable_caching);
356 
357     // See HostResolver::CreateStandaloneResolver.
358     virtual std::unique_ptr<HostResolver> CreateStandaloneResolver(
359         NetLog* net_log,
360         const ManagerOptions& options,
361         std::string_view host_mapping_rules,
362         bool enable_caching);
363   };
364 
365   // Parameter-grouping struct for additional optional parameters for
366   // CreateRequest() calls. All fields are optional and have a reasonable
367   // default.
368   struct NET_EXPORT ResolveHostParameters {
369     ResolveHostParameters();
370 
371     // Requested DNS query type. If UNSPECIFIED, the resolver will select a set
372     // of queries automatically. It will select A, AAAA, or both as the address
373     // queries, depending on IPv4/IPv6 settings and reachability. It may also
374     // replace UNSPECIFIED with additional queries, such as HTTPS.
375     DnsQueryType dns_query_type = DnsQueryType::UNSPECIFIED;
376 
377     // The initial net priority for the host resolution request.
378     RequestPriority initial_priority = RequestPriority::DEFAULT_PRIORITY;
379 
380     // The source to use for resolved addresses. Default allows the resolver to
381     // pick an appropriate source. Only affects use of big external sources (eg
382     // calling the system for resolution or using DNS). Even if a source is
383     // specified, results can still come from cache, resolving "localhost" or
384     // IP literals, etc.
385     HostResolverSource source = HostResolverSource::ANY;
386 
387     enum class CacheUsage {
388       // Results may come from the host cache if non-stale.
389       ALLOWED,
390 
391       // Results may come from the host cache even if stale (by expiration or
392       // network changes). In secure dns AUTOMATIC mode, the cache is checked
393       // for both secure and insecure results prior to any secure DNS lookups to
394       // minimize response time.
395       STALE_ALLOWED,
396 
397       // Results will not come from the host cache.
398       DISALLOWED,
399     };
400     CacheUsage cache_usage = CacheUsage::ALLOWED;
401 
402     // If |true|, requests special behavior that the "canonical name" be
403     // requested from the system and be returned as the only entry in
404     // `ResolveHostRequest::GetDnsAliasResults()` results. Setting this
405     // parameter is disallowed for any requests that cannot be resolved using
406     // the system resolver, e.g. non-address requests or requests specifying a
407     // non-`SYSTEM` `source`.
408     //
409     // TODO(crbug.com/40209534): Consider allowing the built-in resolver to
410     // still be used with this parameter. Would then function as a request to
411     // just keep the single final name from the alias chain instead of all
412     // aliases, and also skip the canonicalization unless that canonicalization
413     // is found to be fine for usage.
414     bool include_canonical_name = false;
415 
416     // Hint to the resolver that resolution is only being requested for loopback
417     // hosts.
418     bool loopback_only = false;
419 
420     // Set |true| iff the host resolve request is only being made speculatively
421     // to fill the cache and the result addresses will not be used. The request
422     // will receive special logging/observer treatment, and the result addresses
423     // will always be |std::nullopt|.
424     bool is_speculative = false;
425 
426     // If `true`, resolver may (but is not guaranteed to) take steps to avoid
427     // the name being resolved via LLMNR or mDNS. Useful for requests where it
428     // is not desired to wait for longer timeouts on potential negative results,
429     // as is typically the case for LLMNR or mDNS queries without any results.
430     bool avoid_multicast_resolution = false;
431 
432     // Controls the resolver's Secure DNS behavior for this request.
433     SecureDnsPolicy secure_dns_policy = SecureDnsPolicy::kAllow;
434   };
435 
436   // Handler for an ongoing MDNS listening operation. Created by
437   // HostResolver::CreateMdnsListener().
438   class MdnsListener {
439    public:
440     // Delegate type for result update notifications from MdnsListener. All
441     // methods have a |result_type| field to allow a single delegate to be
442     // passed to multiple MdnsListeners and be used to listen for updates for
443     // multiple types for the same host.
444     class Delegate {
445      public:
446       virtual ~Delegate() = default;
447 
448       virtual void OnAddressResult(MdnsListenerUpdateType update_type,
449                                    DnsQueryType result_type,
450                                    IPEndPoint address) = 0;
451       virtual void OnTextResult(MdnsListenerUpdateType update_type,
452                                 DnsQueryType result_type,
453                                 std::vector<std::string> text_records) = 0;
454       virtual void OnHostnameResult(MdnsListenerUpdateType update_type,
455                                     DnsQueryType result_type,
456                                     HostPortPair host) = 0;
457 
458       // For results which may be valid MDNS but are not handled/parsed by
459       // HostResolver, e.g. pointers to the root domain.
460       virtual void OnUnhandledResult(MdnsListenerUpdateType update_type,
461                                      DnsQueryType result_type) = 0;
462     };
463 
464     // Destruction cancels the listening operation.
465     virtual ~MdnsListener() = default;
466 
467     // Begins the listening operation, invoking |delegate| whenever results are
468     // updated. |delegate| will no longer be called once the listening operation
469     // is cancelled (via destruction of |this|).
470     virtual int Start(Delegate* delegate) = 0;
471   };
472 
473   HostResolver(const HostResolver&) = delete;
474   HostResolver& operator=(const HostResolver&) = delete;
475 
476   // If any completion callbacks are pending when the resolver is destroyed,
477   // the host resolutions are cancelled, and the completion callbacks will not
478   // be called.
479   virtual ~HostResolver();
480 
481   // Cancels any pending requests without calling callbacks, same as
482   // destruction, except also leaves the resolver in a mostly-noop state. Any
483   // future request Start() calls (for requests created before or after
484   // OnShutdown()) will immediately fail with ERR_CONTEXT_SHUT_DOWN.
485   virtual void OnShutdown() = 0;
486 
487   // Creates a request to resolve the given hostname (or IP address literal).
488   // Profiling information for the request is saved to |net_log| if non-NULL.
489   //
490   // Additional parameters may be set using |optional_parameters|. Reasonable
491   // defaults will be used if passed |nullptr|.
492   virtual std::unique_ptr<ResolveHostRequest> CreateRequest(
493       url::SchemeHostPort host,
494       NetworkAnonymizationKey network_anonymization_key,
495       NetLogWithSource net_log,
496       std::optional<ResolveHostParameters> optional_parameters) = 0;
497 
498   // Create requests when scheme is unknown or non-standard.
499   // TODO(crbug.com/40181080): Rename to discourage use when scheme is known.
500   virtual std::unique_ptr<ResolveHostRequest> CreateRequest(
501       const HostPortPair& host,
502       const NetworkAnonymizationKey& network_anonymization_key,
503       const NetLogWithSource& net_log,
504       const std::optional<ResolveHostParameters>& optional_parameters) = 0;
505 
506   // Creates a service endpoint resolution request.
507   virtual std::unique_ptr<ServiceEndpointRequest> CreateServiceEndpointRequest(
508       Host host,
509       NetworkAnonymizationKey network_anonymization_key,
510       NetLogWithSource net_log,
511       ResolveHostParameters parameters) = 0;
512 
513   // Creates a request to probe configured DoH servers to find which can be used
514   // successfully.
515   virtual std::unique_ptr<ProbeRequest> CreateDohProbeRequest();
516 
517   // Create a listener to watch for updates to an MDNS result.
518   virtual std::unique_ptr<MdnsListener> CreateMdnsListener(
519       const HostPortPair& host,
520       DnsQueryType query_type);
521 
522   // Returns the HostResolverCache |this| uses, or NULL if there isn't one.
523   // Used primarily to clear the cache and for getting debug information.
524   virtual HostCache* GetHostCache();
525 
526   // Returns the current DNS configuration |this| is using, as a Value.
527   virtual base::Value::Dict GetDnsConfigAsValue() const;
528 
529   // Set the associated URLRequestContext, generally expected to be called by
530   // URLRequestContextBuilder on passing ownership of |this| to a context. May
531   // only be called once.
532   virtual void SetRequestContext(URLRequestContext* request_context);
533 
534   virtual HostResolverManager* GetManagerForTesting();
535   virtual const URLRequestContext* GetContextForTesting() const;
536   virtual handles::NetworkHandle GetTargetNetworkForTesting() const;
537 
538   // Creates a new HostResolver. |manager| must outlive the returned resolver.
539   //
540   // If |mapping_rules| is non-empty, the mapping rules will be applied to
541   // requests.  See MappedHostResolver for details.
542   static std::unique_ptr<HostResolver> CreateResolver(
543       HostResolverManager* manager,
544       std::string_view host_mapping_rules = "",
545       bool enable_caching = true);
546 
547   // Creates a HostResolver independent of any global HostResolverManager. Only
548   // for tests and standalone tools not part of the browser.
549   //
550   // If |mapping_rules| is non-empty, the mapping rules will be applied to
551   // requests.  See MappedHostResolver for details.
552   static std::unique_ptr<HostResolver> CreateStandaloneResolver(
553       NetLog* net_log,
554       std::optional<ManagerOptions> options = std::nullopt,
555       std::string_view host_mapping_rules = "",
556       bool enable_caching = true);
557   // Same, but explicitly returns the implementing ContextHostResolver. Only
558   // used by tests and by StaleHostResolver in Cronet. No mapping rules can be
559   // applied because doing so requires wrapping the ContextHostResolver.
560   static std::unique_ptr<ContextHostResolver> CreateStandaloneContextResolver(
561       NetLog* net_log,
562       std::optional<ManagerOptions> options = std::nullopt,
563       bool enable_caching = true);
564   // Same, but bind the resolver to `target_network`: all lookups will be
565   // performed exclusively for `target_network`, lookups will fail if
566   // `target_network` disconnects. This can only be used by network-bound
567   // URLRequestContexts.
568   // Due to the current implementation, if `options` is specified, its
569   // DnsConfigOverrides parameter must be empty.
570   // Only implemented for Android starting from Marshmallow.
571   static std::unique_ptr<HostResolver> CreateStandaloneNetworkBoundResolver(
572       NetLog* net_log,
573       handles::NetworkHandle network,
574       std::optional<ManagerOptions> options = std::nullopt,
575       std::string_view host_mapping_rules = "",
576       bool enable_caching = true);
577 
578   // Helpers for interacting with HostCache and ProcResolver.
579   static AddressFamily DnsQueryTypeSetToAddressFamily(
580       DnsQueryTypeSet query_types);
581   static HostResolverFlags ParametersToHostResolverFlags(
582       const ResolveHostParameters& parameters);
583 
584   // Helper for squashing error code to a small set of DNS error codes.
585   static int SquashErrorCode(int error);
586 
587   // Builds an AddressList from the first non-protocol endpoint found in
588   // `endpoints`.
589   //
590   // TODO(crbug.com/40203587): Delete once `AddressList` usage is fully replaced
591   // in `HostResolver` and results.
592   static AddressList EndpointResultToAddressList(
593       base::span<const HostResolverEndpointResult> endpoints,
594       const std::set<std::string>& aliases);
595 
596   // Returns whether there is at least one protocol endpoint in `endpoints`, and
597   // all such endpoints have ECH parameters. This can be used to implement the
598   // guidance in section 3 of RFC9460.
599   template <typename T>
AllProtocolEndpointsHaveEch(base::span<const T> endpoints)600   static bool AllProtocolEndpointsHaveEch(base::span<const T> endpoints)
601     requires HasConnectionEndpointMetadata<T>
602   {
603     bool has_svcb = false;
604     for (const auto& endpoint : endpoints) {
605       if (!endpoint.metadata.supported_protocol_alpns.empty()) {
606         has_svcb = true;
607         if (endpoint.metadata.ech_config_list.empty()) {
608           return false;  // There is a non-ECH SVCB/HTTPS route.
609         }
610       }
611     }
612     // Either there were no SVCB/HTTPS records (should be SVCB-optional), or
613     // there were and all supported ECH (should be SVCB-reliant).
614     return has_svcb;
615   }
616 
617   // Returns true if NAT64 can be used in place of an IPv4 address during host
618   // resolution.
619   static bool MayUseNAT64ForIPv4Literal(HostResolverFlags flags,
620                                         HostResolverSource source,
621                                         const IPAddress& ip_address);
622 
623  protected:
624   HostResolver();
625 
626   // Utility to create a request implementation that always fails with |error|
627   // immediately on start.
628   static std::unique_ptr<ResolveHostRequest> CreateFailingRequest(int error);
629   static std::unique_ptr<ProbeRequest> CreateFailingProbeRequest(int error);
630   static std::unique_ptr<ServiceEndpointRequest>
631   CreateFailingServiceEndpointRequest(int error);
632 };
633 
634 }  // namespace net
635 
636 #endif  // NET_DNS_HOST_RESOLVER_H_
637