# Host Resolution

This document is a brief overview of how host resolution works in the Chrome
network stack.

The stack includes two different implementations: the "system" or "platform"
resolver, and the "async" or "built-in" resolver. The higher layers are shared
between the implementations, and the lower layers are implemented separately.

## Shared layers

### Host resolver

The HostResolverImpl is the main interface between DNS and the rest of the
network stack. It checks the HostCache, checks if there is an already running
Job, and schedules a new Job if there isn't one in progress.

Data collected at this layer:
* "Net.DNS.TotalTime" (recommended for DNS experiments)
* "Net.DNS.TotalTimeNotCached"

### Job

The HostResolverImpl::Job represents a single DNS resolution from the network
(or in some cases the OS's DNS cache, which Chrome doesn't know about). It
starts a task depending on which implementation should be used. If a DnsTask
fails, it retries using a ProcTask.

Data collected at this layer:
* "Net.DNS.ResolveSuccessTime" (also by address family)
* "Net.DNS.ResolveFailureTime" (also by address family)
* "Net.DNS.ResolveCategory"
* "Net.DNS.ResolveError.Fast"
* "Net.DNS.ResolveError.Slow"

## System resolver

### Task

The entry point for the system resolver is HostResolverImpl::ProcTask. The task
runs almost entirely on TaskScheduler. Its main implementation is in
SystemHostResolverProc. Other implementations of HostResolverProc can be swapped
in for testing.

Data collected at this layer:
* "Net.DNS.ProcTask.SuccessTime"
* "Net.DNS.ProcTask.FailureTime"
* "Net.OSErrorsForGetaddrinfo*"

### Attempt

Attempts in the system resolver are not a separate class. They're implemented as
separate tasks posted to TaskScheduler.

Data collected at this layer:
* "DNS.AttemptFirstSuccess"
* "DNS.AttemptFirstFailure"
* "DNS.AttemptSuccess"
* "DNS.AttemptFailure"
* "DNS.AttemptDiscarded"
* "DNS.AttemptCancelled"
* "DNS.AttemptSuccessDuration"
* "DNS.AttemptFailDuration"

## Async resolver

### Task

The entry point for the async resolver is HostResolverImpl::DnsTask. DnsTask
starts one DnsTransaction for each lookup needed, which can be one for a single
address family or two when both A and AAAA are needed.

Data collected at this layer:
* "Net.DNS.DnsTask.SuccessTime"
* "Net.DNS.DnsTask.FailureTime"
* "Net.DNS.DnsTask.ErrorBeforeFallback.Fast"
* "Net.DNS.DnsTask.ErrorBeforeFallback.Slow"
* "Net.DNS.DnsTask.Errors"

### Transaction

The main implementation of the async resolver is in the DnsTransaction. Each
transaction represents a single query, which might be tried multiple times or in
different ways.

Data collected at this layer:
* "AsyncDNS.TransactionFailure"
* "AsyncDNS.TransactionSuccess" (and by query type)

### Attempt

Attempts in the async resolver are an explicit layer, implemented by subclasses
of DnsAttempt. In most cases, DnsUDPAttempt is used. DnsTCPAttempt is used
instead when the server requests it. DnsHTTPAttempt is experimental.

Data collected at this layer:
* "AsyncDNS.UDPAttemptSuccess"
* "AsyncDNS.UDPAttemptFail"
* "AsyncDNS.TCPAttemptSuccess"
* "AsyncDNS.TCPAttemptFail"
* "AsyncDNS.AttemptCountSuccess"
* "AsyncDNS.AttemptCountFail"
