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