1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/mock_host_resolver.h"
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h"
8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string_split.h"
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h"
103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/platform_thread.h"
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/net_errors.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h"
133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/base/sys_addrinfo.h"
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net {
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace {
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickchar* do_strdup(const char* src) {
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#if defined(OS_WIN)
213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return _strdup(src);
223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#else
233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return strdup(src);
243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif
253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Fills |*addrlist| with a socket address for |host_list| which should be a
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// comma-separated list of IPv4 or IPv6 literal(s) without enclosing brackets.
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// If |canonical_name| is non-empty it is used as the DNS canonical name for
30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// the host. Returns OK on success, ERR_UNEXPECTED otherwise.
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint CreateIPAddressList(const std::string& host_list,
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        const std::string& canonical_name,
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        AddressList* addrlist) {
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  *addrlist = AddressList();
35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<std::string> addresses;
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::SplitString(host_list, ',', &addresses);
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (size_t index = 0; index < addresses.size(); ++index) {
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    IPAddressNumber ip_number;
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!ParseIPLiteralToNumber(addresses[index], &ip_number)) {
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      LOG(WARNING) << "Not a supported IP literal: " << addresses[index];
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return ERR_UNEXPECTED;
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    AddressList result(ip_number, -1, false);
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    struct addrinfo* ai = const_cast<struct addrinfo*>(result.head());
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (index == 0)
47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ai->ai_canonname = do_strdup(canonical_name.c_str());
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!addrlist->head())
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      addrlist->Copy(result.head(), false);
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    else
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      addrlist->Append(result.head());
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return OK;
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
58731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickMockHostResolverBase::~MockHostResolverBase() {}
59731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MockHostResolverBase::Reset(HostResolverProc* interceptor) {
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  synchronous_mode_ = false;
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // At the root of the chain, map everything to localhost.
64513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<RuleBasedHostResolverProc> catchall(
65513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      new RuleBasedHostResolverProc(NULL));
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  catchall->AddRule("*", "127.0.0.1");
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Next add a rules-based layer the use controls.
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rules_ = new RuleBasedHostResolverProc(catchall);
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  HostResolverProc* proc = rules_;
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Lastly add the provided interceptor to the front of the chain.
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (interceptor) {
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    interceptor->SetPreviousProc(proc);
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    proc = interceptor;
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  HostCache* cache = NULL;
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (use_caching_) {
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    cache = new HostCache(
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        100,  // max entries.
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        base::TimeDelta::FromMinutes(1),
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        base::TimeDelta::FromSeconds(0));
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
88731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  impl_.reset(new HostResolverImpl(proc, cache, 50u, NULL));
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenint MockHostResolverBase::Resolve(const RequestInfo& info,
9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                  AddressList* addresses,
9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                  CompletionCallback* callback,
9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                  RequestHandle* out_req,
9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                  const BoundNetLog& net_log) {
9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (synchronous_mode_) {
9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    callback = NULL;
9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    out_req = NULL;
9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
10072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return impl_->Resolve(info, addresses, callback, out_req, net_log);
10172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid MockHostResolverBase::CancelRequest(RequestHandle req) {
10472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  impl_->CancelRequest(req);
10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
10772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid MockHostResolverBase::AddObserver(Observer* observer) {
10872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  impl_->AddObserver(observer);
10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid MockHostResolverBase::RemoveObserver(Observer* observer) {
11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  impl_->RemoveObserver(observer);
11372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
11472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
11572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenMockHostResolverBase::MockHostResolverBase(bool use_caching)
11672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : use_caching_(use_caching) {
11772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Reset(NULL);
11872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
11972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//-----------------------------------------------------------------------------
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct RuleBasedHostResolverProc::Rule {
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  enum ResolverType {
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    kResolverTypeFail,
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    kResolverTypeSystem,
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    kResolverTypeIPLiteral,
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ResolverType resolver_type;
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string host_pattern;
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddressFamily address_family;
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HostResolverFlags host_resolver_flags;
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string replacement;
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string canonical_name;
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int latency_ms;  // In milliseconds.
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Rule(ResolverType resolver_type,
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott       const std::string& host_pattern,
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott       AddressFamily address_family,
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       HostResolverFlags host_resolver_flags,
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott       const std::string& replacement,
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       const std::string& canonical_name,
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott       int latency_ms)
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      : resolver_type(resolver_type),
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        host_pattern(host_pattern),
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        address_family(address_family),
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        host_resolver_flags(host_resolver_flags),
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        replacement(replacement),
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canonical_name(canonical_name),
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        latency_ms(latency_ms) {}
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottRuleBasedHostResolverProc::RuleBasedHostResolverProc(HostResolverProc* previous)
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    : HostResolverProc(previous) {
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RuleBasedHostResolverProc::AddRule(const std::string& host_pattern,
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                        const std::string& replacement) {
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AddRuleForAddressFamily(host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                          replacement);
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RuleBasedHostResolverProc::AddRuleForAddressFamily(
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const std::string& host_pattern,
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    AddressFamily address_family,
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const std::string& replacement) {
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(!replacement.empty());
1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
1703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Rule rule(Rule::kResolverTypeSystem, host_pattern, address_family, flags,
1713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            replacement, "", 0);
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rules_.push_back(rule);
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RuleBasedHostResolverProc::AddIPLiteralRule(
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& host_pattern,
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& ip_literal,
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& canonical_name) {
1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Literals are always resolved to themselves by HostResolverImpl,
1803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // consequently we do not support remapping them.
1813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  IPAddressNumber ip_number;
1823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(!ParseIPLiteralToNumber(host_pattern, &ip_number));
1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!canonical_name.empty())
1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    flags |= HOST_RESOLVER_CANONNAME;
1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Rule rule(Rule::kResolverTypeIPLiteral, host_pattern,
188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            ADDRESS_FAMILY_UNSPECIFIED, flags, ip_literal, canonical_name,
189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            0);
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rules_.push_back(rule);
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RuleBasedHostResolverProc::AddRuleWithLatency(
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const std::string& host_pattern,
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const std::string& replacement,
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int latency_ms) {
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(!replacement.empty());
1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Rule rule(Rule::kResolverTypeSystem, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            flags, replacement, "", latency_ms);
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rules_.push_back(rule);
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RuleBasedHostResolverProc::AllowDirectLookup(
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const std::string& host_pattern) {
2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Rule rule(Rule::kResolverTypeSystem, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            flags, "", "", 0);
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rules_.push_back(rule);
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RuleBasedHostResolverProc::AddSimulatedFailure(
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const std::string& host_pattern) {
2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Rule rule(Rule::kResolverTypeFail, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
2193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            flags, "", "", 0);
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rules_.push_back(rule);
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint RuleBasedHostResolverProc::Resolve(const std::string& host,
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                       AddressFamily address_family,
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       HostResolverFlags host_resolver_flags,
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       AddressList* addrlist,
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       int* os_error) {
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RuleList::iterator r;
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (r = rules_.begin(); r != rules_.end(); ++r) {
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bool matches_address_family =
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        r->address_family == ADDRESS_FAMILY_UNSPECIFIED ||
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        r->address_family == address_family;
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Flags match if all of the bitflags in host_resolver_flags are enabled
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // in the rule's host_resolver_flags. However, the rule may have additional
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // flags specified, in which case the flags should still be considered a
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // match.
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool matches_flags = (r->host_resolver_flags & host_resolver_flags) ==
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        host_resolver_flags;
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (matches_flags && matches_address_family &&
2403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        MatchPattern(host, r->host_pattern)) {
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      if (r->latency_ms != 0)
2423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        base::PlatformThread::Sleep(r->latency_ms);
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // Remap to a new host.
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      const std::string& effective_host =
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          r->replacement.empty() ? host : r->replacement;
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // Apply the resolving function to the remapped hostname.
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      switch (r->resolver_type) {
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        case Rule::kResolverTypeFail:
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          return ERR_NAME_NOT_RESOLVED;
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        case Rule::kResolverTypeSystem:
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          return SystemHostResolverProc(effective_host,
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                        address_family,
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        host_resolver_flags,
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        addrlist, os_error);
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        case Rule::kResolverTypeIPLiteral:
258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          return CreateIPAddressList(effective_host,
259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                     r->canonical_name,
260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                     addrlist);
261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        default:
262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          NOTREACHED();
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          return ERR_UNEXPECTED;
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      }
265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return ResolveUsingPrevious(host, address_family,
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              host_resolver_flags, addrlist, os_error);
269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenRuleBasedHostResolverProc::~RuleBasedHostResolverProc() {
27272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
27372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//-----------------------------------------------------------------------------
275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
276731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickWaitingHostResolverProc::WaitingHostResolverProc(HostResolverProc* previous)
277731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    : HostResolverProc(previous), event_(false, false) {}
278731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
279731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid WaitingHostResolverProc::Signal() {
280731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  event_.Signal();
281731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
282731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
283731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickint WaitingHostResolverProc::Resolve(const std::string& host,
284731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                     AddressFamily address_family,
285731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                     HostResolverFlags host_resolver_flags,
286731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                     AddressList* addrlist,
287731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                     int* os_error) {
288731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  event_.Wait();
289731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return ResolveUsingPrevious(host, address_family, host_resolver_flags,
290731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                              addrlist, os_error);
291731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
292731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
293731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickWaitingHostResolverProc::~WaitingHostResolverProc() {}
294731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
295731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick//-----------------------------------------------------------------------------
296731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
297731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickScopedDefaultHostResolverProc::ScopedDefaultHostResolverProc() {}
298731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottScopedDefaultHostResolverProc::ScopedDefaultHostResolverProc(
300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    HostResolverProc* proc) {
301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Init(proc);
302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottScopedDefaultHostResolverProc::~ScopedDefaultHostResolverProc() {
305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  HostResolverProc* old_proc = HostResolverProc::SetDefault(previous_proc_);
306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The lifetimes of multiple instances must be nested.
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK_EQ(old_proc, current_proc_);
308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ScopedDefaultHostResolverProc::Init(HostResolverProc* proc) {
311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  current_proc_ = proc;
312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  previous_proc_ = HostResolverProc::SetDefault(current_proc_);
313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  current_proc_->SetLastProc(previous_proc_);
314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace net
317