12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/host_resolver.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/metrics/field_trial.h"
95e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/dns_client.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/dns_config_service.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/dns/host_cache.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/host_resolver_impl.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net {
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Maximum of 6 concurrent resolver threads (excluding retries).
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Some routers (or resolvers) appear to start to provide host-not-found if
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// too many simultaneous resolutions are pending.  This number needs to be
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// further optimized, but 8 is what FF currently does. We found some routers
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// that limit this to 6, so we're temporarily holding it at that level.
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const size_t kDefaultMaxProcTasks = 6u;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}  // namespace
28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)PrioritizedDispatcher::Limits HostResolver::Options::GetDispatcherLimits()
30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const {
31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, max_concurrent_resolves);
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If not using default, do not use the field trial.
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (limits.total_jobs != HostResolver::kDefaultParallelism)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return limits;
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Default, without trial is no reserved slots.
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  limits.total_jobs = kDefaultMaxProcTasks;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Parallelism is determined by the field trial.
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string group = base::FieldTrialList::FindFullName(
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "HostResolverDispatch");
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (group.empty())
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return limits;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The format of the group name is a list of non-negative integers separated
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // by ':'. Each of the elements in the list corresponds to an element in
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |reserved_slots|, except the last one which is the |total_jobs|.
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> group_parts;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::SplitString(group, ':', &group_parts);
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (group_parts.size() != NUM_PRIORITIES + 1) {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return limits;
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<size_t> parsed(group_parts.size());
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t total_reserved_slots = 0;
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < group_parts.size(); ++i) {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!base::StringToSizeT(group_parts[i], &parsed[i])) {
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return limits;
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t total_jobs = parsed.back();
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parsed.pop_back();
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < parsed.size(); ++i) {
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    total_reserved_slots += parsed[i];
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // There must be some unreserved slots available for the all priorities.
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (total_reserved_slots > total_jobs ||
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (total_reserved_slots == total_jobs && parsed[MINIMUM_PRIORITY] == 0)) {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return limits;
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  limits.total_jobs = total_jobs;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  limits.reserved_slots = parsed;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return limits;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HostResolver::Options::Options()
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : max_concurrent_resolves(kDefaultParallelism),
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      max_retry_attempts(kDefaultRetryAttempts),
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      enable_caching(true) {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HostResolver::RequestInfo::RequestInfo(const HostPortPair& host_port_pair)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : host_port_pair_(host_port_pair),
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      address_family_(ADDRESS_FAMILY_UNSPECIFIED),
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      host_resolver_flags_(0),
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      allow_cached_response_(true),
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      is_speculative_(false),
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      is_my_ip_address_(false) {}
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HostResolver::~HostResolver() {
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AddressFamily HostResolver::GetDefaultAddressFamily() const {
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ADDRESS_FAMILY_UNSPECIFIED;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HostResolver::SetDnsClientEnabled(bool enabled) {
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HostCache* HostResolver::GetHostCache() {
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NULL;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::Value* HostResolver::GetDnsConfigAsValue() const {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NULL;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)scoped_ptr<HostResolver> HostResolver::CreateSystemResolver(
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const Options& options,
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    NetLog* net_log) {
122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return scoped_ptr<HostResolver>(new HostResolverImpl(options, net_log));
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)scoped_ptr<HostResolver> HostResolver::CreateDefaultResolver(NetLog* net_log) {
127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return scoped_ptr<HostResolver>(new HostResolverImpl(Options(), net_log));
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HostResolver::HostResolver() {
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace net
134