1# Chrome Host Resolution 2 3Implementation and support of host resolution for the Chrome network stack. 4Includes client implementations of host resolution protocols (DNS and mDNS), 5host resolution caching, support for dealing with system host resolution 6(including reading HOSTS files and tracking system network settings related to 7host resolution), and various related utilities. 8 9*** promo 10Note: "DNS" in this directory (including the directory name) is often used as 11shorthand for all host resolution, not just that using the Domain Name System. 12This document attempts to use "DNS" only to refer to the actual Domain Name 13System, except when referring to strings or paths that contain other usage of 14"DNS". 15*** 16 17[TOC] 18 19## Usage 20 21### From outside the network service 22 23Most interaction with host resolution should be through the [network service](/services/network/README.md) 24[`network::HostResolver`](/services/network/public/mojom/host_resolver.mojom), 25retrieved from [`network::NetworkContext`](/services/network/public/mojom/network_context.mojom) 26using `network::NetworkContext::CreateHostResolver()`. 27 28Host resolution is requested using `network::HostResolver::ResolveHost()`. There 29is also a shortcut using `network::NetworkContext::ResolveHost()` when a 30separate passable object is not needed. 31 32Some general utilities are also available in [`/net/dns/public/`](/net/dns/public/) 33that are intended for use by any code, inside or outside the network service. 34Otherwise, code outside the network service should never interact directly with 35the code in [`/net/dns/`](/net/dns/). 36 37### From inside the network service 38 39Inside the network service or inside the Chrome networking stack, host 40resolution goes through [`net::HostResolver`](/net/dns/host_resolver.h), 41retrieved from [`net::URLRequestContext`](/net/url_request/url_request_context.h). 42 43### Stand-alone tools 44 45Tests and stand-alone tools not part of the browser may interact with host 46resolution directly by creating their own HostResolvers using 47`net::HostResolver::CreateStandaloneResolver()`. 48 49## Test support 50 51### MockHostResolver 52 53[`net::MockHostResolver`](/net/dns/mock_host_resolver.h) 54 55Tests with the ability to inject and replace the used `net::HostResolver` should 56replace it with a `net::MockHostResolver`, allowing rule-based results. 57`net::MockCachingHostResolver` is the same except it includes basic support for 58the caching functionality normally done by prod `net::HostResolver`s. 59 60Some tests may also find `net::HangingHostResolver` useful. It will begin host 61resolution requests, but never complete them until cancellation. 62 63### TestHostResolver 64 65[`content::TestHostResolver`](/content/public/test/test_host_resolver.h) 66 67Used by most browser tests (via [`content::BrowserTestBase`](/content/public/test/browser_test_base.h)), 68`content::TestHostResolver` installs itself on creation globally into all host 69resolvers in the process. By default, only allows resolution of the local host 70and returns `net::ERR_NAME_NOT_RESOLVED` for other hostnames. Allows setting rules 71for other results using a [net::RuleBasedHostResolverProc](/net/dns/mock_host_resolver.h). 72 73*** note 74**Warning:** `content::TestHostResolver` only replaces host address resolution 75to the system and then artificially uses such system resolution for many 76requests that would normally be handled differently (e.g. using the built-in DNS 77client). This means a significant amount of normal prod host resolution logic 78will be bypassed in tests using `content::TestHostResolver`. 79*** 80 81### Request remapping 82 83Most prod logic for creating HostResolvers will check if any global remappings 84have been requested. In the browser, this is requested using the 85["host-resolver-rules"](/services/network/public/cpp/network_switches.h) 86commandline flag. 87 88See [`net::HostMappingRules`](/net/base/host_mapping_rules.h) for details on the 89format of the rules string. Allows remapping any request hostname to another 90hostname, an IP address, or a NOTFOUND error. 91 92## Implementation 93 94### HostResolver 95 96[`net::HostResolver`](/net/dns/host_resolver.h) 97 98The main interface for requesting host resolution within the network stack or 99network service. In prod, generally owned, and retrieved as-needed from 100[`net::URLRequestContext`](/net/url_request/url_request_context.h)s. Created 101using `net::HostResolver::CreateResolver()` or 102`net::HostResolver::CreateStandaloneResolver()`. 103 104Various implementations are used in prod. 105 106#### ContextHostResolver 107 108[`net::ContextHostResolver`](/net/dns/context_host_resolver.h) 109 110The main prod implementation of `net::HostResolver`. Expected to be owned 1:1 by 111a single `net::URLRequestContext`, the `net::ContextHostResolver` owns or keeps 112references to per-URLRequestContext properties used for host resolution, 113including an owned [`net::HostCache`](/net/dns/host_cache.h). 114 115On resolution, calls into an underlying `net::HostResolverManager` with the per- 116context properties. 117 118On destruction, silently cancels all host resolution requests made through the 119`net::ContextHostResolver` instance. This prevents the underlying 120`net::HostResolverManager` from continuing to reference the per-context 121properties that may be destroyed on destruction of the `net::URLRequestContext` 122or `net::ContextHostResolver`. 123 124#### MappedHostResolver 125 126[`net::MappedHostResolver`](/net/dns/mapped_host_resolver.h) 127 128A wrapping implementation around another `net::HostResolver`. Maintains request 129remapping rules to remap request hostnames to other hostnames or IP addresses. 130 131Used to implement the ["host-resolver-rules"](/services/network/public/cpp/network_switches.h) 132commandline flag. 133 134#### StaleHostResolver 135 136[`cronet::StaleHostResolver`](/components/cronet/stale_host_resolver.h) 137 138A wrapping implementation around another `net::HostResolver`. Returns stale 139(expired or invalidated by network changes) data from the `net::HostCache` when 140non-stale results take longer than a configurable timeout. Reduces host 141resolution latency at the expense of accuracy. 142 143Only used and created by [Cronet](/components/cronet/README.md). 144 145### HostResolverManager 146 147[`net::HostResolverManager`](/net/dns/host_resolver_manager.h) 148 149Scheduler and controller of host resolution requests. Contains the logic for 150immediate host resolution from fast local sources (e.g. querying 151`net::HostCache`s, IP address literals, etc). Throttles, schedules, and merges 152asynchronous jobs for resolution from slower network sources. 153 154On destruction, silently cancels all in-progress host resolution requests. 155 156In prod, a single shared `net::HostResolverManager` is generally used for the 157entire browser. The shared manager is owned and configured by the 158[`network::NetworkService`](/services/network/network_service.h). 159 160#### Request 161 162`net::HostResolverManager::RequestImpl` 163 164Implementation of [`net::HostResolver::ResolveHostRequest`](/net/dns/host_resolver.h) 165and overall representation of a single request for resolution from a 166`net::HostResolverManager`. The `RequestImpl` object itself primarily acts only 167as a container of parameters and results for the request, leaving the actual 168logic to the `net::HostResolverManager` itself. 169 170Data collected at this layer: 171 172* "Net.DNS.Request.TotalTime" (recommended for experiments) 173* "Net.DNS.Request.TotalTimeAsync" 174 175#### Job 176 177`net::HostResolverManager::Job` 178 179Representation of an asynchronous job for resolution from slower network 180sources. Contains the logic to determine and query the appropriate source for 181host resolution results with retry and fallback support to other sources. On 182completion adds results to relevant `net::HostCache`s and invokes request 183callbacks. 184 185Multiple requests can be merged into a single Job if compatible. This includes 186merging newly-started Jobs with already-running Jobs. 187 188`net::HostResolverManager` schedules and throttles running 189`net::HostResolverManager::Job`s using a [`net::PrioritizedDispatcher`](/net/base/prioritized_dispatcher.h). 190The throttling is important to avoid overworking network sources, especially 191poorly designed home routers that may crash on only a small number of concurrent 192DNS resolves. 193 194Data collected at this layer: 195 196* "Net.DNS.ResolveSuccessTime" 197* "Net.DNS.ResolveFailureTime" 198* "Net.DNS.ResolveCategory" 199* "Net.DNS.ResolveError.Fast" 200* "Net.DNS.ResolveError.Slow" 201* "Net.DNS.SecureDnsMode.[Off/Automatic/Secure].ResolveTime" 202 203### Host resolution sources 204 205Various sources are used to query host resolution. The sources to be used by a 206`net::HostResolverManager::Job` are determined in advance of running the Job by 207`net::HostResolverManager::CreateTaskSequence()`, which outputs a list of 208`net::HostResolverManager::TaskType` specifying the order of sources to attempt. 209By default, this will use internal logic to decide the source to use and will 210often allow fallback to additional sources. 211 212The sources chosen by default are also affected by the Secure DNS mode, by 213default determined from 214[`net::DnsConfig::secure_dns_mode`](/net/dns/dns_config.h) but overridable for 215individual requests using 216`net::HostResolver::ResolveHostParameters::secure_dns_mode_override`. 217 218Specific sources for a request can be 219specified using `net::HostResolver::ResolveHostParameters::source` and 220[`net::HostResolverSource`](/net/dns/host_resolver_source.h). 221 222The Job will then use \*Task objects that implement the behavior specific to the 223particular resolution sources. 224 225#### SYSTEM 226 227`net::HostResolverSource::SYSTEM` 228`net::HostResolverManager::TaskType::SYSTEM` 229 230Implemented by: `net::HostResolverSystemTask` 231 232Usually called the "system resolver" or sometimes the "proc resolver" (because 233it was historically always implemented using net::HostResolverProc). Results 234are queried from the system or OS using the `getaddrinfo()` OS API call. This 235source is only capable of address (A and AAAA) resolves but will also query for 236canonname info if the request includes the `HOST_RESOLVER_CANONNAME` flag. The 237system will query from its own internal cache, HOSTS files, DNS, and sometimes 238mDNS, depending on the capabilities of the system. 239 240When host resolution requests do not specify a source, the system resolver will 241always be used for **address resolves** when **any** of the following are true: 242 243* Requests with the `HOST_RESOLVER_CANONNAME` flag 244* For hostnames ending in ".local" 245* When the Secure DNS mode is `net::SecureDnsMode::OFF` and 246 `net::HostResolverSource::DNS` is not enabled via 247 `net::HostResolverManager::SetInsecureDnsClientEnabled(true)` 248* When a system DNS configuration could not be determined 249 250Secure DNS requests cannot be made using the system resolver. 251 252`net::HostResolverSystemTask`'s behavior can be overridden by an asynchronous 253global override (e.g. in case resolution needs to be brokered out of the current 254process for sandboxing reasons). Otherwise, it posts a blocking task to a 255[`base::ThreadPool`](/base/task/thread_pool.h) to make blocking resolution 256requests in-process. 257On a timeout, additional attempts are made, but previous attempts are not 258cancelled as there is no cancellation mechanism for `getaddrinfo()`. The first 259attempt to complete is used and any other attempt completions are ignored. 260 261In prod, the blocking task runner always calls `SystemHostResolverCall()`, which 262makes the actual call to `getaddrinfo()` using the 263[`net::AddressInfo`](/net/dns/address_info.h) helper. In tests, the blocking 264task runner may use a test implementation of 265[`net::HostResolverProc`](/net/dns/host_resolver_proc.h), which itself can be 266chained. 267 268Data collected specifically for this source: 269 270* "Net.DNS.SystemTask.SuccessTime" 271* "Net.DNS.SystemTask.FailureTime" 272 273#### DNS 274 275`net::HostResolverSource::DNS` 276`net::HostResolverManager::TaskType::DNS` 277`net::HostResolverManager::TaskType::SECURE_DNS` 278 279Implemented by: `net::HostResolverManager::DnsTask` 280 281Usually called the "built-in resolver" or the "async resolver". Results are 282queried from DNS using [`net::DnsClient`](/net/dns/dns_client.h), a Chrome 283network stack implementation of a DNS "stub resolver" or "DNS client". 284 285When host resolution requests do not specify a source, the built-in resolver 286will be used when **all** of the following are true: 287 288* DnsClient is enabled for insecure requests enabled via 289 `net::HostResolverManager::SetInsecureDnsClientEnabled(true)` or 290 the Secure DNS mode is not `net::SecureDnsMode::OFF`. 291* The system DNS configuration could be determined successfully 292* The request hostname does not end in ".local" 293* The request is not an address query with the `HOST_RESOLVER_CANONNAME` flag 294 295The `net::HostResolverManager::DnsTask` will create and run a 296[`net::DnsTransaction`](/net/dns/dns_transaction.h) for each DNS name/type pair 297to be queried. The task will then process successful results from the returned 298[`net::DnsResponse`](/net/dns/dns_response.h). 299 300When a request requires both A and AAAA results, they are handled via two 301separate `net::DnsTransaction`s and the `net::HostResolverManager::DnsTask` will 302request a second slots from the `net::PrioritizedDispatcher` used by 303`net::HostResolverManager`. The A transaction is started immediately on starting 304the `net::HostResolverManager::DnsTask`, and the AAAA transaction is started 305once a second dispatcher slot can be obtained. 306 307Each `net::DnsTransaction` internally makes a series of `net::DnsAttempt`s, each 308representing an individual DNS request. A single `net::DnsTransaction` can run 309many `net::DnsAttempt`s due to retry logic, fallback between multiple configured 310DNS servers, and name permutation due to configured search suffixes. 311 312Data collected specifically for this source (more internally to 313`net::DnsTransaction` implementation not listed here): 314 315* "Net.DNS.DnsTask.SuccessTime" 316* "Net.DNS.InsecureDnsTask.FailureTime" 317* "Net.DNS.JobQueueTime.PerTransaction" 318* "Net.DNS.JobQueueTime.Failure" 319* "Net.DNS.JobQueueTime.Success" 320* "Net.DNS.SecureDnsTask.DnsModeSecure.FailureTime" 321* "Net.DNS.SecureDnsTask.DnsModeAutomatic.FailureTime" 322 323#### MULTICAST_DNS 324 325`net::HostResolverSource::MULTICAST_DNS` 326`net::HostResolverManager::TaskType::MDNS` 327 328Implemented by [`net::HostResolverMdnsTask`](/net/dns/host_resolver_mdns_task.h) 329 330Results are queried from mDNS using [`net::MDnsClient`](/net/dns/mdns_client.h). 331 332When host resolution requests do not specify a source, mDNS is only used for 333non-address requests when the request hostname ends in ".local". 334 335mDNS requests start with [`net::HostResolverMdnsTask`](/net/dns/host_resolver_mdns_task.h), 336which will create and run a [`net::MDnsTransaction`](/net/dns/mdns_client.h) for 337each query type needed. 338 339Unlike `net::HostResolverManager::DnsTask`, each `net::HostResolverMdnsTask` 340will only ever use a single dispatcher slot, even when both A and AAAA types are 341queried concurrently. 342 343`net::MDnsClient` maintains its own cache, separate from the main 344[`net::HostCache`](/net/dns/host_cache.h) owned by the 345[`net::ContextHostResolver`](/net/dns/context_host_resolver.h). As such, mDNS 346results are never cached in the `net::HostCache`. 347 348### IPv6 and connectivity 349 350Some poorly written DNS servers, especially on home routers, are unaware of the 351existence of IPv6 and will result in bad performance or even crash when sent 352AAAA DNS queries. 353 354To avoid such issues, `net::HostResolverManager` heuristically detects IPv4-only 355networks by attempting a UDP connection to `2001:4860:4860::8888` (the IPv6 356address for Google Public DNS). If the connection fails, Chrome will convert 357host resolution requests for `net::DnsQueryType::UNSPECIFIED` to 358`net::DnsQueryType::A`. This generally results in disallowing AAAA requests. 359 360Exceptions when AAAA requests are always allowed despite a failed connectivity 361check: 362 363* The host resolution request explicitly requests `net::DnsQueryType::AAAA` 364* IP address literal resolution including when a hostname request has been 365 rewritten to an IP address literal using `net::MappedHostResolver` 366* Results read from HOSTS files where there is no non-loopback IPv4 result. Note 367 that this exception only applies when Chrome does the read from HOSTS. When 368 Chrome's built-in DNS client is not used, HOSTS is only read by the system 369 where Chrome would only request A results to avoid the system making AAAA DNS 370 queries. 371 372The heuristic for detecting IPv4-only networks is not perfect. E.g., it fails 373and disallows AAAA requests in private (no global internet access including to 374Google Public DNS) IPv6-only networks, which could then break most Chrome usage 375on the network because, being an IPv6-only network, AAAA results are necessary. 376 377Workarounds to allow Chrome to attempt to load IPv6 endpoints when the 378connectivity check fails: 379 380* Starting Chrome with 381 `--host-resolver-rules="MAP the.hostname.com [dead::beef]"` where 382 `the.hostname.com` is the hostname to allow resolving and `dead::beef` is the 383 IPv6 address to resolve it to. `net::MappedHostResolver` acts at a level 384 before IPv6 connectivity checks, and if a hostname is remapped to an IP 385 literal, connectivity checks do not apply. 386* Add entries for the hostnames to resolve to the HOSTS file with just IPv6 387 results. Only works with the built-in DNS client is used. 388* Add a network route to `2001:4860:4860::8888`. Doesn't have to actually be 389 functional (could just drop requests to it). As long as Chrome can connect a 390 UDP socket to the address, it will pass the heuristic checking 391 IPv6-connectivity. 392