Home | History | Annotate | Download | only in dns
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/dns/host_resolver_impl.h"
      6 
      7 #if defined(OS_WIN)
      8 #include <Winsock2.h>
      9 #elif defined(OS_POSIX)
     10 #include <netdb.h>
     11 #endif
     12 
     13 #include <cmath>
     14 #include <utility>
     15 #include <vector>
     16 
     17 #include "base/basictypes.h"
     18 #include "base/bind.h"
     19 #include "base/bind_helpers.h"
     20 #include "base/callback.h"
     21 #include "base/compiler_specific.h"
     22 #include "base/debug/debugger.h"
     23 #include "base/debug/stack_trace.h"
     24 #include "base/message_loop/message_loop_proxy.h"
     25 #include "base/metrics/field_trial.h"
     26 #include "base/metrics/histogram.h"
     27 #include "base/stl_util.h"
     28 #include "base/strings/string_util.h"
     29 #include "base/strings/utf_string_conversions.h"
     30 #include "base/threading/worker_pool.h"
     31 #include "base/time/time.h"
     32 #include "base/values.h"
     33 #include "net/base/address_family.h"
     34 #include "net/base/address_list.h"
     35 #include "net/base/dns_reloader.h"
     36 #include "net/base/dns_util.h"
     37 #include "net/base/host_port_pair.h"
     38 #include "net/base/net_errors.h"
     39 #include "net/base/net_log.h"
     40 #include "net/base/net_util.h"
     41 #include "net/dns/address_sorter.h"
     42 #include "net/dns/dns_client.h"
     43 #include "net/dns/dns_config_service.h"
     44 #include "net/dns/dns_protocol.h"
     45 #include "net/dns/dns_response.h"
     46 #include "net/dns/dns_transaction.h"
     47 #include "net/dns/host_resolver_proc.h"
     48 #include "net/socket/client_socket_factory.h"
     49 #include "net/udp/datagram_client_socket.h"
     50 
     51 #if defined(OS_WIN)
     52 #include "net/base/winsock_init.h"
     53 #endif
     54 
     55 namespace net {
     56 
     57 namespace {
     58 
     59 // Limit the size of hostnames that will be resolved to combat issues in
     60 // some platform's resolvers.
     61 const size_t kMaxHostLength = 4096;
     62 
     63 // Default TTL for successful resolutions with ProcTask.
     64 const unsigned kCacheEntryTTLSeconds = 60;
     65 
     66 // Default TTL for unsuccessful resolutions with ProcTask.
     67 const unsigned kNegativeCacheEntryTTLSeconds = 0;
     68 
     69 // Minimum TTL for successful resolutions with DnsTask.
     70 const unsigned kMinimumTTLSeconds = kCacheEntryTTLSeconds;
     71 
     72 // Number of consecutive failures of DnsTask (with successful fallback) before
     73 // the DnsClient is disabled until the next DNS change.
     74 const unsigned kMaximumDnsFailures = 16;
     75 
     76 // We use a separate histogram name for each platform to facilitate the
     77 // display of error codes by their symbolic name (since each platform has
     78 // different mappings).
     79 const char kOSErrorsForGetAddrinfoHistogramName[] =
     80 #if defined(OS_WIN)
     81     "Net.OSErrorsForGetAddrinfo_Win";
     82 #elif defined(OS_MACOSX)
     83     "Net.OSErrorsForGetAddrinfo_Mac";
     84 #elif defined(OS_LINUX)
     85     "Net.OSErrorsForGetAddrinfo_Linux";
     86 #else
     87     "Net.OSErrorsForGetAddrinfo";
     88 #endif
     89 
     90 // Gets a list of the likely error codes that getaddrinfo() can return
     91 // (non-exhaustive). These are the error codes that we will track via
     92 // a histogram.
     93 std::vector<int> GetAllGetAddrinfoOSErrors() {
     94   int os_errors[] = {
     95 #if defined(OS_POSIX)
     96 #if !defined(OS_FREEBSD)
     97 #if !defined(OS_ANDROID)
     98     // EAI_ADDRFAMILY has been declared obsolete in Android's and
     99     // FreeBSD's netdb.h.
    100     EAI_ADDRFAMILY,
    101 #endif
    102     // EAI_NODATA has been declared obsolete in FreeBSD's netdb.h.
    103     EAI_NODATA,
    104 #endif
    105     EAI_AGAIN,
    106     EAI_BADFLAGS,
    107     EAI_FAIL,
    108     EAI_FAMILY,
    109     EAI_MEMORY,
    110     EAI_NONAME,
    111     EAI_SERVICE,
    112     EAI_SOCKTYPE,
    113     EAI_SYSTEM,
    114 #elif defined(OS_WIN)
    115     // See: http://msdn.microsoft.com/en-us/library/ms738520(VS.85).aspx
    116     WSA_NOT_ENOUGH_MEMORY,
    117     WSAEAFNOSUPPORT,
    118     WSAEINVAL,
    119     WSAESOCKTNOSUPPORT,
    120     WSAHOST_NOT_FOUND,
    121     WSANO_DATA,
    122     WSANO_RECOVERY,
    123     WSANOTINITIALISED,
    124     WSATRY_AGAIN,
    125     WSATYPE_NOT_FOUND,
    126     // The following are not in doc, but might be to appearing in results :-(.
    127     WSA_INVALID_HANDLE,
    128 #endif
    129   };
    130 
    131   // Ensure all errors are positive, as histogram only tracks positive values.
    132   for (size_t i = 0; i < arraysize(os_errors); ++i) {
    133     os_errors[i] = std::abs(os_errors[i]);
    134   }
    135 
    136   return base::CustomHistogram::ArrayToCustomRanges(os_errors,
    137                                                     arraysize(os_errors));
    138 }
    139 
    140 enum DnsResolveStatus {
    141   RESOLVE_STATUS_DNS_SUCCESS = 0,
    142   RESOLVE_STATUS_PROC_SUCCESS,
    143   RESOLVE_STATUS_FAIL,
    144   RESOLVE_STATUS_SUSPECT_NETBIOS,
    145   RESOLVE_STATUS_MAX
    146 };
    147 
    148 void UmaAsyncDnsResolveStatus(DnsResolveStatus result) {
    149   UMA_HISTOGRAM_ENUMERATION("AsyncDNS.ResolveStatus",
    150                             result,
    151                             RESOLVE_STATUS_MAX);
    152 }
    153 
    154 bool ResemblesNetBIOSName(const std::string& hostname) {
    155   return (hostname.size() < 16) && (hostname.find('.') == std::string::npos);
    156 }
    157 
    158 // True if |hostname| ends with either ".local" or ".local.".
    159 bool ResemblesMulticastDNSName(const std::string& hostname) {
    160   DCHECK(!hostname.empty());
    161   const char kSuffix[] = ".local.";
    162   const size_t kSuffixLen = sizeof(kSuffix) - 1;
    163   const size_t kSuffixLenTrimmed = kSuffixLen - 1;
    164   if (hostname[hostname.size() - 1] == '.') {
    165     return hostname.size() > kSuffixLen &&
    166         !hostname.compare(hostname.size() - kSuffixLen, kSuffixLen, kSuffix);
    167   }
    168   return hostname.size() > kSuffixLenTrimmed &&
    169       !hostname.compare(hostname.size() - kSuffixLenTrimmed, kSuffixLenTrimmed,
    170                         kSuffix, kSuffixLenTrimmed);
    171 }
    172 
    173 // Attempts to connect a UDP socket to |dest|:53.
    174 bool IsGloballyReachable(const IPAddressNumber& dest,
    175                          const BoundNetLog& net_log) {
    176   scoped_ptr<DatagramClientSocket> socket(
    177       ClientSocketFactory::GetDefaultFactory()->CreateDatagramClientSocket(
    178           DatagramSocket::DEFAULT_BIND,
    179           RandIntCallback(),
    180           net_log.net_log(),
    181           net_log.source()));
    182   int rv = socket->Connect(IPEndPoint(dest, 53));
    183   if (rv != OK)
    184     return false;
    185   IPEndPoint endpoint;
    186   rv = socket->GetLocalAddress(&endpoint);
    187   if (rv != OK)
    188     return false;
    189   DCHECK(endpoint.GetFamily() == ADDRESS_FAMILY_IPV6);
    190   const IPAddressNumber& address = endpoint.address();
    191   bool is_link_local = (address[0] == 0xFE) && ((address[1] & 0xC0) == 0x80);
    192   if (is_link_local)
    193     return false;
    194   const uint8 kTeredoPrefix[] = { 0x20, 0x01, 0, 0 };
    195   bool is_teredo = std::equal(kTeredoPrefix,
    196                               kTeredoPrefix + arraysize(kTeredoPrefix),
    197                               address.begin());
    198   if (is_teredo)
    199     return false;
    200   return true;
    201 }
    202 
    203 // Provide a common macro to simplify code and readability. We must use a
    204 // macro as the underlying HISTOGRAM macro creates static variables.
    205 #define DNS_HISTOGRAM(name, time) UMA_HISTOGRAM_CUSTOM_TIMES(name, time, \
    206     base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromHours(1), 100)
    207 
    208 // A macro to simplify code and readability.
    209 #define DNS_HISTOGRAM_BY_PRIORITY(basename, priority, time) \
    210   do { \
    211     switch (priority) { \
    212       case HIGHEST: DNS_HISTOGRAM(basename "_HIGHEST", time); break; \
    213       case MEDIUM: DNS_HISTOGRAM(basename "_MEDIUM", time); break; \
    214       case LOW: DNS_HISTOGRAM(basename "_LOW", time); break; \
    215       case LOWEST: DNS_HISTOGRAM(basename "_LOWEST", time); break; \
    216       case IDLE: DNS_HISTOGRAM(basename "_IDLE", time); break; \
    217       default: NOTREACHED(); break; \
    218     } \
    219     DNS_HISTOGRAM(basename, time); \
    220   } while (0)
    221 
    222 // Record time from Request creation until a valid DNS response.
    223 void RecordTotalTime(bool had_dns_config,
    224                      bool speculative,
    225                      base::TimeDelta duration) {
    226   if (had_dns_config) {
    227     if (speculative) {
    228       DNS_HISTOGRAM("AsyncDNS.TotalTime_speculative", duration);
    229     } else {
    230       DNS_HISTOGRAM("AsyncDNS.TotalTime", duration);
    231     }
    232   } else {
    233     if (speculative) {
    234       DNS_HISTOGRAM("DNS.TotalTime_speculative", duration);
    235     } else {
    236       DNS_HISTOGRAM("DNS.TotalTime", duration);
    237     }
    238   }
    239 }
    240 
    241 void RecordTTL(base::TimeDelta ttl) {
    242   UMA_HISTOGRAM_CUSTOM_TIMES("AsyncDNS.TTL", ttl,
    243                              base::TimeDelta::FromSeconds(1),
    244                              base::TimeDelta::FromDays(1), 100);
    245 }
    246 
    247 bool ConfigureAsyncDnsNoFallbackFieldTrial() {
    248   const bool kDefault = false;
    249 
    250   // Configure the AsyncDns field trial as follows:
    251   // groups AsyncDnsNoFallbackA and AsyncDnsNoFallbackB: return true,
    252   // groups AsyncDnsA and AsyncDnsB: return false,
    253   // groups SystemDnsA and SystemDnsB: return false,
    254   // otherwise (trial absent): return default.
    255   std::string group_name = base::FieldTrialList::FindFullName("AsyncDns");
    256   if (!group_name.empty())
    257     return StartsWithASCII(group_name, "AsyncDnsNoFallback", false);
    258   return kDefault;
    259 }
    260 
    261 //-----------------------------------------------------------------------------
    262 
    263 AddressList EnsurePortOnAddressList(const AddressList& list, uint16 port) {
    264   if (list.empty() || list.front().port() == port)
    265     return list;
    266   return AddressList::CopyWithPort(list, port);
    267 }
    268 
    269 // Returns true if |addresses| contains only IPv4 loopback addresses.
    270 bool IsAllIPv4Loopback(const AddressList& addresses) {
    271   for (unsigned i = 0; i < addresses.size(); ++i) {
    272     const IPAddressNumber& address = addresses[i].address();
    273     switch (addresses[i].GetFamily()) {
    274       case ADDRESS_FAMILY_IPV4:
    275         if (address[0] != 127)
    276           return false;
    277         break;
    278       case ADDRESS_FAMILY_IPV6:
    279         return false;
    280       default:
    281         NOTREACHED();
    282         return false;
    283     }
    284   }
    285   return true;
    286 }
    287 
    288 // Creates NetLog parameters when the resolve failed.
    289 base::Value* NetLogProcTaskFailedCallback(uint32 attempt_number,
    290                                           int net_error,
    291                                           int os_error,
    292                                           NetLog::LogLevel /* log_level */) {
    293   base::DictionaryValue* dict = new base::DictionaryValue();
    294   if (attempt_number)
    295     dict->SetInteger("attempt_number", attempt_number);
    296 
    297   dict->SetInteger("net_error", net_error);
    298 
    299   if (os_error) {
    300     dict->SetInteger("os_error", os_error);
    301 #if defined(OS_POSIX)
    302     dict->SetString("os_error_string", gai_strerror(os_error));
    303 #elif defined(OS_WIN)
    304     // Map the error code to a human-readable string.
    305     LPWSTR error_string = NULL;
    306     int size = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
    307                              FORMAT_MESSAGE_FROM_SYSTEM,
    308                              0,  // Use the internal message table.
    309                              os_error,
    310                              0,  // Use default language.
    311                              (LPWSTR)&error_string,
    312                              0,  // Buffer size.
    313                              0);  // Arguments (unused).
    314     dict->SetString("os_error_string", WideToUTF8(error_string));
    315     LocalFree(error_string);
    316 #endif
    317   }
    318 
    319   return dict;
    320 }
    321 
    322 // Creates NetLog parameters when the DnsTask failed.
    323 base::Value* NetLogDnsTaskFailedCallback(int net_error,
    324                                          int dns_error,
    325                                          NetLog::LogLevel /* log_level */) {
    326   base::DictionaryValue* dict = new base::DictionaryValue();
    327   dict->SetInteger("net_error", net_error);
    328   if (dns_error)
    329     dict->SetInteger("dns_error", dns_error);
    330   return dict;
    331 };
    332 
    333 // Creates NetLog parameters containing the information in a RequestInfo object,
    334 // along with the associated NetLog::Source.
    335 base::Value* NetLogRequestInfoCallback(const NetLog::Source& source,
    336                                        const HostResolver::RequestInfo* info,
    337                                        NetLog::LogLevel /* log_level */) {
    338   base::DictionaryValue* dict = new base::DictionaryValue();
    339   source.AddToEventParameters(dict);
    340 
    341   dict->SetString("host", info->host_port_pair().ToString());
    342   dict->SetInteger("address_family",
    343                    static_cast<int>(info->address_family()));
    344   dict->SetBoolean("allow_cached_response", info->allow_cached_response());
    345   dict->SetBoolean("is_speculative", info->is_speculative());
    346   dict->SetInteger("priority", info->priority());
    347   return dict;
    348 }
    349 
    350 // Creates NetLog parameters for the creation of a HostResolverImpl::Job.
    351 base::Value* NetLogJobCreationCallback(const NetLog::Source& source,
    352                                        const std::string* host,
    353                                        NetLog::LogLevel /* log_level */) {
    354   base::DictionaryValue* dict = new base::DictionaryValue();
    355   source.AddToEventParameters(dict);
    356   dict->SetString("host", *host);
    357   return dict;
    358 }
    359 
    360 // Creates NetLog parameters for HOST_RESOLVER_IMPL_JOB_ATTACH/DETACH events.
    361 base::Value* NetLogJobAttachCallback(const NetLog::Source& source,
    362                                      RequestPriority priority,
    363                                      NetLog::LogLevel /* log_level */) {
    364   base::DictionaryValue* dict = new base::DictionaryValue();
    365   source.AddToEventParameters(dict);
    366   dict->SetInteger("priority", priority);
    367   return dict;
    368 }
    369 
    370 // Creates NetLog parameters for the DNS_CONFIG_CHANGED event.
    371 base::Value* NetLogDnsConfigCallback(const DnsConfig* config,
    372                                      NetLog::LogLevel /* log_level */) {
    373   return config->ToValue();
    374 }
    375 
    376 // The logging routines are defined here because some requests are resolved
    377 // without a Request object.
    378 
    379 // Logs when a request has just been started.
    380 void LogStartRequest(const BoundNetLog& source_net_log,
    381                      const BoundNetLog& request_net_log,
    382                      const HostResolver::RequestInfo& info) {
    383   source_net_log.BeginEvent(
    384       NetLog::TYPE_HOST_RESOLVER_IMPL,
    385       request_net_log.source().ToEventParametersCallback());
    386 
    387   request_net_log.BeginEvent(
    388       NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST,
    389       base::Bind(&NetLogRequestInfoCallback, source_net_log.source(), &info));
    390 }
    391 
    392 // Logs when a request has just completed (before its callback is run).
    393 void LogFinishRequest(const BoundNetLog& source_net_log,
    394                       const BoundNetLog& request_net_log,
    395                       const HostResolver::RequestInfo& info,
    396                       int net_error) {
    397   request_net_log.EndEventWithNetErrorCode(
    398       NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, net_error);
    399   source_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL);
    400 }
    401 
    402 // Logs when a request has been cancelled.
    403 void LogCancelRequest(const BoundNetLog& source_net_log,
    404                       const BoundNetLog& request_net_log,
    405                       const HostResolverImpl::RequestInfo& info) {
    406   request_net_log.AddEvent(NetLog::TYPE_CANCELLED);
    407   request_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST);
    408   source_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL);
    409 }
    410 
    411 //-----------------------------------------------------------------------------
    412 
    413 // Keeps track of the highest priority.
    414 class PriorityTracker {
    415  public:
    416   explicit PriorityTracker(RequestPriority initial_priority)
    417       : highest_priority_(initial_priority), total_count_(0) {
    418     memset(counts_, 0, sizeof(counts_));
    419   }
    420 
    421   RequestPriority highest_priority() const {
    422     return highest_priority_;
    423   }
    424 
    425   size_t total_count() const {
    426     return total_count_;
    427   }
    428 
    429   void Add(RequestPriority req_priority) {
    430     ++total_count_;
    431     ++counts_[req_priority];
    432     if (highest_priority_ < req_priority)
    433       highest_priority_ = req_priority;
    434   }
    435 
    436   void Remove(RequestPriority req_priority) {
    437     DCHECK_GT(total_count_, 0u);
    438     DCHECK_GT(counts_[req_priority], 0u);
    439     --total_count_;
    440     --counts_[req_priority];
    441     size_t i;
    442     for (i = highest_priority_; i > MINIMUM_PRIORITY && !counts_[i]; --i);
    443     highest_priority_ = static_cast<RequestPriority>(i);
    444 
    445     // In absence of requests, default to MINIMUM_PRIORITY.
    446     if (total_count_ == 0)
    447       DCHECK_EQ(MINIMUM_PRIORITY, highest_priority_);
    448   }
    449 
    450  private:
    451   RequestPriority highest_priority_;
    452   size_t total_count_;
    453   size_t counts_[NUM_PRIORITIES];
    454 };
    455 
    456 }  // namespace
    457 
    458 //-----------------------------------------------------------------------------
    459 
    460 // Holds the data for a request that could not be completed synchronously.
    461 // It is owned by a Job. Canceled Requests are only marked as canceled rather
    462 // than removed from the Job's |requests_| list.
    463 class HostResolverImpl::Request {
    464  public:
    465   Request(const BoundNetLog& source_net_log,
    466           const BoundNetLog& request_net_log,
    467           const RequestInfo& info,
    468           const CompletionCallback& callback,
    469           AddressList* addresses)
    470       : source_net_log_(source_net_log),
    471         request_net_log_(request_net_log),
    472         info_(info),
    473         job_(NULL),
    474         callback_(callback),
    475         addresses_(addresses),
    476         request_time_(base::TimeTicks::Now()) {
    477   }
    478 
    479   // Mark the request as canceled.
    480   void MarkAsCanceled() {
    481     job_ = NULL;
    482     addresses_ = NULL;
    483     callback_.Reset();
    484   }
    485 
    486   bool was_canceled() const {
    487     return callback_.is_null();
    488   }
    489 
    490   void set_job(Job* job) {
    491     DCHECK(job);
    492     // Identify which job the request is waiting on.
    493     job_ = job;
    494   }
    495 
    496   // Prepare final AddressList and call completion callback.
    497   void OnComplete(int error, const AddressList& addr_list) {
    498     DCHECK(!was_canceled());
    499     if (error == OK)
    500       *addresses_ = EnsurePortOnAddressList(addr_list, info_.port());
    501     CompletionCallback callback = callback_;
    502     MarkAsCanceled();
    503     callback.Run(error);
    504   }
    505 
    506   Job* job() const {
    507     return job_;
    508   }
    509 
    510   // NetLog for the source, passed in HostResolver::Resolve.
    511   const BoundNetLog& source_net_log() {
    512     return source_net_log_;
    513   }
    514 
    515   // NetLog for this request.
    516   const BoundNetLog& request_net_log() {
    517     return request_net_log_;
    518   }
    519 
    520   const RequestInfo& info() const {
    521     return info_;
    522   }
    523 
    524   base::TimeTicks request_time() const {
    525     return request_time_;
    526   }
    527 
    528  private:
    529   BoundNetLog source_net_log_;
    530   BoundNetLog request_net_log_;
    531 
    532   // The request info that started the request.
    533   RequestInfo info_;
    534 
    535   // The resolve job that this request is dependent on.
    536   Job* job_;
    537 
    538   // The user's callback to invoke when the request completes.
    539   CompletionCallback callback_;
    540 
    541   // The address list to save result into.
    542   AddressList* addresses_;
    543 
    544   const base::TimeTicks request_time_;
    545 
    546   DISALLOW_COPY_AND_ASSIGN(Request);
    547 };
    548 
    549 //------------------------------------------------------------------------------
    550 
    551 // Calls HostResolverProc on the WorkerPool. Performs retries if necessary.
    552 //
    553 // Whenever we try to resolve the host, we post a delayed task to check if host
    554 // resolution (OnLookupComplete) is completed or not. If the original attempt
    555 // hasn't completed, then we start another attempt for host resolution. We take
    556 // the results from the first attempt that finishes and ignore the results from
    557 // all other attempts.
    558 //
    559 // TODO(szym): Move to separate source file for testing and mocking.
    560 //
    561 class HostResolverImpl::ProcTask
    562     : public base::RefCountedThreadSafe<HostResolverImpl::ProcTask> {
    563  public:
    564   typedef base::Callback<void(int net_error,
    565                               const AddressList& addr_list)> Callback;
    566 
    567   ProcTask(const Key& key,
    568            const ProcTaskParams& params,
    569            const Callback& callback,
    570            const BoundNetLog& job_net_log)
    571       : key_(key),
    572         params_(params),
    573         callback_(callback),
    574         origin_loop_(base::MessageLoopProxy::current()),
    575         attempt_number_(0),
    576         completed_attempt_number_(0),
    577         completed_attempt_error_(ERR_UNEXPECTED),
    578         had_non_speculative_request_(false),
    579         net_log_(job_net_log) {
    580     if (!params_.resolver_proc.get())
    581       params_.resolver_proc = HostResolverProc::GetDefault();
    582     // If default is unset, use the system proc.
    583     if (!params_.resolver_proc.get())
    584       params_.resolver_proc = new SystemHostResolverProc();
    585   }
    586 
    587   void Start() {
    588     DCHECK(origin_loop_->BelongsToCurrentThread());
    589     net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK);
    590     StartLookupAttempt();
    591   }
    592 
    593   // Cancels this ProcTask. It will be orphaned. Any outstanding resolve
    594   // attempts running on worker threads will continue running. Only once all the
    595   // attempts complete will the final reference to this ProcTask be released.
    596   void Cancel() {
    597     DCHECK(origin_loop_->BelongsToCurrentThread());
    598 
    599     if (was_canceled() || was_completed())
    600       return;
    601 
    602     callback_.Reset();
    603     net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK);
    604   }
    605 
    606   void set_had_non_speculative_request() {
    607     DCHECK(origin_loop_->BelongsToCurrentThread());
    608     had_non_speculative_request_ = true;
    609   }
    610 
    611   bool was_canceled() const {
    612     DCHECK(origin_loop_->BelongsToCurrentThread());
    613     return callback_.is_null();
    614   }
    615 
    616   bool was_completed() const {
    617     DCHECK(origin_loop_->BelongsToCurrentThread());
    618     return completed_attempt_number_ > 0;
    619   }
    620 
    621  private:
    622   friend class base::RefCountedThreadSafe<ProcTask>;
    623   ~ProcTask() {}
    624 
    625   void StartLookupAttempt() {
    626     DCHECK(origin_loop_->BelongsToCurrentThread());
    627     base::TimeTicks start_time = base::TimeTicks::Now();
    628     ++attempt_number_;
    629     // Dispatch the lookup attempt to a worker thread.
    630     if (!base::WorkerPool::PostTask(
    631             FROM_HERE,
    632             base::Bind(&ProcTask::DoLookup, this, start_time, attempt_number_),
    633             true)) {
    634       NOTREACHED();
    635 
    636       // Since we could be running within Resolve() right now, we can't just
    637       // call OnLookupComplete().  Instead we must wait until Resolve() has
    638       // returned (IO_PENDING).
    639       origin_loop_->PostTask(
    640           FROM_HERE,
    641           base::Bind(&ProcTask::OnLookupComplete, this, AddressList(),
    642                      start_time, attempt_number_, ERR_UNEXPECTED, 0));
    643       return;
    644     }
    645 
    646     net_log_.AddEvent(
    647         NetLog::TYPE_HOST_RESOLVER_IMPL_ATTEMPT_STARTED,
    648         NetLog::IntegerCallback("attempt_number", attempt_number_));
    649 
    650     // If we don't get the results within a given time, RetryIfNotComplete
    651     // will start a new attempt on a different worker thread if none of our
    652     // outstanding attempts have completed yet.
    653     if (attempt_number_ <= params_.max_retry_attempts) {
    654       origin_loop_->PostDelayedTask(
    655           FROM_HERE,
    656           base::Bind(&ProcTask::RetryIfNotComplete, this),
    657           params_.unresponsive_delay);
    658     }
    659   }
    660 
    661   // WARNING: This code runs inside a worker pool. The shutdown code cannot
    662   // wait for it to finish, so we must be very careful here about using other
    663   // objects (like MessageLoops, Singletons, etc). During shutdown these objects
    664   // may no longer exist. Multiple DoLookups() could be running in parallel, so
    665   // any state inside of |this| must not mutate .
    666   void DoLookup(const base::TimeTicks& start_time,
    667                 const uint32 attempt_number) {
    668     AddressList results;
    669     int os_error = 0;
    670     // Running on the worker thread
    671     int error = params_.resolver_proc->Resolve(key_.hostname,
    672                                                key_.address_family,
    673                                                key_.host_resolver_flags,
    674                                                &results,
    675                                                &os_error);
    676 
    677     origin_loop_->PostTask(
    678         FROM_HERE,
    679         base::Bind(&ProcTask::OnLookupComplete, this, results, start_time,
    680                    attempt_number, error, os_error));
    681   }
    682 
    683   // Makes next attempt if DoLookup() has not finished (runs on origin thread).
    684   void RetryIfNotComplete() {
    685     DCHECK(origin_loop_->BelongsToCurrentThread());
    686 
    687     if (was_completed() || was_canceled())
    688       return;
    689 
    690     params_.unresponsive_delay *= params_.retry_factor;
    691     StartLookupAttempt();
    692   }
    693 
    694   // Callback for when DoLookup() completes (runs on origin thread).
    695   void OnLookupComplete(const AddressList& results,
    696                         const base::TimeTicks& start_time,
    697                         const uint32 attempt_number,
    698                         int error,
    699                         const int os_error) {
    700     DCHECK(origin_loop_->BelongsToCurrentThread());
    701     // If results are empty, we should return an error.
    702     bool empty_list_on_ok = (error == OK && results.empty());
    703     UMA_HISTOGRAM_BOOLEAN("DNS.EmptyAddressListAndNoError", empty_list_on_ok);
    704     if (empty_list_on_ok)
    705       error = ERR_NAME_NOT_RESOLVED;
    706 
    707     bool was_retry_attempt = attempt_number > 1;
    708 
    709     // Ideally the following code would be part of host_resolver_proc.cc,
    710     // however it isn't safe to call NetworkChangeNotifier from worker threads.
    711     // So we do it here on the IO thread instead.
    712     if (error != OK && NetworkChangeNotifier::IsOffline())
    713       error = ERR_INTERNET_DISCONNECTED;
    714 
    715     // If this is the first attempt that is finishing later, then record data
    716     // for the first attempt. Won't contaminate with retry attempt's data.
    717     if (!was_retry_attempt)
    718       RecordPerformanceHistograms(start_time, error, os_error);
    719 
    720     RecordAttemptHistograms(start_time, attempt_number, error, os_error);
    721 
    722     if (was_canceled())
    723       return;
    724 
    725     NetLog::ParametersCallback net_log_callback;
    726     if (error != OK) {
    727       net_log_callback = base::Bind(&NetLogProcTaskFailedCallback,
    728                                     attempt_number,
    729                                     error,
    730                                     os_error);
    731     } else {
    732       net_log_callback = NetLog::IntegerCallback("attempt_number",
    733                                                  attempt_number);
    734     }
    735     net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_ATTEMPT_FINISHED,
    736                       net_log_callback);
    737 
    738     if (was_completed())
    739       return;
    740 
    741     // Copy the results from the first worker thread that resolves the host.
    742     results_ = results;
    743     completed_attempt_number_ = attempt_number;
    744     completed_attempt_error_ = error;
    745 
    746     if (was_retry_attempt) {
    747       // If retry attempt finishes before 1st attempt, then get stats on how
    748       // much time is saved by having spawned an extra attempt.
    749       retry_attempt_finished_time_ = base::TimeTicks::Now();
    750     }
    751 
    752     if (error != OK) {
    753       net_log_callback = base::Bind(&NetLogProcTaskFailedCallback,
    754                                     0, error, os_error);
    755     } else {
    756       net_log_callback = results_.CreateNetLogCallback();
    757     }
    758     net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK,
    759                       net_log_callback);
    760 
    761     callback_.Run(error, results_);
    762   }
    763 
    764   void RecordPerformanceHistograms(const base::TimeTicks& start_time,
    765                                    const int error,
    766                                    const int os_error) const {
    767     DCHECK(origin_loop_->BelongsToCurrentThread());
    768     enum Category {  // Used in HISTOGRAM_ENUMERATION.
    769       RESOLVE_SUCCESS,
    770       RESOLVE_FAIL,
    771       RESOLVE_SPECULATIVE_SUCCESS,
    772       RESOLVE_SPECULATIVE_FAIL,
    773       RESOLVE_MAX,  // Bounding value.
    774     };
    775     int category = RESOLVE_MAX;  // Illegal value for later DCHECK only.
    776 
    777     base::TimeDelta duration = base::TimeTicks::Now() - start_time;
    778     if (error == OK) {
    779       if (had_non_speculative_request_) {
    780         category = RESOLVE_SUCCESS;
    781         DNS_HISTOGRAM("DNS.ResolveSuccess", duration);
    782       } else {
    783         category = RESOLVE_SPECULATIVE_SUCCESS;
    784         DNS_HISTOGRAM("DNS.ResolveSpeculativeSuccess", duration);
    785       }
    786 
    787       // Log DNS lookups based on |address_family|. This will help us determine
    788       // if IPv4 or IPv4/6 lookups are faster or slower.
    789       switch(key_.address_family) {
    790         case ADDRESS_FAMILY_IPV4:
    791           DNS_HISTOGRAM("DNS.ResolveSuccess_FAMILY_IPV4", duration);
    792           break;
    793         case ADDRESS_FAMILY_IPV6:
    794           DNS_HISTOGRAM("DNS.ResolveSuccess_FAMILY_IPV6", duration);
    795           break;
    796         case ADDRESS_FAMILY_UNSPECIFIED:
    797           DNS_HISTOGRAM("DNS.ResolveSuccess_FAMILY_UNSPEC", duration);
    798           break;
    799       }
    800     } else {
    801       if (had_non_speculative_request_) {
    802         category = RESOLVE_FAIL;
    803         DNS_HISTOGRAM("DNS.ResolveFail", duration);
    804       } else {
    805         category = RESOLVE_SPECULATIVE_FAIL;
    806         DNS_HISTOGRAM("DNS.ResolveSpeculativeFail", duration);
    807       }
    808       // Log DNS lookups based on |address_family|. This will help us determine
    809       // if IPv4 or IPv4/6 lookups are faster or slower.
    810       switch(key_.address_family) {
    811         case ADDRESS_FAMILY_IPV4:
    812           DNS_HISTOGRAM("DNS.ResolveFail_FAMILY_IPV4", duration);
    813           break;
    814         case ADDRESS_FAMILY_IPV6:
    815           DNS_HISTOGRAM("DNS.ResolveFail_FAMILY_IPV6", duration);
    816           break;
    817         case ADDRESS_FAMILY_UNSPECIFIED:
    818           DNS_HISTOGRAM("DNS.ResolveFail_FAMILY_UNSPEC", duration);
    819           break;
    820       }
    821       UMA_HISTOGRAM_CUSTOM_ENUMERATION(kOSErrorsForGetAddrinfoHistogramName,
    822                                        std::abs(os_error),
    823                                        GetAllGetAddrinfoOSErrors());
    824     }
    825     DCHECK_LT(category, static_cast<int>(RESOLVE_MAX));  // Be sure it was set.
    826 
    827     UMA_HISTOGRAM_ENUMERATION("DNS.ResolveCategory", category, RESOLVE_MAX);
    828   }
    829 
    830   void RecordAttemptHistograms(const base::TimeTicks& start_time,
    831                                const uint32 attempt_number,
    832                                const int error,
    833                                const int os_error) const {
    834     DCHECK(origin_loop_->BelongsToCurrentThread());
    835     bool first_attempt_to_complete =
    836         completed_attempt_number_ == attempt_number;
    837     bool is_first_attempt = (attempt_number == 1);
    838 
    839     if (first_attempt_to_complete) {
    840       // If this was first attempt to complete, then record the resolution
    841       // status of the attempt.
    842       if (completed_attempt_error_ == OK) {
    843         UMA_HISTOGRAM_ENUMERATION(
    844             "DNS.AttemptFirstSuccess", attempt_number, 100);
    845       } else {
    846         UMA_HISTOGRAM_ENUMERATION(
    847             "DNS.AttemptFirstFailure", attempt_number, 100);
    848       }
    849     }
    850 
    851     if (error == OK)
    852       UMA_HISTOGRAM_ENUMERATION("DNS.AttemptSuccess", attempt_number, 100);
    853     else
    854       UMA_HISTOGRAM_ENUMERATION("DNS.AttemptFailure", attempt_number, 100);
    855 
    856     // If first attempt didn't finish before retry attempt, then calculate stats
    857     // on how much time is saved by having spawned an extra attempt.
    858     if (!first_attempt_to_complete && is_first_attempt && !was_canceled()) {
    859       DNS_HISTOGRAM("DNS.AttemptTimeSavedByRetry",
    860                     base::TimeTicks::Now() - retry_attempt_finished_time_);
    861     }
    862 
    863     if (was_canceled() || !first_attempt_to_complete) {
    864       // Count those attempts which completed after the job was already canceled
    865       // OR after the job was already completed by an earlier attempt (so in
    866       // effect).
    867       UMA_HISTOGRAM_ENUMERATION("DNS.AttemptDiscarded", attempt_number, 100);
    868 
    869       // Record if job is canceled.
    870       if (was_canceled())
    871         UMA_HISTOGRAM_ENUMERATION("DNS.AttemptCancelled", attempt_number, 100);
    872     }
    873 
    874     base::TimeDelta duration = base::TimeTicks::Now() - start_time;
    875     if (error == OK)
    876       DNS_HISTOGRAM("DNS.AttemptSuccessDuration", duration);
    877     else
    878       DNS_HISTOGRAM("DNS.AttemptFailDuration", duration);
    879   }
    880 
    881   // Set on the origin thread, read on the worker thread.
    882   Key key_;
    883 
    884   // Holds an owning reference to the HostResolverProc that we are going to use.
    885   // This may not be the current resolver procedure by the time we call
    886   // ResolveAddrInfo, but that's OK... we'll use it anyways, and the owning
    887   // reference ensures that it remains valid until we are done.
    888   ProcTaskParams params_;
    889 
    890   // The listener to the results of this ProcTask.
    891   Callback callback_;
    892 
    893   // Used to post ourselves onto the origin thread.
    894   scoped_refptr<base::MessageLoopProxy> origin_loop_;
    895 
    896   // Keeps track of the number of attempts we have made so far to resolve the
    897   // host. Whenever we start an attempt to resolve the host, we increase this
    898   // number.
    899   uint32 attempt_number_;
    900 
    901   // The index of the attempt which finished first (or 0 if the job is still in
    902   // progress).
    903   uint32 completed_attempt_number_;
    904 
    905   // The result (a net error code) from the first attempt to complete.
    906   int completed_attempt_error_;
    907 
    908   // The time when retry attempt was finished.
    909   base::TimeTicks retry_attempt_finished_time_;
    910 
    911   // True if a non-speculative request was ever attached to this job
    912   // (regardless of whether or not it was later canceled.
    913   // This boolean is used for histogramming the duration of jobs used to
    914   // service non-speculative requests.
    915   bool had_non_speculative_request_;
    916 
    917   AddressList results_;
    918 
    919   BoundNetLog net_log_;
    920 
    921   DISALLOW_COPY_AND_ASSIGN(ProcTask);
    922 };
    923 
    924 //-----------------------------------------------------------------------------
    925 
    926 // Wraps a call to HaveOnlyLoopbackAddresses to be executed on the WorkerPool as
    927 // it takes 40-100ms and should not block initialization.
    928 class HostResolverImpl::LoopbackProbeJob {
    929  public:
    930   explicit LoopbackProbeJob(const base::WeakPtr<HostResolverImpl>& resolver)
    931       : resolver_(resolver),
    932         result_(false) {
    933     DCHECK(resolver.get());
    934     const bool kIsSlow = true;
    935     base::WorkerPool::PostTaskAndReply(
    936         FROM_HERE,
    937         base::Bind(&LoopbackProbeJob::DoProbe, base::Unretained(this)),
    938         base::Bind(&LoopbackProbeJob::OnProbeComplete, base::Owned(this)),
    939         kIsSlow);
    940   }
    941 
    942   virtual ~LoopbackProbeJob() {}
    943 
    944  private:
    945   // Runs on worker thread.
    946   void DoProbe() {
    947     result_ = HaveOnlyLoopbackAddresses();
    948   }
    949 
    950   void OnProbeComplete() {
    951     if (!resolver_.get())
    952       return;
    953     resolver_->SetHaveOnlyLoopbackAddresses(result_);
    954   }
    955 
    956   // Used/set only on origin thread.
    957   base::WeakPtr<HostResolverImpl> resolver_;
    958 
    959   bool result_;
    960 
    961   DISALLOW_COPY_AND_ASSIGN(LoopbackProbeJob);
    962 };
    963 
    964 //-----------------------------------------------------------------------------
    965 
    966 // Resolves the hostname using DnsTransaction.
    967 // TODO(szym): This could be moved to separate source file as well.
    968 class HostResolverImpl::DnsTask : public base::SupportsWeakPtr<DnsTask> {
    969  public:
    970   typedef base::Callback<void(int net_error,
    971                               const AddressList& addr_list,
    972                               base::TimeDelta ttl)> Callback;
    973 
    974   DnsTask(DnsClient* client,
    975           const Key& key,
    976           const Callback& callback,
    977           const BoundNetLog& job_net_log)
    978       : client_(client),
    979         family_(key.address_family),
    980         callback_(callback),
    981         net_log_(job_net_log) {
    982     DCHECK(client);
    983     DCHECK(!callback.is_null());
    984 
    985     // If unspecified, do IPv4 first, because suffix search will be faster.
    986     uint16 qtype = (family_ == ADDRESS_FAMILY_IPV6) ?
    987                    dns_protocol::kTypeAAAA :
    988                    dns_protocol::kTypeA;
    989     transaction_ = client_->GetTransactionFactory()->CreateTransaction(
    990         key.hostname,
    991         qtype,
    992         base::Bind(&DnsTask::OnTransactionComplete, base::Unretained(this),
    993                    true /* first_query */, base::TimeTicks::Now()),
    994         net_log_);
    995   }
    996 
    997   void Start() {
    998     net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK);
    999     transaction_->Start();
   1000   }
   1001 
   1002  private:
   1003   void OnTransactionComplete(bool first_query,
   1004                              const base::TimeTicks& start_time,
   1005                              DnsTransaction* transaction,
   1006                              int net_error,
   1007                              const DnsResponse* response) {
   1008     DCHECK(transaction);
   1009     base::TimeDelta duration = base::TimeTicks::Now() - start_time;
   1010     // Run |callback_| last since the owning Job will then delete this DnsTask.
   1011     if (net_error != OK) {
   1012       DNS_HISTOGRAM("AsyncDNS.TransactionFailure", duration);
   1013       OnFailure(net_error, DnsResponse::DNS_PARSE_OK);
   1014       return;
   1015     }
   1016 
   1017     CHECK(response);
   1018     DNS_HISTOGRAM("AsyncDNS.TransactionSuccess", duration);
   1019     switch (transaction->GetType()) {
   1020       case dns_protocol::kTypeA:
   1021         DNS_HISTOGRAM("AsyncDNS.TransactionSuccess_A", duration);
   1022         break;
   1023       case dns_protocol::kTypeAAAA:
   1024         DNS_HISTOGRAM("AsyncDNS.TransactionSuccess_AAAA", duration);
   1025         break;
   1026     }
   1027     AddressList addr_list;
   1028     base::TimeDelta ttl;
   1029     DnsResponse::Result result = response->ParseToAddressList(&addr_list, &ttl);
   1030     UMA_HISTOGRAM_ENUMERATION("AsyncDNS.ParseToAddressList",
   1031                               result,
   1032                               DnsResponse::DNS_PARSE_RESULT_MAX);
   1033     if (result != DnsResponse::DNS_PARSE_OK) {
   1034       // Fail even if the other query succeeds.
   1035       OnFailure(ERR_DNS_MALFORMED_RESPONSE, result);
   1036       return;
   1037     }
   1038 
   1039     bool needs_sort = false;
   1040     if (first_query) {
   1041       DCHECK(client_->GetConfig()) <<
   1042           "Transaction should have been aborted when config changed!";
   1043       if (family_ == ADDRESS_FAMILY_IPV6) {
   1044         needs_sort = (addr_list.size() > 1);
   1045       } else if (family_ == ADDRESS_FAMILY_UNSPECIFIED) {
   1046         first_addr_list_ = addr_list;
   1047         first_ttl_ = ttl;
   1048         // Use fully-qualified domain name to avoid search.
   1049         transaction_ = client_->GetTransactionFactory()->CreateTransaction(
   1050             response->GetDottedName() + ".",
   1051             dns_protocol::kTypeAAAA,
   1052             base::Bind(&DnsTask::OnTransactionComplete, base::Unretained(this),
   1053                        false /* first_query */, base::TimeTicks::Now()),
   1054             net_log_);
   1055         transaction_->Start();
   1056         return;
   1057       }
   1058     } else {
   1059       DCHECK_EQ(ADDRESS_FAMILY_UNSPECIFIED, family_);
   1060       bool has_ipv6_addresses = !addr_list.empty();
   1061       if (!first_addr_list_.empty()) {
   1062         ttl = std::min(ttl, first_ttl_);
   1063         // Place IPv4 addresses after IPv6.
   1064         addr_list.insert(addr_list.end(), first_addr_list_.begin(),
   1065                                           first_addr_list_.end());
   1066       }
   1067       needs_sort = (has_ipv6_addresses && addr_list.size() > 1);
   1068     }
   1069 
   1070     if (addr_list.empty()) {
   1071       // TODO(szym): Don't fallback to ProcTask in this case.
   1072       OnFailure(ERR_NAME_NOT_RESOLVED, DnsResponse::DNS_PARSE_OK);
   1073       return;
   1074     }
   1075 
   1076     if (needs_sort) {
   1077       // Sort could complete synchronously.
   1078       client_->GetAddressSorter()->Sort(
   1079           addr_list,
   1080           base::Bind(&DnsTask::OnSortComplete,
   1081                      AsWeakPtr(),
   1082                      base::TimeTicks::Now(),
   1083                      ttl));
   1084     } else {
   1085       OnSuccess(addr_list, ttl);
   1086     }
   1087   }
   1088 
   1089   void OnSortComplete(base::TimeTicks start_time,
   1090                       base::TimeDelta ttl,
   1091                       bool success,
   1092                       const AddressList& addr_list) {
   1093     if (!success) {
   1094       DNS_HISTOGRAM("AsyncDNS.SortFailure",
   1095                     base::TimeTicks::Now() - start_time);
   1096       OnFailure(ERR_DNS_SORT_ERROR, DnsResponse::DNS_PARSE_OK);
   1097       return;
   1098     }
   1099 
   1100     DNS_HISTOGRAM("AsyncDNS.SortSuccess",
   1101                   base::TimeTicks::Now() - start_time);
   1102 
   1103     // AddressSorter prunes unusable destinations.
   1104     if (addr_list.empty()) {
   1105       LOG(WARNING) << "Address list empty after RFC3484 sort";
   1106       OnFailure(ERR_NAME_NOT_RESOLVED, DnsResponse::DNS_PARSE_OK);
   1107       return;
   1108     }
   1109 
   1110     OnSuccess(addr_list, ttl);
   1111   }
   1112 
   1113   void OnFailure(int net_error, DnsResponse::Result result) {
   1114     DCHECK_NE(OK, net_error);
   1115     net_log_.EndEvent(
   1116         NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK,
   1117         base::Bind(&NetLogDnsTaskFailedCallback, net_error, result));
   1118     callback_.Run(net_error, AddressList(), base::TimeDelta());
   1119   }
   1120 
   1121   void OnSuccess(const AddressList& addr_list, base::TimeDelta ttl) {
   1122     net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK,
   1123                       addr_list.CreateNetLogCallback());
   1124     callback_.Run(OK, addr_list, ttl);
   1125   }
   1126 
   1127   DnsClient* client_;
   1128   AddressFamily family_;
   1129   // The listener to the results of this DnsTask.
   1130   Callback callback_;
   1131   const BoundNetLog net_log_;
   1132 
   1133   scoped_ptr<DnsTransaction> transaction_;
   1134 
   1135   // Results from the first transaction. Used only if |family_| is unspecified.
   1136   AddressList first_addr_list_;
   1137   base::TimeDelta first_ttl_;
   1138 
   1139   DISALLOW_COPY_AND_ASSIGN(DnsTask);
   1140 };
   1141 
   1142 //-----------------------------------------------------------------------------
   1143 
   1144 // Aggregates all Requests for the same Key. Dispatched via PriorityDispatch.
   1145 class HostResolverImpl::Job : public PrioritizedDispatcher::Job {
   1146  public:
   1147   // Creates new job for |key| where |request_net_log| is bound to the
   1148   // request that spawned it.
   1149   Job(const base::WeakPtr<HostResolverImpl>& resolver,
   1150       const Key& key,
   1151       RequestPriority priority,
   1152       const BoundNetLog& request_net_log)
   1153       : resolver_(resolver),
   1154         key_(key),
   1155         priority_tracker_(priority),
   1156         had_non_speculative_request_(false),
   1157         had_dns_config_(false),
   1158         dns_task_error_(OK),
   1159         creation_time_(base::TimeTicks::Now()),
   1160         priority_change_time_(creation_time_),
   1161         net_log_(BoundNetLog::Make(request_net_log.net_log(),
   1162                                    NetLog::SOURCE_HOST_RESOLVER_IMPL_JOB)) {
   1163     request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CREATE_JOB);
   1164 
   1165     net_log_.BeginEvent(
   1166         NetLog::TYPE_HOST_RESOLVER_IMPL_JOB,
   1167         base::Bind(&NetLogJobCreationCallback,
   1168                    request_net_log.source(),
   1169                    &key_.hostname));
   1170   }
   1171 
   1172   virtual ~Job() {
   1173     if (is_running()) {
   1174       // |resolver_| was destroyed with this Job still in flight.
   1175       // Clean-up, record in the log, but don't run any callbacks.
   1176       if (is_proc_running()) {
   1177         proc_task_->Cancel();
   1178         proc_task_ = NULL;
   1179       }
   1180       // Clean up now for nice NetLog.
   1181       dns_task_.reset(NULL);
   1182       net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB,
   1183                                         ERR_ABORTED);
   1184     } else if (is_queued()) {
   1185       // |resolver_| was destroyed without running this Job.
   1186       // TODO(szym): is there any benefit in having this distinction?
   1187       net_log_.AddEvent(NetLog::TYPE_CANCELLED);
   1188       net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB);
   1189     }
   1190     // else CompleteRequests logged EndEvent.
   1191 
   1192     // Log any remaining Requests as cancelled.
   1193     for (RequestsList::const_iterator it = requests_.begin();
   1194          it != requests_.end(); ++it) {
   1195       Request* req = *it;
   1196       if (req->was_canceled())
   1197         continue;
   1198       DCHECK_EQ(this, req->job());
   1199       LogCancelRequest(req->source_net_log(), req->request_net_log(),
   1200                        req->info());
   1201     }
   1202   }
   1203 
   1204   // Add this job to the dispatcher.
   1205   void Schedule() {
   1206     handle_ = resolver_->dispatcher_.Add(this, priority());
   1207   }
   1208 
   1209   void AddRequest(scoped_ptr<Request> req) {
   1210     DCHECK_EQ(key_.hostname, req->info().hostname());
   1211 
   1212     req->set_job(this);
   1213     priority_tracker_.Add(req->info().priority());
   1214 
   1215     req->request_net_log().AddEvent(
   1216         NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_ATTACH,
   1217         net_log_.source().ToEventParametersCallback());
   1218 
   1219     net_log_.AddEvent(
   1220         NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_REQUEST_ATTACH,
   1221         base::Bind(&NetLogJobAttachCallback,
   1222                    req->request_net_log().source(),
   1223                    priority()));
   1224 
   1225     // TODO(szym): Check if this is still needed.
   1226     if (!req->info().is_speculative()) {
   1227       had_non_speculative_request_ = true;
   1228       if (proc_task_.get())
   1229         proc_task_->set_had_non_speculative_request();
   1230     }
   1231 
   1232     requests_.push_back(req.release());
   1233 
   1234     UpdatePriority();
   1235   }
   1236 
   1237   // Marks |req| as cancelled. If it was the last active Request, also finishes
   1238   // this Job, marking it as cancelled, and deletes it.
   1239   void CancelRequest(Request* req) {
   1240     DCHECK_EQ(key_.hostname, req->info().hostname());
   1241     DCHECK(!req->was_canceled());
   1242 
   1243     // Don't remove it from |requests_| just mark it canceled.
   1244     req->MarkAsCanceled();
   1245     LogCancelRequest(req->source_net_log(), req->request_net_log(),
   1246                      req->info());
   1247 
   1248     priority_tracker_.Remove(req->info().priority());
   1249     net_log_.AddEvent(
   1250         NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_REQUEST_DETACH,
   1251         base::Bind(&NetLogJobAttachCallback,
   1252                    req->request_net_log().source(),
   1253                    priority()));
   1254 
   1255     if (num_active_requests() > 0) {
   1256       UpdatePriority();
   1257     } else {
   1258       // If we were called from a Request's callback within CompleteRequests,
   1259       // that Request could not have been cancelled, so num_active_requests()
   1260       // could not be 0. Therefore, we are not in CompleteRequests().
   1261       CompleteRequestsWithError(OK /* cancelled */);
   1262     }
   1263   }
   1264 
   1265   // Called from AbortAllInProgressJobs. Completes all requests and destroys
   1266   // the job. This currently assumes the abort is due to a network change.
   1267   void Abort() {
   1268     DCHECK(is_running());
   1269     CompleteRequestsWithError(ERR_NETWORK_CHANGED);
   1270   }
   1271 
   1272   // If DnsTask present, abort it and fall back to ProcTask.
   1273   void AbortDnsTask() {
   1274     if (dns_task_) {
   1275       dns_task_.reset();
   1276       dns_task_error_ = OK;
   1277       StartProcTask();
   1278     }
   1279   }
   1280 
   1281   // Called by HostResolverImpl when this job is evicted due to queue overflow.
   1282   // Completes all requests and destroys the job.
   1283   void OnEvicted() {
   1284     DCHECK(!is_running());
   1285     DCHECK(is_queued());
   1286     handle_.Reset();
   1287 
   1288     net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_EVICTED);
   1289 
   1290     // This signals to CompleteRequests that this job never ran.
   1291     CompleteRequestsWithError(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE);
   1292   }
   1293 
   1294   // Attempts to serve the job from HOSTS. Returns true if succeeded and
   1295   // this Job was destroyed.
   1296   bool ServeFromHosts() {
   1297     DCHECK_GT(num_active_requests(), 0u);
   1298     AddressList addr_list;
   1299     if (resolver_->ServeFromHosts(key(),
   1300                                   requests_.front()->info(),
   1301                                   &addr_list)) {
   1302       // This will destroy the Job.
   1303       CompleteRequests(
   1304           HostCache::Entry(OK, MakeAddressListForRequest(addr_list)),
   1305           base::TimeDelta());
   1306       return true;
   1307     }
   1308     return false;
   1309   }
   1310 
   1311   const Key key() const {
   1312     return key_;
   1313   }
   1314 
   1315   bool is_queued() const {
   1316     return !handle_.is_null();
   1317   }
   1318 
   1319   bool is_running() const {
   1320     return is_dns_running() || is_proc_running();
   1321   }
   1322 
   1323  private:
   1324   void UpdatePriority() {
   1325     if (is_queued()) {
   1326       if (priority() != static_cast<RequestPriority>(handle_.priority()))
   1327         priority_change_time_ = base::TimeTicks::Now();
   1328       handle_ = resolver_->dispatcher_.ChangePriority(handle_, priority());
   1329     }
   1330   }
   1331 
   1332   AddressList MakeAddressListForRequest(const AddressList& list) const {
   1333     if (requests_.empty())
   1334       return list;
   1335     return AddressList::CopyWithPort(list, requests_.front()->info().port());
   1336   }
   1337 
   1338   // PriorityDispatch::Job:
   1339   virtual void Start() OVERRIDE {
   1340     DCHECK(!is_running());
   1341     handle_.Reset();
   1342 
   1343     net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_STARTED);
   1344 
   1345     had_dns_config_ = resolver_->HaveDnsConfig();
   1346 
   1347     base::TimeTicks now = base::TimeTicks::Now();
   1348     base::TimeDelta queue_time = now - creation_time_;
   1349     base::TimeDelta queue_time_after_change = now - priority_change_time_;
   1350 
   1351     if (had_dns_config_) {
   1352       DNS_HISTOGRAM_BY_PRIORITY("AsyncDNS.JobQueueTime", priority(),
   1353                                 queue_time);
   1354       DNS_HISTOGRAM_BY_PRIORITY("AsyncDNS.JobQueueTimeAfterChange", priority(),
   1355                                 queue_time_after_change);
   1356     } else {
   1357       DNS_HISTOGRAM_BY_PRIORITY("DNS.JobQueueTime", priority(), queue_time);
   1358       DNS_HISTOGRAM_BY_PRIORITY("DNS.JobQueueTimeAfterChange", priority(),
   1359                                 queue_time_after_change);
   1360     }
   1361 
   1362     // Caution: Job::Start must not complete synchronously.
   1363     if (had_dns_config_ && !ResemblesMulticastDNSName(key_.hostname)) {
   1364       StartDnsTask();
   1365     } else {
   1366       StartProcTask();
   1367     }
   1368   }
   1369 
   1370   // TODO(szym): Since DnsTransaction does not consume threads, we can increase
   1371   // the limits on |dispatcher_|. But in order to keep the number of WorkerPool
   1372   // threads low, we will need to use an "inner" PrioritizedDispatcher with
   1373   // tighter limits.
   1374   void StartProcTask() {
   1375     DCHECK(!is_dns_running());
   1376     proc_task_ = new ProcTask(
   1377         key_,
   1378         resolver_->proc_params_,
   1379         base::Bind(&Job::OnProcTaskComplete, base::Unretained(this),
   1380                    base::TimeTicks::Now()),
   1381         net_log_);
   1382 
   1383     if (had_non_speculative_request_)
   1384       proc_task_->set_had_non_speculative_request();
   1385     // Start() could be called from within Resolve(), hence it must NOT directly
   1386     // call OnProcTaskComplete, for example, on synchronous failure.
   1387     proc_task_->Start();
   1388   }
   1389 
   1390   // Called by ProcTask when it completes.
   1391   void OnProcTaskComplete(base::TimeTicks start_time,
   1392                           int net_error,
   1393                           const AddressList& addr_list) {
   1394     DCHECK(is_proc_running());
   1395 
   1396     if (!resolver_->resolved_known_ipv6_hostname_ &&
   1397         net_error == OK &&
   1398         key_.address_family == ADDRESS_FAMILY_UNSPECIFIED) {
   1399       if (key_.hostname == "www.google.com") {
   1400         resolver_->resolved_known_ipv6_hostname_ = true;
   1401         bool got_ipv6_address = false;
   1402         for (size_t i = 0; i < addr_list.size(); ++i) {
   1403           if (addr_list[i].GetFamily() == ADDRESS_FAMILY_IPV6) {
   1404             got_ipv6_address = true;
   1405             break;
   1406           }
   1407         }
   1408         UMA_HISTOGRAM_BOOLEAN("Net.UnspecResolvedIPv6", got_ipv6_address);
   1409       }
   1410     }
   1411 
   1412     if (dns_task_error_ != OK) {
   1413       base::TimeDelta duration = base::TimeTicks::Now() - start_time;
   1414       if (net_error == OK) {
   1415         DNS_HISTOGRAM("AsyncDNS.FallbackSuccess", duration);
   1416         if ((dns_task_error_ == ERR_NAME_NOT_RESOLVED) &&
   1417             ResemblesNetBIOSName(key_.hostname)) {
   1418           UmaAsyncDnsResolveStatus(RESOLVE_STATUS_SUSPECT_NETBIOS);
   1419         } else {
   1420           UmaAsyncDnsResolveStatus(RESOLVE_STATUS_PROC_SUCCESS);
   1421         }
   1422         UMA_HISTOGRAM_CUSTOM_ENUMERATION("AsyncDNS.ResolveError",
   1423                                          std::abs(dns_task_error_),
   1424                                          GetAllErrorCodesForUma());
   1425         resolver_->OnDnsTaskResolve(dns_task_error_);
   1426       } else {
   1427         DNS_HISTOGRAM("AsyncDNS.FallbackFail", duration);
   1428         UmaAsyncDnsResolveStatus(RESOLVE_STATUS_FAIL);
   1429       }
   1430     }
   1431 
   1432     base::TimeDelta ttl =
   1433         base::TimeDelta::FromSeconds(kNegativeCacheEntryTTLSeconds);
   1434     if (net_error == OK)
   1435       ttl = base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds);
   1436 
   1437     // Don't store the |ttl| in cache since it's not obtained from the server.
   1438     CompleteRequests(
   1439         HostCache::Entry(net_error, MakeAddressListForRequest(addr_list)),
   1440         ttl);
   1441   }
   1442 
   1443   void StartDnsTask() {
   1444     DCHECK(resolver_->HaveDnsConfig());
   1445     base::TimeTicks start_time = base::TimeTicks::Now();
   1446     dns_task_.reset(new DnsTask(
   1447         resolver_->dns_client_.get(),
   1448         key_,
   1449         base::Bind(&Job::OnDnsTaskComplete, base::Unretained(this), start_time),
   1450         net_log_));
   1451 
   1452     dns_task_->Start();
   1453   }
   1454 
   1455   // Called if DnsTask fails. It is posted from StartDnsTask, so Job may be
   1456   // deleted before this callback. In this case dns_task is deleted as well,
   1457   // so we use it as indicator whether Job is still valid.
   1458   void OnDnsTaskFailure(const base::WeakPtr<DnsTask>& dns_task,
   1459                         base::TimeDelta duration,
   1460                         int net_error) {
   1461     DNS_HISTOGRAM("AsyncDNS.ResolveFail", duration);
   1462 
   1463     if (dns_task == NULL)
   1464       return;
   1465 
   1466     dns_task_error_ = net_error;
   1467 
   1468     // TODO(szym): Run ServeFromHosts now if nsswitch.conf says so.
   1469     // http://crbug.com/117655
   1470 
   1471     // TODO(szym): Some net errors indicate lack of connectivity. Starting
   1472     // ProcTask in that case is a waste of time.
   1473     if (resolver_->fallback_to_proctask_) {
   1474       dns_task_.reset();
   1475       StartProcTask();
   1476     } else {
   1477       UmaAsyncDnsResolveStatus(RESOLVE_STATUS_FAIL);
   1478       CompleteRequestsWithError(net_error);
   1479     }
   1480   }
   1481 
   1482   // Called by DnsTask when it completes.
   1483   void OnDnsTaskComplete(base::TimeTicks start_time,
   1484                          int net_error,
   1485                          const AddressList& addr_list,
   1486                          base::TimeDelta ttl) {
   1487     DCHECK(is_dns_running());
   1488 
   1489     base::TimeDelta duration = base::TimeTicks::Now() - start_time;
   1490     if (net_error != OK) {
   1491       OnDnsTaskFailure(dns_task_->AsWeakPtr(), duration, net_error);
   1492       return;
   1493     }
   1494     DNS_HISTOGRAM("AsyncDNS.ResolveSuccess", duration);
   1495     // Log DNS lookups based on |address_family|.
   1496     switch(key_.address_family) {
   1497       case ADDRESS_FAMILY_IPV4:
   1498         DNS_HISTOGRAM("AsyncDNS.ResolveSuccess_FAMILY_IPV4", duration);
   1499         break;
   1500       case ADDRESS_FAMILY_IPV6:
   1501         DNS_HISTOGRAM("AsyncDNS.ResolveSuccess_FAMILY_IPV6", duration);
   1502         break;
   1503       case ADDRESS_FAMILY_UNSPECIFIED:
   1504         DNS_HISTOGRAM("AsyncDNS.ResolveSuccess_FAMILY_UNSPEC", duration);
   1505         break;
   1506     }
   1507 
   1508     UmaAsyncDnsResolveStatus(RESOLVE_STATUS_DNS_SUCCESS);
   1509     RecordTTL(ttl);
   1510 
   1511     resolver_->OnDnsTaskResolve(OK);
   1512 
   1513     base::TimeDelta bounded_ttl =
   1514         std::max(ttl, base::TimeDelta::FromSeconds(kMinimumTTLSeconds));
   1515 
   1516     CompleteRequests(
   1517         HostCache::Entry(net_error, MakeAddressListForRequest(addr_list), ttl),
   1518         bounded_ttl);
   1519   }
   1520 
   1521   // Performs Job's last rites. Completes all Requests. Deletes this.
   1522   void CompleteRequests(const HostCache::Entry& entry,
   1523                         base::TimeDelta ttl) {
   1524     CHECK(resolver_.get());
   1525 
   1526     // This job must be removed from resolver's |jobs_| now to make room for a
   1527     // new job with the same key in case one of the OnComplete callbacks decides
   1528     // to spawn one. Consequently, the job deletes itself when CompleteRequests
   1529     // is done.
   1530     scoped_ptr<Job> self_deleter(this);
   1531 
   1532     resolver_->RemoveJob(this);
   1533 
   1534     if (is_running()) {
   1535       DCHECK(!is_queued());
   1536       if (is_proc_running()) {
   1537         proc_task_->Cancel();
   1538         proc_task_ = NULL;
   1539       }
   1540       dns_task_.reset();
   1541 
   1542       // Signal dispatcher that a slot has opened.
   1543       resolver_->dispatcher_.OnJobFinished();
   1544     } else if (is_queued()) {
   1545       resolver_->dispatcher_.Cancel(handle_);
   1546       handle_.Reset();
   1547     }
   1548 
   1549     if (num_active_requests() == 0) {
   1550       net_log_.AddEvent(NetLog::TYPE_CANCELLED);
   1551       net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB,
   1552                                         OK);
   1553       return;
   1554     }
   1555 
   1556     net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB,
   1557                                       entry.error);
   1558 
   1559     DCHECK(!requests_.empty());
   1560 
   1561     if (entry.error == OK) {
   1562       // Record this histogram here, when we know the system has a valid DNS
   1563       // configuration.
   1564       UMA_HISTOGRAM_BOOLEAN("AsyncDNS.HaveDnsConfig",
   1565                             resolver_->received_dns_config_);
   1566     }
   1567 
   1568     bool did_complete = (entry.error != ERR_NETWORK_CHANGED) &&
   1569                         (entry.error != ERR_HOST_RESOLVER_QUEUE_TOO_LARGE);
   1570     if (did_complete)
   1571       resolver_->CacheResult(key_, entry, ttl);
   1572 
   1573     // Complete all of the requests that were attached to the job.
   1574     for (RequestsList::const_iterator it = requests_.begin();
   1575          it != requests_.end(); ++it) {
   1576       Request* req = *it;
   1577 
   1578       if (req->was_canceled())
   1579         continue;
   1580 
   1581       DCHECK_EQ(this, req->job());
   1582       // Update the net log and notify registered observers.
   1583       LogFinishRequest(req->source_net_log(), req->request_net_log(),
   1584                        req->info(), entry.error);
   1585       if (did_complete) {
   1586         // Record effective total time from creation to completion.
   1587         RecordTotalTime(had_dns_config_, req->info().is_speculative(),
   1588                         base::TimeTicks::Now() - req->request_time());
   1589       }
   1590       req->OnComplete(entry.error, entry.addrlist);
   1591 
   1592       // Check if the resolver was destroyed as a result of running the
   1593       // callback. If it was, we could continue, but we choose to bail.
   1594       if (!resolver_.get())
   1595         return;
   1596     }
   1597   }
   1598 
   1599   // Convenience wrapper for CompleteRequests in case of failure.
   1600   void CompleteRequestsWithError(int net_error) {
   1601     CompleteRequests(HostCache::Entry(net_error, AddressList()),
   1602                      base::TimeDelta());
   1603   }
   1604 
   1605   RequestPriority priority() const {
   1606     return priority_tracker_.highest_priority();
   1607   }
   1608 
   1609   // Number of non-canceled requests in |requests_|.
   1610   size_t num_active_requests() const {
   1611     return priority_tracker_.total_count();
   1612   }
   1613 
   1614   bool is_dns_running() const {
   1615     return dns_task_.get() != NULL;
   1616   }
   1617 
   1618   bool is_proc_running() const {
   1619     return proc_task_.get() != NULL;
   1620   }
   1621 
   1622   base::WeakPtr<HostResolverImpl> resolver_;
   1623 
   1624   Key key_;
   1625 
   1626   // Tracks the highest priority across |requests_|.
   1627   PriorityTracker priority_tracker_;
   1628 
   1629   bool had_non_speculative_request_;
   1630 
   1631   // Distinguishes measurements taken while DnsClient was fully configured.
   1632   bool had_dns_config_;
   1633 
   1634   // Result of DnsTask.
   1635   int dns_task_error_;
   1636 
   1637   const base::TimeTicks creation_time_;
   1638   base::TimeTicks priority_change_time_;
   1639 
   1640   BoundNetLog net_log_;
   1641 
   1642   // Resolves the host using a HostResolverProc.
   1643   scoped_refptr<ProcTask> proc_task_;
   1644 
   1645   // Resolves the host using a DnsTransaction.
   1646   scoped_ptr<DnsTask> dns_task_;
   1647 
   1648   // All Requests waiting for the result of this Job. Some can be canceled.
   1649   RequestsList requests_;
   1650 
   1651   // A handle used in |HostResolverImpl::dispatcher_|.
   1652   PrioritizedDispatcher::Handle handle_;
   1653 };
   1654 
   1655 //-----------------------------------------------------------------------------
   1656 
   1657 HostResolverImpl::ProcTaskParams::ProcTaskParams(
   1658     HostResolverProc* resolver_proc,
   1659     size_t max_retry_attempts)
   1660     : resolver_proc(resolver_proc),
   1661       max_retry_attempts(max_retry_attempts),
   1662       unresponsive_delay(base::TimeDelta::FromMilliseconds(6000)),
   1663       retry_factor(2) {
   1664 }
   1665 
   1666 HostResolverImpl::ProcTaskParams::~ProcTaskParams() {}
   1667 
   1668 HostResolverImpl::HostResolverImpl(
   1669     scoped_ptr<HostCache> cache,
   1670     const PrioritizedDispatcher::Limits& job_limits,
   1671     const ProcTaskParams& proc_params,
   1672     NetLog* net_log)
   1673     : cache_(cache.Pass()),
   1674       dispatcher_(job_limits),
   1675       max_queued_jobs_(job_limits.total_jobs * 100u),
   1676       proc_params_(proc_params),
   1677       net_log_(net_log),
   1678       default_address_family_(ADDRESS_FAMILY_UNSPECIFIED),
   1679       weak_ptr_factory_(this),
   1680       probe_weak_ptr_factory_(this),
   1681       received_dns_config_(false),
   1682       num_dns_failures_(0),
   1683       probe_ipv6_support_(true),
   1684       resolved_known_ipv6_hostname_(false),
   1685       additional_resolver_flags_(0),
   1686       fallback_to_proctask_(true) {
   1687 
   1688   DCHECK_GE(dispatcher_.num_priorities(), static_cast<size_t>(NUM_PRIORITIES));
   1689 
   1690   // Maximum of 4 retry attempts for host resolution.
   1691   static const size_t kDefaultMaxRetryAttempts = 4u;
   1692 
   1693   if (proc_params_.max_retry_attempts == HostResolver::kDefaultRetryAttempts)
   1694     proc_params_.max_retry_attempts = kDefaultMaxRetryAttempts;
   1695 
   1696 #if defined(OS_WIN)
   1697   EnsureWinsockInit();
   1698 #endif
   1699 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
   1700   new LoopbackProbeJob(weak_ptr_factory_.GetWeakPtr());
   1701 #endif
   1702   NetworkChangeNotifier::AddIPAddressObserver(this);
   1703   NetworkChangeNotifier::AddDNSObserver(this);
   1704 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) && \
   1705     !defined(OS_ANDROID)
   1706   EnsureDnsReloaderInit();
   1707 #endif
   1708 
   1709   // TODO(szym): Remove when received_dns_config_ is removed, once
   1710   // http://crbug.com/137914 is resolved.
   1711   {
   1712     DnsConfig dns_config;
   1713     NetworkChangeNotifier::GetDnsConfig(&dns_config);
   1714     received_dns_config_ = dns_config.IsValid();
   1715   }
   1716 
   1717   fallback_to_proctask_ = !ConfigureAsyncDnsNoFallbackFieldTrial();
   1718 }
   1719 
   1720 HostResolverImpl::~HostResolverImpl() {
   1721   // This will also cancel all outstanding requests.
   1722   STLDeleteValues(&jobs_);
   1723 
   1724   NetworkChangeNotifier::RemoveIPAddressObserver(this);
   1725   NetworkChangeNotifier::RemoveDNSObserver(this);
   1726 }
   1727 
   1728 void HostResolverImpl::SetMaxQueuedJobs(size_t value) {
   1729   DCHECK_EQ(0u, dispatcher_.num_queued_jobs());
   1730   DCHECK_GT(value, 0u);
   1731   max_queued_jobs_ = value;
   1732 }
   1733 
   1734 int HostResolverImpl::Resolve(const RequestInfo& info,
   1735                               AddressList* addresses,
   1736                               const CompletionCallback& callback,
   1737                               RequestHandle* out_req,
   1738                               const BoundNetLog& source_net_log) {
   1739   DCHECK(addresses);
   1740   DCHECK(CalledOnValidThread());
   1741   DCHECK_EQ(false, callback.is_null());
   1742 
   1743   // Check that the caller supplied a valid hostname to resolve.
   1744   std::string labeled_hostname;
   1745   if (!DNSDomainFromDot(info.hostname(), &labeled_hostname))
   1746     return ERR_NAME_NOT_RESOLVED;
   1747 
   1748   // Make a log item for the request.
   1749   BoundNetLog request_net_log = BoundNetLog::Make(net_log_,
   1750       NetLog::SOURCE_HOST_RESOLVER_IMPL_REQUEST);
   1751 
   1752   LogStartRequest(source_net_log, request_net_log, info);
   1753 
   1754   // Build a key that identifies the request in the cache and in the
   1755   // outstanding jobs map.
   1756   Key key = GetEffectiveKeyForRequest(info, request_net_log);
   1757 
   1758   int rv = ResolveHelper(key, info, addresses, request_net_log);
   1759   if (rv != ERR_DNS_CACHE_MISS) {
   1760     LogFinishRequest(source_net_log, request_net_log, info, rv);
   1761     RecordTotalTime(HaveDnsConfig(), info.is_speculative(), base::TimeDelta());
   1762     return rv;
   1763   }
   1764 
   1765   // Next we need to attach our request to a "job". This job is responsible for
   1766   // calling "getaddrinfo(hostname)" on a worker thread.
   1767 
   1768   JobMap::iterator jobit = jobs_.find(key);
   1769   Job* job;
   1770   if (jobit == jobs_.end()) {
   1771     job = new Job(weak_ptr_factory_.GetWeakPtr(), key, info.priority(),
   1772                   request_net_log);
   1773     job->Schedule();
   1774 
   1775     // Check for queue overflow.
   1776     if (dispatcher_.num_queued_jobs() > max_queued_jobs_) {
   1777       Job* evicted = static_cast<Job*>(dispatcher_.EvictOldestLowest());
   1778       DCHECK(evicted);
   1779       evicted->OnEvicted();  // Deletes |evicted|.
   1780       if (evicted == job) {
   1781         rv = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE;
   1782         LogFinishRequest(source_net_log, request_net_log, info, rv);
   1783         return rv;
   1784       }
   1785     }
   1786     jobs_.insert(jobit, std::make_pair(key, job));
   1787   } else {
   1788     job = jobit->second;
   1789   }
   1790 
   1791   // Can't complete synchronously. Create and attach request.
   1792   scoped_ptr<Request> req(new Request(source_net_log,
   1793                                       request_net_log,
   1794                                       info,
   1795                                       callback,
   1796                                       addresses));
   1797   if (out_req)
   1798     *out_req = reinterpret_cast<RequestHandle>(req.get());
   1799 
   1800   job->AddRequest(req.Pass());
   1801   // Completion happens during Job::CompleteRequests().
   1802   return ERR_IO_PENDING;
   1803 }
   1804 
   1805 int HostResolverImpl::ResolveHelper(const Key& key,
   1806                                     const RequestInfo& info,
   1807                                     AddressList* addresses,
   1808                                     const BoundNetLog& request_net_log) {
   1809   // The result of |getaddrinfo| for empty hosts is inconsistent across systems.
   1810   // On Windows it gives the default interface's address, whereas on Linux it
   1811   // gives an error. We will make it fail on all platforms for consistency.
   1812   if (info.hostname().empty() || info.hostname().size() > kMaxHostLength)
   1813     return ERR_NAME_NOT_RESOLVED;
   1814 
   1815   int net_error = ERR_UNEXPECTED;
   1816   if (ResolveAsIP(key, info, &net_error, addresses))
   1817     return net_error;
   1818   if (ServeFromCache(key, info, &net_error, addresses)) {
   1819     request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT);
   1820     return net_error;
   1821   }
   1822   // TODO(szym): Do not do this if nsswitch.conf instructs not to.
   1823   // http://crbug.com/117655
   1824   if (ServeFromHosts(key, info, addresses)) {
   1825     request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_HOSTS_HIT);
   1826     return OK;
   1827   }
   1828   return ERR_DNS_CACHE_MISS;
   1829 }
   1830 
   1831 int HostResolverImpl::ResolveFromCache(const RequestInfo& info,
   1832                                        AddressList* addresses,
   1833                                        const BoundNetLog& source_net_log) {
   1834   DCHECK(CalledOnValidThread());
   1835   DCHECK(addresses);
   1836 
   1837   // Make a log item for the request.
   1838   BoundNetLog request_net_log = BoundNetLog::Make(net_log_,
   1839       NetLog::SOURCE_HOST_RESOLVER_IMPL_REQUEST);
   1840 
   1841   // Update the net log and notify registered observers.
   1842   LogStartRequest(source_net_log, request_net_log, info);
   1843 
   1844   Key key = GetEffectiveKeyForRequest(info, request_net_log);
   1845 
   1846   int rv = ResolveHelper(key, info, addresses, request_net_log);
   1847   LogFinishRequest(source_net_log, request_net_log, info, rv);
   1848   return rv;
   1849 }
   1850 
   1851 void HostResolverImpl::CancelRequest(RequestHandle req_handle) {
   1852   DCHECK(CalledOnValidThread());
   1853   Request* req = reinterpret_cast<Request*>(req_handle);
   1854   DCHECK(req);
   1855   Job* job = req->job();
   1856   DCHECK(job);
   1857   job->CancelRequest(req);
   1858 }
   1859 
   1860 void HostResolverImpl::SetDefaultAddressFamily(AddressFamily address_family) {
   1861   DCHECK(CalledOnValidThread());
   1862   default_address_family_ = address_family;
   1863   probe_ipv6_support_ = false;
   1864 }
   1865 
   1866 AddressFamily HostResolverImpl::GetDefaultAddressFamily() const {
   1867   return default_address_family_;
   1868 }
   1869 
   1870 void HostResolverImpl::SetDnsClientEnabled(bool enabled) {
   1871   DCHECK(CalledOnValidThread());
   1872 #if defined(ENABLE_BUILT_IN_DNS)
   1873   if (enabled && !dns_client_) {
   1874     SetDnsClient(DnsClient::CreateClient(net_log_));
   1875   } else if (!enabled && dns_client_) {
   1876     SetDnsClient(scoped_ptr<DnsClient>());
   1877   }
   1878 #endif
   1879 }
   1880 
   1881 HostCache* HostResolverImpl::GetHostCache() {
   1882   return cache_.get();
   1883 }
   1884 
   1885 base::Value* HostResolverImpl::GetDnsConfigAsValue() const {
   1886   // Check if async DNS is disabled.
   1887   if (!dns_client_.get())
   1888     return NULL;
   1889 
   1890   // Check if async DNS is enabled, but we currently have no configuration
   1891   // for it.
   1892   const DnsConfig* dns_config = dns_client_->GetConfig();
   1893   if (dns_config == NULL)
   1894     return new base::DictionaryValue();
   1895 
   1896   return dns_config->ToValue();
   1897 }
   1898 
   1899 bool HostResolverImpl::ResolveAsIP(const Key& key,
   1900                                    const RequestInfo& info,
   1901                                    int* net_error,
   1902                                    AddressList* addresses) {
   1903   DCHECK(addresses);
   1904   DCHECK(net_error);
   1905   IPAddressNumber ip_number;
   1906   if (!ParseIPLiteralToNumber(key.hostname, &ip_number))
   1907     return false;
   1908 
   1909   DCHECK_EQ(key.host_resolver_flags &
   1910       ~(HOST_RESOLVER_CANONNAME | HOST_RESOLVER_LOOPBACK_ONLY |
   1911         HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6),
   1912             0) << " Unhandled flag";
   1913   bool ipv6_disabled = (default_address_family_ == ADDRESS_FAMILY_IPV4) &&
   1914       !probe_ipv6_support_;
   1915   *net_error = OK;
   1916   if ((ip_number.size() == kIPv6AddressSize) && ipv6_disabled) {
   1917     *net_error = ERR_NAME_NOT_RESOLVED;
   1918   } else {
   1919     *addresses = AddressList::CreateFromIPAddress(ip_number, info.port());
   1920     if (key.host_resolver_flags & HOST_RESOLVER_CANONNAME)
   1921       addresses->SetDefaultCanonicalName();
   1922   }
   1923   return true;
   1924 }
   1925 
   1926 bool HostResolverImpl::ServeFromCache(const Key& key,
   1927                                       const RequestInfo& info,
   1928                                       int* net_error,
   1929                                       AddressList* addresses) {
   1930   DCHECK(addresses);
   1931   DCHECK(net_error);
   1932   if (!info.allow_cached_response() || !cache_.get())
   1933     return false;
   1934 
   1935   const HostCache::Entry* cache_entry = cache_->Lookup(
   1936       key, base::TimeTicks::Now());
   1937   if (!cache_entry)
   1938     return false;
   1939 
   1940   *net_error = cache_entry->error;
   1941   if (*net_error == OK) {
   1942     if (cache_entry->has_ttl())
   1943       RecordTTL(cache_entry->ttl);
   1944     *addresses = EnsurePortOnAddressList(cache_entry->addrlist, info.port());
   1945   }
   1946   return true;
   1947 }
   1948 
   1949 bool HostResolverImpl::ServeFromHosts(const Key& key,
   1950                                       const RequestInfo& info,
   1951                                       AddressList* addresses) {
   1952   DCHECK(addresses);
   1953   if (!HaveDnsConfig())
   1954     return false;
   1955   addresses->clear();
   1956 
   1957   // HOSTS lookups are case-insensitive.
   1958   std::string hostname = StringToLowerASCII(key.hostname);
   1959 
   1960   const DnsHosts& hosts = dns_client_->GetConfig()->hosts;
   1961 
   1962   // If |address_family| is ADDRESS_FAMILY_UNSPECIFIED other implementations
   1963   // (glibc and c-ares) return the first matching line. We have more
   1964   // flexibility, but lose implicit ordering.
   1965   // We prefer IPv6 because "happy eyeballs" will fall back to IPv4 if
   1966   // necessary.
   1967   if (key.address_family == ADDRESS_FAMILY_IPV6 ||
   1968       key.address_family == ADDRESS_FAMILY_UNSPECIFIED) {
   1969     DnsHosts::const_iterator it = hosts.find(
   1970         DnsHostsKey(hostname, ADDRESS_FAMILY_IPV6));
   1971     if (it != hosts.end())
   1972       addresses->push_back(IPEndPoint(it->second, info.port()));
   1973   }
   1974 
   1975   if (key.address_family == ADDRESS_FAMILY_IPV4 ||
   1976       key.address_family == ADDRESS_FAMILY_UNSPECIFIED) {
   1977     DnsHosts::const_iterator it = hosts.find(
   1978         DnsHostsKey(hostname, ADDRESS_FAMILY_IPV4));
   1979     if (it != hosts.end())
   1980       addresses->push_back(IPEndPoint(it->second, info.port()));
   1981   }
   1982 
   1983   // If got only loopback addresses and the family was restricted, resolve
   1984   // again, without restrictions. See SystemHostResolverCall for rationale.
   1985   if ((key.host_resolver_flags &
   1986           HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6) &&
   1987       IsAllIPv4Loopback(*addresses)) {
   1988     Key new_key(key);
   1989     new_key.address_family = ADDRESS_FAMILY_UNSPECIFIED;
   1990     new_key.host_resolver_flags &=
   1991         ~HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
   1992     return ServeFromHosts(new_key, info, addresses);
   1993   }
   1994   return !addresses->empty();
   1995 }
   1996 
   1997 void HostResolverImpl::CacheResult(const Key& key,
   1998                                    const HostCache::Entry& entry,
   1999                                    base::TimeDelta ttl) {
   2000   if (cache_.get())
   2001     cache_->Set(key, entry, base::TimeTicks::Now(), ttl);
   2002 }
   2003 
   2004 void HostResolverImpl::RemoveJob(Job* job) {
   2005   DCHECK(job);
   2006   JobMap::iterator it = jobs_.find(job->key());
   2007   if (it != jobs_.end() && it->second == job)
   2008     jobs_.erase(it);
   2009 }
   2010 
   2011 void HostResolverImpl::SetHaveOnlyLoopbackAddresses(bool result) {
   2012   if (result) {
   2013     additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY;
   2014   } else {
   2015     additional_resolver_flags_ &= ~HOST_RESOLVER_LOOPBACK_ONLY;
   2016   }
   2017 }
   2018 
   2019 HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest(
   2020     const RequestInfo& info, const BoundNetLog& net_log) const {
   2021   HostResolverFlags effective_flags =
   2022       info.host_resolver_flags() | additional_resolver_flags_;
   2023   AddressFamily effective_address_family = info.address_family();
   2024 
   2025   if (info.address_family() == ADDRESS_FAMILY_UNSPECIFIED) {
   2026     base::TimeTicks start_time = base::TimeTicks::Now();
   2027     // Google DNS address.
   2028     const uint8 kIPv6Address[] =
   2029         { 0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00,
   2030           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88 };
   2031     IPAddressNumber address(kIPv6Address,
   2032                             kIPv6Address + arraysize(kIPv6Address));
   2033     bool rv6 = IsGloballyReachable(address, net_log);
   2034     if (rv6)
   2035       net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_IPV6_SUPPORTED);
   2036 
   2037     UMA_HISTOGRAM_TIMES("Net.IPv6ConnectDuration",
   2038                         base::TimeTicks::Now() - start_time);
   2039     if (rv6) {
   2040       UMA_HISTOGRAM_BOOLEAN("Net.IPv6ConnectSuccessMatch",
   2041           default_address_family_ == ADDRESS_FAMILY_UNSPECIFIED);
   2042     } else {
   2043       UMA_HISTOGRAM_BOOLEAN("Net.IPv6ConnectFailureMatch",
   2044           default_address_family_ != ADDRESS_FAMILY_UNSPECIFIED);
   2045     }
   2046   }
   2047 
   2048   if (effective_address_family == ADDRESS_FAMILY_UNSPECIFIED &&
   2049       default_address_family_ != ADDRESS_FAMILY_UNSPECIFIED) {
   2050     effective_address_family = default_address_family_;
   2051     if (probe_ipv6_support_)
   2052       effective_flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
   2053   }
   2054 
   2055   return Key(info.hostname(), effective_address_family, effective_flags);
   2056 }
   2057 
   2058 void HostResolverImpl::AbortAllInProgressJobs() {
   2059   // In Abort, a Request callback could spawn new Jobs with matching keys, so
   2060   // first collect and remove all running jobs from |jobs_|.
   2061   ScopedVector<Job> jobs_to_abort;
   2062   for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ) {
   2063     Job* job = it->second;
   2064     if (job->is_running()) {
   2065       jobs_to_abort.push_back(job);
   2066       jobs_.erase(it++);
   2067     } else {
   2068       DCHECK(job->is_queued());
   2069       ++it;
   2070     }
   2071   }
   2072 
   2073   // Check if no dispatcher slots leaked out.
   2074   DCHECK_EQ(dispatcher_.num_running_jobs(), jobs_to_abort.size());
   2075 
   2076   // Life check to bail once |this| is deleted.
   2077   base::WeakPtr<HostResolverImpl> self = weak_ptr_factory_.GetWeakPtr();
   2078 
   2079   // Then Abort them.
   2080   for (size_t i = 0; self.get() && i < jobs_to_abort.size(); ++i) {
   2081     jobs_to_abort[i]->Abort();
   2082     jobs_to_abort[i] = NULL;
   2083   }
   2084 }
   2085 
   2086 void HostResolverImpl::TryServingAllJobsFromHosts() {
   2087   if (!HaveDnsConfig())
   2088     return;
   2089 
   2090   // TODO(szym): Do not do this if nsswitch.conf instructs not to.
   2091   // http://crbug.com/117655
   2092 
   2093   // Life check to bail once |this| is deleted.
   2094   base::WeakPtr<HostResolverImpl> self = weak_ptr_factory_.GetWeakPtr();
   2095 
   2096   for (JobMap::iterator it = jobs_.begin(); self.get() && it != jobs_.end();) {
   2097     Job* job = it->second;
   2098     ++it;
   2099     // This could remove |job| from |jobs_|, but iterator will remain valid.
   2100     job->ServeFromHosts();
   2101   }
   2102 }
   2103 
   2104 void HostResolverImpl::OnIPAddressChanged() {
   2105   resolved_known_ipv6_hostname_ = false;
   2106   // Abandon all ProbeJobs.
   2107   probe_weak_ptr_factory_.InvalidateWeakPtrs();
   2108   if (cache_.get())
   2109     cache_->clear();
   2110 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
   2111   new LoopbackProbeJob(probe_weak_ptr_factory_.GetWeakPtr());
   2112 #endif
   2113   AbortAllInProgressJobs();
   2114   // |this| may be deleted inside AbortAllInProgressJobs().
   2115 }
   2116 
   2117 void HostResolverImpl::OnDNSChanged() {
   2118   DnsConfig dns_config;
   2119   NetworkChangeNotifier::GetDnsConfig(&dns_config);
   2120 
   2121   if (net_log_) {
   2122     net_log_->AddGlobalEntry(
   2123         NetLog::TYPE_DNS_CONFIG_CHANGED,
   2124         base::Bind(&NetLogDnsConfigCallback, &dns_config));
   2125   }
   2126 
   2127   // TODO(szym): Remove once http://crbug.com/137914 is resolved.
   2128   received_dns_config_ = dns_config.IsValid();
   2129 
   2130   num_dns_failures_ = 0;
   2131 
   2132   // We want a new DnsSession in place, before we Abort running Jobs, so that
   2133   // the newly started jobs use the new config.
   2134   if (dns_client_.get()) {
   2135     dns_client_->SetConfig(dns_config);
   2136     if (dns_config.IsValid())
   2137       UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true);
   2138   }
   2139 
   2140   // If the DNS server has changed, existing cached info could be wrong so we
   2141   // have to drop our internal cache :( Note that OS level DNS caches, such
   2142   // as NSCD's cache should be dropped automatically by the OS when
   2143   // resolv.conf changes so we don't need to do anything to clear that cache.
   2144   if (cache_.get())
   2145     cache_->clear();
   2146 
   2147   // Life check to bail once |this| is deleted.
   2148   base::WeakPtr<HostResolverImpl> self = weak_ptr_factory_.GetWeakPtr();
   2149 
   2150   // Existing jobs will have been sent to the original server so they need to
   2151   // be aborted.
   2152   AbortAllInProgressJobs();
   2153 
   2154   // |this| may be deleted inside AbortAllInProgressJobs().
   2155   if (self.get())
   2156     TryServingAllJobsFromHosts();
   2157 }
   2158 
   2159 bool HostResolverImpl::HaveDnsConfig() const {
   2160   // Use DnsClient only if it's fully configured and there is no override by
   2161   // ScopedDefaultHostResolverProc.
   2162   // The alternative is to use NetworkChangeNotifier to override DnsConfig,
   2163   // but that would introduce construction order requirements for NCN and SDHRP.
   2164   return (dns_client_.get() != NULL) && (dns_client_->GetConfig() != NULL) &&
   2165          !(proc_params_.resolver_proc.get() == NULL &&
   2166            HostResolverProc::GetDefault() != NULL);
   2167 }
   2168 
   2169 void HostResolverImpl::OnDnsTaskResolve(int net_error) {
   2170   DCHECK(dns_client_);
   2171   if (net_error == OK) {
   2172     num_dns_failures_ = 0;
   2173     return;
   2174   }
   2175   ++num_dns_failures_;
   2176   if (num_dns_failures_ < kMaximumDnsFailures)
   2177     return;
   2178   // Disable DnsClient until the next DNS change.
   2179   for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ++it)
   2180     it->second->AbortDnsTask();
   2181   dns_client_->SetConfig(DnsConfig());
   2182   UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", false);
   2183   UMA_HISTOGRAM_CUSTOM_ENUMERATION("AsyncDNS.DnsClientDisabledReason",
   2184                                    std::abs(net_error),
   2185                                    GetAllErrorCodesForUma());
   2186 }
   2187 
   2188 void HostResolverImpl::SetDnsClient(scoped_ptr<DnsClient> dns_client) {
   2189   if (HaveDnsConfig()) {
   2190     for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ++it)
   2191       it->second->AbortDnsTask();
   2192   }
   2193   dns_client_ = dns_client.Pass();
   2194   if (!dns_client_ || dns_client_->GetConfig() ||
   2195       num_dns_failures_ >= kMaximumDnsFailures) {
   2196     return;
   2197   }
   2198   DnsConfig dns_config;
   2199   NetworkChangeNotifier::GetDnsConfig(&dns_config);
   2200   dns_client_->SetConfig(dns_config);
   2201   num_dns_failures_ = 0;
   2202   if (dns_config.IsValid())
   2203     UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true);
   2204 }
   2205 
   2206 }  // namespace net
   2207