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