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}  // namespace
28
29PrioritizedDispatcher::Limits HostResolver::Options::GetDispatcherLimits()
30    const {
31  PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, max_concurrent_resolves);
32
33  // If not using default, do not use the field trial.
34  if (limits.total_jobs != HostResolver::kDefaultParallelism)
35    return limits;
36
37  // Default, without trial is no reserved slots.
38  limits.total_jobs = kDefaultMaxProcTasks;
39
40  // Parallelism is determined by the field trial.
41  std::string group = base::FieldTrialList::FindFullName(
42      "HostResolverDispatch");
43
44  if (group.empty())
45    return limits;
46
47  // The format of the group name is a list of non-negative integers separated
48  // by ':'. Each of the elements in the list corresponds to an element in
49  // |reserved_slots|, except the last one which is the |total_jobs|.
50
51  std::vector<std::string> group_parts;
52  base::SplitString(group, ':', &group_parts);
53  if (group_parts.size() != NUM_PRIORITIES + 1) {
54    NOTREACHED();
55    return limits;
56  }
57
58  std::vector<size_t> parsed(group_parts.size());
59  size_t total_reserved_slots = 0;
60
61  for (size_t i = 0; i < group_parts.size(); ++i) {
62    if (!base::StringToSizeT(group_parts[i], &parsed[i])) {
63      NOTREACHED();
64      return limits;
65    }
66  }
67
68  size_t total_jobs = parsed.back();
69  parsed.pop_back();
70  for (size_t i = 0; i < parsed.size(); ++i) {
71    total_reserved_slots += parsed[i];
72  }
73
74  // There must be some unreserved slots available for the all priorities.
75  if (total_reserved_slots > total_jobs ||
76      (total_reserved_slots == total_jobs && parsed[MINIMUM_PRIORITY] == 0)) {
77    NOTREACHED();
78    return limits;
79  }
80
81  limits.total_jobs = total_jobs;
82  limits.reserved_slots = parsed;
83  return limits;
84}
85
86HostResolver::Options::Options()
87    : max_concurrent_resolves(kDefaultParallelism),
88      max_retry_attempts(kDefaultRetryAttempts),
89      enable_caching(true) {
90}
91
92HostResolver::RequestInfo::RequestInfo(const HostPortPair& host_port_pair)
93    : host_port_pair_(host_port_pair),
94      address_family_(ADDRESS_FAMILY_UNSPECIFIED),
95      host_resolver_flags_(0),
96      allow_cached_response_(true),
97      is_speculative_(false),
98      is_my_ip_address_(false) {}
99
100HostResolver::~HostResolver() {
101}
102
103AddressFamily HostResolver::GetDefaultAddressFamily() const {
104  return ADDRESS_FAMILY_UNSPECIFIED;
105}
106
107void HostResolver::SetDnsClientEnabled(bool enabled) {
108}
109
110HostCache* HostResolver::GetHostCache() {
111  return NULL;
112}
113
114base::Value* HostResolver::GetDnsConfigAsValue() const {
115  return NULL;
116}
117
118// static
119scoped_ptr<HostResolver> HostResolver::CreateSystemResolver(
120    const Options& options,
121    NetLog* net_log) {
122  return scoped_ptr<HostResolver>(new HostResolverImpl(options, net_log));
123}
124
125// static
126scoped_ptr<HostResolver> HostResolver::CreateDefaultResolver(NetLog* net_log) {
127  return scoped_ptr<HostResolver>(new HostResolverImpl(Options(), net_log));
128}
129
130HostResolver::HostResolver() {
131}
132
133}  // namespace net
134