mock_host_resolver.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742
  1. // Copyright (c) 2011 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. #ifndef NET_DNS_MOCK_HOST_RESOLVER_H_
  5. #define NET_DNS_MOCK_HOST_RESOLVER_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <list>
  9. #include <map>
  10. #include <memory>
  11. #include <set>
  12. #include <string>
  13. #include <vector>
  14. #include "base/memory/raw_ptr.h"
  15. #include "base/memory/weak_ptr.h"
  16. #include "base/strings/string_piece.h"
  17. #include "base/synchronization/lock.h"
  18. #include "base/synchronization/waitable_event.h"
  19. #include "base/threading/thread_checker.h"
  20. #include "net/base/address_family.h"
  21. #include "net/base/address_list.h"
  22. #include "net/base/completion_once_callback.h"
  23. #include "net/base/host_port_pair.h"
  24. #include "net/base/net_errors.h"
  25. #include "net/base/network_isolation_key.h"
  26. #include "net/dns/host_resolver.h"
  27. #include "net/dns/host_resolver_proc.h"
  28. #include "net/dns/host_resolver_results.h"
  29. #include "net/dns/public/dns_query_type.h"
  30. #include "net/dns/public/host_resolver_source.h"
  31. #include "net/dns/public/mdns_listener_update_type.h"
  32. #include "net/dns/public/secure_dns_policy.h"
  33. #include "net/log/net_log_with_source.h"
  34. #include "third_party/abseil-cpp/absl/types/optional.h"
  35. #include "third_party/abseil-cpp/absl/types/variant.h"
  36. #include "url/scheme_host_port.h"
  37. namespace base {
  38. class TickClock;
  39. } // namespace base
  40. namespace net {
  41. class HostCache;
  42. class IPEndPoint;
  43. class URLRequestContext;
  44. // Fills `ip_endpoints` with a socket address for `host_list` which should be a
  45. // comma-separated list of IPv4 or IPv6 literal(s) without enclosing brackets.
  46. int ParseAddressList(base::StringPiece host_list,
  47. std::vector<net::IPEndPoint>* ip_endpoints);
  48. // In most cases, it is important that unit tests avoid relying on making actual
  49. // DNS queries since the resulting tests can be flaky, especially if the network
  50. // is unreliable for some reason. To simplify writing tests that avoid making
  51. // actual DNS queries, pass a MockHostResolver as the HostResolver dependency.
  52. // The socket addresses returned can be configured using the
  53. // MockHostResolverBase::RuleResolver:
  54. //
  55. // host_resolver->rules()->AddRule("foo.com", "1.2.3.4");
  56. // host_resolver->rules()->AddRule("bar.com", "2.3.4.5");
  57. //
  58. // The above rules define a static mapping from hostnames to IP address
  59. // literals. The first parameter to AddRule specifies a host pattern to match
  60. // against, and the second parameter indicates what IP address should be used to
  61. // replace the given hostname. So, the following is also supported:
  62. //
  63. // host_mapper->AddRule("*.com", "127.0.0.1");
  64. //
  65. // For more advanced matching, the first parameter may be replaced with a
  66. // MockHostResolverBase::RuleResolver::RuleKey. For more advanced responses, the
  67. // second parameter may be replaced with a
  68. // MockHostResolverBase::RuleResolver::RuleResultOrError.
  69. //
  70. // MockHostResolvers may optionally be created with a default result:
  71. //
  72. // MockHostResolver(ERR_NAME_NOT_RESOLVED);
  73. // MockHostResolver(AddressList(ip_endpoint));
  74. // MockHostResolver(MockHostResolverBase::RuleResolver::GetLocalhostResult());
  75. //
  76. // If no default result is given, every resolve request must match a configured
  77. // rule, otherwise DCHECKs will fire.
  78. // Base class shared by MockHostResolver and MockCachingHostResolver.
  79. class MockHostResolverBase
  80. : public HostResolver,
  81. public base::SupportsWeakPtr<MockHostResolverBase> {
  82. private:
  83. class RequestImpl;
  84. class ProbeRequestImpl;
  85. class MdnsListenerImpl;
  86. public:
  87. class RuleResolver {
  88. public:
  89. struct RuleKey {
  90. struct WildcardScheme : absl::monostate {};
  91. struct NoScheme : absl::monostate {};
  92. using Scheme = std::string;
  93. RuleKey();
  94. ~RuleKey();
  95. RuleKey(const RuleKey&);
  96. RuleKey& operator=(const RuleKey&);
  97. RuleKey(RuleKey&&);
  98. RuleKey& operator=(RuleKey&&);
  99. auto GetTuple() const {
  100. return std::tie(scheme, hostname_pattern, port, query_type,
  101. query_source);
  102. }
  103. bool operator<(const RuleKey& other) const {
  104. return GetTuple() < other.GetTuple();
  105. }
  106. // If `WildcardScheme`, scheme is wildcard and any query will match,
  107. // whether made with url::SchemeHostPort or HostPortPair. If `NoScheme`,
  108. // queries will only match if made using HostPortPair. Else, queries will
  109. // only match if made using url::SchemeHostPort with matching scheme
  110. // value.
  111. absl::variant<WildcardScheme, NoScheme, Scheme> scheme = WildcardScheme();
  112. // Pattern matched via `base::MatchPattern()`.
  113. std::string hostname_pattern = "*";
  114. // `nullopt` represents wildcard and all queries will match.
  115. absl::optional<uint16_t> port;
  116. absl::optional<DnsQueryType> query_type;
  117. absl::optional<HostResolverSource> query_source;
  118. };
  119. struct RuleResult {
  120. RuleResult();
  121. explicit RuleResult(
  122. std::vector<HostResolverEndpointResult> endpoints,
  123. std::set<std::string> aliases = std::set<std::string>());
  124. ~RuleResult();
  125. RuleResult(const RuleResult&);
  126. RuleResult& operator=(const RuleResult&);
  127. RuleResult(RuleResult&&);
  128. RuleResult& operator=(RuleResult&&);
  129. std::vector<HostResolverEndpointResult> endpoints;
  130. std::set<std::string> aliases;
  131. };
  132. using ErrorResult = Error;
  133. using RuleResultOrError = absl::variant<RuleResult, ErrorResult>;
  134. // If `default_result` is nullopt, every resolve must match an added rule.
  135. explicit RuleResolver(
  136. absl::optional<RuleResultOrError> default_result = absl::nullopt);
  137. ~RuleResolver();
  138. RuleResolver(const RuleResolver&);
  139. RuleResolver& operator=(const RuleResolver&);
  140. RuleResolver(RuleResolver&&);
  141. RuleResolver& operator=(RuleResolver&&);
  142. const RuleResultOrError& Resolve(const Host& request_endpoint,
  143. DnsQueryTypeSet request_types,
  144. HostResolverSource request_source) const;
  145. void ClearRules();
  146. static RuleResultOrError GetLocalhostResult();
  147. void AddRule(RuleKey key, RuleResultOrError result);
  148. void AddRule(RuleKey key, base::StringPiece ip_literal);
  149. void AddRule(base::StringPiece hostname_pattern, RuleResultOrError result);
  150. void AddRule(base::StringPiece hostname_pattern,
  151. base::StringPiece ip_literal);
  152. void AddRule(base::StringPiece hostname_pattern, Error error);
  153. // Legacy rule creation. Only for compatibility with tests written for use
  154. // with RuleBasedHostResolverProc. New code should use the AddRule() calls
  155. // above.
  156. void AddIPLiteralRule(base::StringPiece hostname_pattern,
  157. base::StringPiece ip_literal,
  158. base::StringPiece canonical_name);
  159. void AddIPLiteralRuleWithDnsAliases(base::StringPiece hostname_pattern,
  160. base::StringPiece ip_literal,
  161. std::vector<std::string> dns_aliases);
  162. void AddIPLiteralRuleWithDnsAliases(base::StringPiece hostname_pattern,
  163. base::StringPiece ip_literal,
  164. std::set<std::string> dns_aliases);
  165. void AddSimulatedFailure(base::StringPiece hostname_pattern);
  166. void AddSimulatedTimeoutFailure(base::StringPiece hostname_pattern);
  167. void AddRuleWithFlags(base::StringPiece host_pattern,
  168. base::StringPiece ip_literal,
  169. HostResolverFlags flags,
  170. std::vector<std::string> dns_aliases = {});
  171. private:
  172. std::map<RuleKey, RuleResultOrError> rules_;
  173. absl::optional<RuleResultOrError> default_result_;
  174. };
  175. using RequestMap = std::map<size_t, RequestImpl*>;
  176. // A set of states in MockHostResolver. This is used to observe the internal
  177. // state variables after destructing a MockHostResolver.
  178. class State : public base::RefCounted<State> {
  179. public:
  180. State();
  181. bool has_pending_requests() const { return !requests_.empty(); }
  182. bool IsDohProbeRunning() const { return !!doh_probe_request_; }
  183. size_t num_resolve() const { return num_resolve_; }
  184. size_t num_resolve_from_cache() const { return num_resolve_from_cache_; }
  185. size_t num_non_local_resolves() const { return num_non_local_resolves_; }
  186. RequestMap& mutable_requests() { return requests_; }
  187. void IncrementNumResolve() { ++num_resolve_; }
  188. void IncrementNumResolveFromCache() { ++num_resolve_from_cache_; }
  189. void IncrementNumNonLocalResolves() { ++num_non_local_resolves_; }
  190. void ClearDohProbeRequest() { doh_probe_request_ = nullptr; }
  191. void ClearDohProbeRequestIfMatching(ProbeRequestImpl* request) {
  192. if (request == doh_probe_request_) {
  193. doh_probe_request_ = nullptr;
  194. }
  195. }
  196. void set_doh_probe_request(ProbeRequestImpl* request) {
  197. DCHECK(request);
  198. DCHECK(!doh_probe_request_);
  199. doh_probe_request_ = request;
  200. }
  201. private:
  202. friend class RefCounted<State>;
  203. ~State();
  204. // Maintain non-owning pointers to outstanding requests and listeners to
  205. // allow completing/notifying them. The objects are owned by callers, and
  206. // should be removed from |this| on destruction by calling DetachRequest()
  207. // or RemoveCancelledListener().
  208. RequestMap requests_;
  209. raw_ptr<ProbeRequestImpl> doh_probe_request_ = nullptr;
  210. size_t num_resolve_ = 0;
  211. size_t num_resolve_from_cache_ = 0;
  212. size_t num_non_local_resolves_ = 0;
  213. };
  214. MockHostResolverBase(const MockHostResolverBase&) = delete;
  215. MockHostResolverBase& operator=(const MockHostResolverBase&) = delete;
  216. ~MockHostResolverBase() override;
  217. RuleResolver* rules() { return &rule_resolver_; }
  218. scoped_refptr<const State> state() const { return state_; }
  219. // Controls whether resolutions complete synchronously or asynchronously.
  220. void set_synchronous_mode(bool is_synchronous) {
  221. synchronous_mode_ = is_synchronous;
  222. }
  223. // Asynchronous requests are automatically resolved by default.
  224. // If set_ondemand_mode() is set then Resolve() returns IO_PENDING and
  225. // ResolveAllPending() must be explicitly invoked to resolve all requests
  226. // that are pending.
  227. void set_ondemand_mode(bool is_ondemand) {
  228. ondemand_mode_ = is_ondemand;
  229. }
  230. // HostResolver methods:
  231. void OnShutdown() override;
  232. std::unique_ptr<ResolveHostRequest> CreateRequest(
  233. url::SchemeHostPort host,
  234. NetworkIsolationKey network_isolation_key,
  235. NetLogWithSource net_log,
  236. absl::optional<ResolveHostParameters> optional_parameters) override;
  237. std::unique_ptr<ResolveHostRequest> CreateRequest(
  238. const HostPortPair& host,
  239. const NetworkIsolationKey& network_isolation_key,
  240. const NetLogWithSource& net_log,
  241. const absl::optional<ResolveHostParameters>& optional_parameters)
  242. override;
  243. std::unique_ptr<ProbeRequest> CreateDohProbeRequest() override;
  244. std::unique_ptr<MdnsListener> CreateMdnsListener(
  245. const HostPortPair& host,
  246. DnsQueryType query_type) override;
  247. HostCache* GetHostCache() override;
  248. void SetRequestContext(URLRequestContext* request_context) override {}
  249. // Preloads the cache with what would currently be the result of a request
  250. // with the given parameters. Returns the net error of the cached result.
  251. int LoadIntoCache(
  252. const Host& endpoint,
  253. const NetworkIsolationKey& network_isolation_key,
  254. const absl::optional<ResolveHostParameters>& optional_parameters);
  255. // Returns true if there are pending requests that can be resolved by invoking
  256. // ResolveAllPending().
  257. bool has_pending_requests() const { return state_->has_pending_requests(); }
  258. // Resolves all pending requests. It is only valid to invoke this if
  259. // set_ondemand_mode was set before. The requests are resolved asynchronously,
  260. // after this call returns.
  261. void ResolveAllPending();
  262. // Each request is assigned an ID when started and stored with the resolver
  263. // for async resolution, starting with 1. IDs are not reused. Once a request
  264. // completes, it is destroyed, and can no longer be accessed.
  265. // Returns the ID of the most recently started still-active request. Zero if
  266. // no requests are currently active.
  267. size_t last_id();
  268. // Resolve request stored in |requests_|. Pass rv to callback.
  269. void ResolveNow(size_t id);
  270. // Detach cancelled request.
  271. void DetachRequest(size_t id);
  272. // Returns the hostname of the request with the given id.
  273. base::StringPiece request_host(size_t id);
  274. // Returns the priority of the request with the given id.
  275. RequestPriority request_priority(size_t id);
  276. // Returns NetworkIsolationKey of the request with the given id.
  277. const NetworkIsolationKey& request_network_isolation_key(size_t id);
  278. // Like ResolveNow, but doesn't take an ID. DCHECKs if there's more than one
  279. // pending request.
  280. void ResolveOnlyRequestNow();
  281. // The number of times that Resolve() has been called.
  282. size_t num_resolve() const { return state_->num_resolve(); }
  283. // The number of times that ResolveFromCache() has been called.
  284. size_t num_resolve_from_cache() const {
  285. return state_->num_resolve_from_cache();
  286. }
  287. // The number of times resolve was attempted non-locally.
  288. size_t num_non_local_resolves() const {
  289. return state_->num_non_local_resolves();
  290. }
  291. // Returns the RequestPriority of the last call to Resolve() (or
  292. // DEFAULT_PRIORITY if Resolve() hasn't been called yet).
  293. RequestPriority last_request_priority() const {
  294. return last_request_priority_;
  295. }
  296. // Returns the NetworkIsolationKey passed in to the last call to Resolve() (or
  297. // absl::nullopt if Resolve() hasn't been called yet).
  298. const absl::optional<NetworkIsolationKey>&
  299. last_request_network_isolation_key() {
  300. return last_request_network_isolation_key_;
  301. }
  302. // Returns the SecureDnsPolicy of the last call to Resolve() (or
  303. // absl::nullopt if Resolve() hasn't been called yet).
  304. SecureDnsPolicy last_secure_dns_policy() const {
  305. return last_secure_dns_policy_;
  306. }
  307. bool IsDohProbeRunning() const { return state_->IsDohProbeRunning(); }
  308. void TriggerMdnsListeners(const HostPortPair& host,
  309. DnsQueryType query_type,
  310. MdnsListenerUpdateType update_type,
  311. const IPEndPoint& address_result);
  312. void TriggerMdnsListeners(const HostPortPair& host,
  313. DnsQueryType query_type,
  314. MdnsListenerUpdateType update_type,
  315. const std::vector<std::string>& text_result);
  316. void TriggerMdnsListeners(const HostPortPair& host,
  317. DnsQueryType query_type,
  318. MdnsListenerUpdateType update_type,
  319. const HostPortPair& host_result);
  320. void TriggerMdnsListeners(const HostPortPair& host,
  321. DnsQueryType query_type,
  322. MdnsListenerUpdateType update_type);
  323. void set_tick_clock(const base::TickClock* tick_clock) {
  324. tick_clock_ = tick_clock;
  325. }
  326. private:
  327. friend class MockHostResolver;
  328. friend class MockCachingHostResolver;
  329. friend class MockHostResolverFactory;
  330. // Returns the request with the given id.
  331. RequestImpl* request(size_t id);
  332. // If > 0, |cache_invalidation_num| is the number of times a cached entry can
  333. // be read before it invalidates itself. Useful to force cache expiration
  334. // scenarios.
  335. MockHostResolverBase(bool use_caching,
  336. int cache_invalidation_num,
  337. RuleResolver rule_resolver);
  338. // Handle resolution for |request|. Expected to be called only the RequestImpl
  339. // object itself.
  340. int Resolve(RequestImpl* request);
  341. // Resolve as IP or from |cache_| return cached error or
  342. // DNS_CACHE_MISS if failed.
  343. int ResolveFromIPLiteralOrCache(
  344. const Host& endpoint,
  345. const NetworkIsolationKey& network_isolation_key,
  346. DnsQueryType dns_query_type,
  347. HostResolverFlags flags,
  348. HostResolverSource source,
  349. HostResolver::ResolveHostParameters::CacheUsage cache_usage,
  350. std::vector<HostResolverEndpointResult>* out_endpoints,
  351. std::set<std::string>* out_aliases,
  352. absl::optional<HostCache::EntryStaleness>* out_stale_info);
  353. int DoSynchronousResolution(RequestImpl& request);
  354. void AddListener(MdnsListenerImpl* listener);
  355. void RemoveCancelledListener(MdnsListenerImpl* listener);
  356. RequestPriority last_request_priority_ = DEFAULT_PRIORITY;
  357. absl::optional<NetworkIsolationKey> last_request_network_isolation_key_;
  358. SecureDnsPolicy last_secure_dns_policy_ = SecureDnsPolicy::kAllow;
  359. bool synchronous_mode_ = false;
  360. bool ondemand_mode_ = false;
  361. RuleResolver rule_resolver_;
  362. std::unique_ptr<HostCache> cache_;
  363. const int initial_cache_invalidation_num_;
  364. std::map<HostCache::Key, int> cache_invalidation_nums_;
  365. std::set<MdnsListenerImpl*> listeners_;
  366. size_t next_request_id_ = 1;
  367. raw_ptr<const base::TickClock> tick_clock_;
  368. scoped_refptr<State> state_;
  369. THREAD_CHECKER(thread_checker_);
  370. };
  371. class MockHostResolver : public MockHostResolverBase {
  372. public:
  373. explicit MockHostResolver(absl::optional<RuleResolver::RuleResultOrError>
  374. default_result = absl::nullopt)
  375. : MockHostResolverBase(/*use_caching=*/false,
  376. /*cache_invalidation_num=*/0,
  377. RuleResolver(std::move(default_result))) {}
  378. ~MockHostResolver() override = default;
  379. };
  380. // Same as MockHostResolver, except internally it uses a host-cache.
  381. //
  382. // Note that tests are advised to use MockHostResolver instead, since it is
  383. // more predictable. (MockHostResolver also can be put into synchronous
  384. // operation mode in case that is what you needed from the caching version).
  385. class MockCachingHostResolver : public MockHostResolverBase {
  386. public:
  387. // If > 0, |cache_invalidation_num| is the number of times a cached entry can
  388. // be read before it invalidates itself. Useful to force cache expiration
  389. // scenarios.
  390. explicit MockCachingHostResolver(
  391. int cache_invalidation_num = 0,
  392. absl::optional<RuleResolver::RuleResultOrError> default_result =
  393. absl::nullopt)
  394. : MockHostResolverBase(/*use_caching=*/true,
  395. cache_invalidation_num,
  396. RuleResolver(std::move(default_result))) {}
  397. ~MockCachingHostResolver() override = default;
  398. };
  399. // Factory that will always create and return Mock(Caching)HostResolvers.
  400. //
  401. // The default behavior is to create a non-caching mock, even if the tested code
  402. // requests caching enabled (via the |enable_caching| parameter in the creation
  403. // methods). A caching mock will only be created if both |use_caching| is set on
  404. // factory construction and |enable_caching| is set in the creation method.
  405. class MockHostResolverFactory : public HostResolver::Factory {
  406. public:
  407. explicit MockHostResolverFactory(MockHostResolverBase::RuleResolver rules =
  408. MockHostResolverBase::RuleResolver(),
  409. bool use_caching = false,
  410. int cache_invalidation_num = 0);
  411. MockHostResolverFactory(const MockHostResolverFactory&) = delete;
  412. MockHostResolverFactory& operator=(const MockHostResolverFactory&) = delete;
  413. ~MockHostResolverFactory() override;
  414. std::unique_ptr<HostResolver> CreateResolver(
  415. HostResolverManager* manager,
  416. base::StringPiece host_mapping_rules,
  417. bool enable_caching) override;
  418. std::unique_ptr<HostResolver> CreateStandaloneResolver(
  419. NetLog* net_log,
  420. const HostResolver::ManagerOptions& options,
  421. base::StringPiece host_mapping_rules,
  422. bool enable_caching) override;
  423. private:
  424. const MockHostResolverBase::RuleResolver rules_;
  425. const bool use_caching_;
  426. const int cache_invalidation_num_;
  427. };
  428. // RuleBasedHostResolverProc applies a set of rules to map a host string to
  429. // a replacement host string. It then uses the system host resolver to return
  430. // a socket address. Generally the replacement should be an IPv4 literal so
  431. // there is no network dependency.
  432. //
  433. // RuleBasedHostResolverProc is thread-safe, to a limited degree. Rules can be
  434. // added or removed on any thread.
  435. class RuleBasedHostResolverProc : public HostResolverProc {
  436. public:
  437. // If `allow_fallback` is false, no Proc fallback is allowed except to
  438. // `previous`.
  439. explicit RuleBasedHostResolverProc(scoped_refptr<HostResolverProc> previous,
  440. bool allow_fallback = true);
  441. // Any hostname matching the given pattern will be replaced with the given
  442. // |ip_literal|.
  443. void AddRule(base::StringPiece host_pattern, base::StringPiece ip_literal);
  444. // Same as AddRule(), but further restricts to |address_family|.
  445. void AddRuleForAddressFamily(base::StringPiece host_pattern,
  446. AddressFamily address_family,
  447. base::StringPiece ip_literal);
  448. void AddRuleWithFlags(base::StringPiece host_pattern,
  449. base::StringPiece ip_literal,
  450. HostResolverFlags flags,
  451. std::vector<std::string> dns_aliases = {});
  452. // Same as AddRule(), but the replacement is expected to be an IPv4 or IPv6
  453. // literal. This can be used in place of AddRule() to bypass the system's
  454. // host resolver (the address list will be constructed manually).
  455. // If |canonical_name| is non-empty, it is copied to the resulting AddressList
  456. // but does not impact DNS resolution.
  457. // |ip_literal| can be a single IP address like "192.168.1.1" or a comma
  458. // separated list of IP addresses, like "::1,192:168.1.2".
  459. void AddIPLiteralRule(base::StringPiece host_pattern,
  460. base::StringPiece ip_literal,
  461. base::StringPiece canonical_name);
  462. // Same as AddIPLiteralRule, but with a parameter allowing multiple DNS
  463. // aliases, such as CNAME aliases, instead of only the canonical name. While
  464. // a simulation using HostResolverProc to obtain more than a single DNS alias
  465. // is currently unrealistic, this capability is useful for clients of
  466. // MockHostResolver who need to be able to obtain aliases and can be
  467. // agnostic about how the host resolution took place, as the alternative,
  468. // MockDnsClient, is not currently hooked up to MockHostResolver.
  469. void AddIPLiteralRuleWithDnsAliases(base::StringPiece host_pattern,
  470. base::StringPiece ip_literal,
  471. std::vector<std::string> dns_aliases);
  472. void AddRuleWithLatency(base::StringPiece host_pattern,
  473. base::StringPiece replacement,
  474. int latency_ms);
  475. // Make sure that |host| will not be re-mapped or even processed by underlying
  476. // host resolver procedures. It can also be a pattern.
  477. void AllowDirectLookup(base::StringPiece host);
  478. // Simulate a lookup failure for |host| (it also can be a pattern).
  479. void AddSimulatedFailure(
  480. base::StringPiece host,
  481. HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY);
  482. // Simulate a lookup timeout failure for |host| (it also can be a pattern).
  483. void AddSimulatedTimeoutFailure(
  484. base::StringPiece host,
  485. HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY);
  486. // Deletes all the rules that have been added.
  487. void ClearRules();
  488. // Causes method calls that add or delete rules to assert.
  489. // TODO(jam): once this class isn't used by tests that use an out of process
  490. // network service, remove this method and make Rule private.
  491. void DisableModifications();
  492. // HostResolverProc methods:
  493. int Resolve(const std::string& host,
  494. AddressFamily address_family,
  495. HostResolverFlags host_resolver_flags,
  496. AddressList* addrlist,
  497. int* os_error) override;
  498. struct Rule {
  499. // TODO(https://crbug.com/1298106) Deduplicate this enum's definition.
  500. enum ResolverType {
  501. kResolverTypeFail,
  502. kResolverTypeFailTimeout,
  503. // TODO(mmenke): Is it really reasonable for a "mock" host resolver to
  504. // fall back to the system resolver?
  505. kResolverTypeSystem,
  506. kResolverTypeIPLiteral,
  507. };
  508. Rule(ResolverType resolver_type,
  509. base::StringPiece host_pattern,
  510. AddressFamily address_family,
  511. HostResolverFlags host_resolver_flags,
  512. base::StringPiece replacement,
  513. std::vector<std::string> dns_aliases,
  514. int latency_ms);
  515. Rule(const Rule& other);
  516. ~Rule();
  517. ResolverType resolver_type;
  518. std::string host_pattern;
  519. AddressFamily address_family;
  520. HostResolverFlags host_resolver_flags;
  521. std::string replacement;
  522. std::vector<std::string> dns_aliases;
  523. int latency_ms; // In milliseconds.
  524. };
  525. typedef std::list<Rule> RuleList;
  526. RuleList GetRules();
  527. private:
  528. ~RuleBasedHostResolverProc() override;
  529. void AddRuleInternal(const Rule& rule);
  530. RuleList rules_;
  531. // Must be obtained before writing to or reading from |rules_|.
  532. base::Lock rule_lock_;
  533. // Whether changes are allowed.
  534. bool modifications_allowed_ = true;
  535. };
  536. // Create rules that map all requests to localhost.
  537. scoped_refptr<RuleBasedHostResolverProc> CreateCatchAllHostResolverProc();
  538. // HangingHostResolver never completes its |Resolve| request. As LOCAL_ONLY
  539. // requests are not allowed to complete asynchronously, they will always result
  540. // in |ERR_DNS_CACHE_MISS|.
  541. class HangingHostResolver : public HostResolver {
  542. public:
  543. // A set of states in HangingHostResolver. This is used to observe the
  544. // internal state variables after destructing a MockHostResolver.
  545. class State : public base::RefCounted<State> {
  546. public:
  547. State();
  548. int num_cancellations() const { return num_cancellations_; }
  549. void IncrementNumCancellations() { ++num_cancellations_; }
  550. private:
  551. friend class RefCounted<State>;
  552. ~State();
  553. int num_cancellations_ = 0;
  554. };
  555. HangingHostResolver();
  556. ~HangingHostResolver() override;
  557. void OnShutdown() override;
  558. std::unique_ptr<ResolveHostRequest> CreateRequest(
  559. url::SchemeHostPort host,
  560. NetworkIsolationKey network_isolation_key,
  561. NetLogWithSource net_log,
  562. absl::optional<ResolveHostParameters> optional_parameters) override;
  563. std::unique_ptr<ResolveHostRequest> CreateRequest(
  564. const HostPortPair& host,
  565. const NetworkIsolationKey& network_isolation_key,
  566. const NetLogWithSource& net_log,
  567. const absl::optional<ResolveHostParameters>& optional_parameters)
  568. override;
  569. std::unique_ptr<ProbeRequest> CreateDohProbeRequest() override;
  570. void SetRequestContext(URLRequestContext* url_request_context) override;
  571. // Use to detect cancellations since there's otherwise no externally-visible
  572. // differentiation between a cancelled and a hung task.
  573. int num_cancellations() const { return state_->num_cancellations(); }
  574. // Return the corresponding values passed to the most recent call to
  575. // CreateRequest()
  576. const HostPortPair& last_host() const { return last_host_; }
  577. const NetworkIsolationKey& last_network_isolation_key() const {
  578. return last_network_isolation_key_;
  579. }
  580. const scoped_refptr<const State> state() const { return state_; }
  581. private:
  582. class RequestImpl;
  583. class ProbeRequestImpl;
  584. HostPortPair last_host_;
  585. NetworkIsolationKey last_network_isolation_key_;
  586. scoped_refptr<State> state_;
  587. bool shutting_down_ = false;
  588. base::WeakPtrFactory<HangingHostResolver> weak_ptr_factory_{this};
  589. };
  590. // This class sets the default HostResolverProc for a particular scope. The
  591. // chain of resolver procs starting at |proc| is placed in front of any existing
  592. // default resolver proc(s). This means that if multiple
  593. // ScopedDefaultHostResolverProcs are declared, then resolving will start with
  594. // the procs given to the last-allocated one, then fall back to the procs given
  595. // to the previously-allocated one, and so forth.
  596. //
  597. // NOTE: Only use this as a catch-all safety net. Individual tests should use
  598. // MockHostResolver.
  599. class ScopedDefaultHostResolverProc {
  600. public:
  601. ScopedDefaultHostResolverProc();
  602. explicit ScopedDefaultHostResolverProc(HostResolverProc* proc);
  603. ~ScopedDefaultHostResolverProc();
  604. void Init(HostResolverProc* proc);
  605. private:
  606. scoped_refptr<HostResolverProc> current_proc_;
  607. scoped_refptr<HostResolverProc> previous_proc_;
  608. };
  609. } // namespace net
  610. #endif // NET_DNS_MOCK_HOST_RESOLVER_H_