host_resolver.cc revision 3551c9c881056c480085172ff9840cab31610854
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.h"
6
7#include "base/logging.h"
8#include "base/metrics/field_trial.h"
9#include "base/strings/string_number_conversions.h"
10#include "base/strings/string_split.h"
11#include "net/dns/dns_client.h"
12#include "net/dns/dns_config_service.h"
13#include "net/dns/host_cache.h"
14#include "net/dns/host_resolver_impl.h"
15
16namespace net {
17
18namespace {
19
20// Maximum of 6 concurrent resolver threads (excluding retries).
21// Some routers (or resolvers) appear to start to provide host-not-found if
22// too many simultaneous resolutions are pending.  This number needs to be
23// further optimized, but 8 is what FF currently does. We found some routers
24// that limit this to 6, so we're temporarily holding it at that level.
25const size_t kDefaultMaxProcTasks = 6u;
26
27// When configuring from field trial, do not allow
28const size_t kSaneMaxProcTasks = 20u;
29
30PrioritizedDispatcher::Limits GetDispatcherLimits(
31    const HostResolver::Options& options) {
32  PrioritizedDispatcher::Limits limits(NUM_PRIORITIES,
33                                       options.max_concurrent_resolves);
34
35  // If not using default, do not use the field trial.
36  if (limits.total_jobs != HostResolver::kDefaultParallelism)
37    return limits;
38
39  // Default, without trial is no reserved slots.
40  limits.total_jobs = kDefaultMaxProcTasks;
41
42  // Parallelism is determined by the field trial.
43  std::string group = base::FieldTrialList::FindFullName(
44      "HostResolverDispatch");
45
46  if (group.empty())
47    return limits;
48
49  // The format of the group name is a list of non-negative integers separated
50  // by ':'. Each of the elements in the list corresponds to an element in
51  // |reserved_slots|, except the last one which is the |total_jobs|.
52
53  std::vector<std::string> group_parts;
54  base::SplitString(group, ':', &group_parts);
55  if (group_parts.size() != NUM_PRIORITIES + 1) {
56    NOTREACHED();
57    return limits;
58  }
59
60  std::vector<size_t> parsed(group_parts.size());
61  size_t total_reserved_slots = 0;
62
63  for (size_t i = 0; i < group_parts.size(); ++i) {
64    if (!base::StringToSizeT(group_parts[i], &parsed[i])) {
65      NOTREACHED();
66      return limits;
67    }
68  }
69
70  size_t total_jobs = parsed.back();
71  parsed.pop_back();
72  for (size_t i = 0; i < parsed.size(); ++i) {
73    total_reserved_slots += parsed[i];
74  }
75
76  // There must be some unreserved slots available for the all priorities.
77  if (total_reserved_slots > total_jobs ||
78      (total_reserved_slots == total_jobs && parsed[MINIMUM_PRIORITY] == 0)) {
79    NOTREACHED();
80    return limits;
81  }
82
83  limits.total_jobs = total_jobs;
84  limits.reserved_slots = parsed;
85  return limits;
86}
87
88}  // namespace
89
90HostResolver::Options::Options()
91    : max_concurrent_resolves(kDefaultParallelism),
92      max_retry_attempts(kDefaultRetryAttempts),
93      enable_caching(true) {
94}
95
96HostResolver::RequestInfo::RequestInfo(const HostPortPair& host_port_pair)
97    : host_port_pair_(host_port_pair),
98      address_family_(ADDRESS_FAMILY_UNSPECIFIED),
99      host_resolver_flags_(0),
100      allow_cached_response_(true),
101      is_speculative_(false) {}
102
103HostResolver::~HostResolver() {
104}
105
106AddressFamily HostResolver::GetDefaultAddressFamily() const {
107  return ADDRESS_FAMILY_UNSPECIFIED;
108}
109
110void HostResolver::SetDnsClientEnabled(bool enabled) {
111}
112
113HostCache* HostResolver::GetHostCache() {
114  return NULL;
115}
116
117base::Value* HostResolver::GetDnsConfigAsValue() const {
118  return NULL;
119}
120
121// static
122scoped_ptr<HostResolver>
123HostResolver::CreateSystemResolver(const Options& options, NetLog* net_log) {
124  scoped_ptr<HostCache> cache;
125  if (options.enable_caching)
126    cache = HostCache::CreateDefaultCache();
127  return scoped_ptr<HostResolver>(new HostResolverImpl(
128      cache.Pass(),
129      GetDispatcherLimits(options),
130      HostResolverImpl::ProcTaskParams(NULL, options.max_retry_attempts),
131      net_log));
132}
133
134// static
135scoped_ptr<HostResolver>
136HostResolver::CreateDefaultResolver(NetLog* net_log) {
137  return CreateSystemResolver(Options(), net_log);
138}
139
140HostResolver::HostResolver() {
141}
142
143}  // namespace net
144