1 // Copyright 2019 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/context_host_resolver.h"
6 
7 #include <utility>
8 
9 #include "base/bind.h"
10 #include "base/optional.h"
11 #include "base/run_loop.h"
12 #include "base/test/scoped_feature_list.h"
13 #include "base/test/simple_test_tick_clock.h"
14 #include "base/test/task_environment.h"
15 #include "base/time/time.h"
16 #include "net/base/features.h"
17 #include "net/base/host_port_pair.h"
18 #include "net/base/ip_address.h"
19 #include "net/base/ip_endpoint.h"
20 #include "net/base/net_errors.h"
21 #include "net/base/test_completion_callback.h"
22 #include "net/dns/dns_config.h"
23 #include "net/dns/dns_test_util.h"
24 #include "net/dns/dns_util.h"
25 #include "net/dns/host_cache.h"
26 #include "net/dns/host_resolver_manager.h"
27 #include "net/dns/host_resolver_source.h"
28 #include "net/dns/mock_host_resolver.h"
29 #include "net/dns/public/dns_protocol.h"
30 #include "net/dns/public/resolve_error_info.h"
31 #include "net/dns/resolve_context.h"
32 #include "net/log/net_log_with_source.h"
33 #include "net/test/gtest_util.h"
34 #include "net/test/test_with_task_environment.h"
35 #include "net/url_request/url_request_context.h"
36 #include "testing/gmock/include/gmock/gmock.h"
37 #include "testing/gtest/include/gtest/gtest.h"
38 #include "url/gurl.h"
39 #include "url/origin.h"
40 
41 namespace net {
42 
43 namespace {
44 const IPEndPoint kEndpoint(IPAddress(1, 2, 3, 4), 100);
45 }
46 
47 class ContextHostResolverTest : public ::testing::Test,
48                                 public WithTaskEnvironment {
49  protected:
50   // Use mock time to prevent the HostResolverManager's injected IPv6 probe
51   // result from timing out.
ContextHostResolverTest()52   ContextHostResolverTest()
53       : WithTaskEnvironment(
54             base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
55 
56   ~ContextHostResolverTest() override = default;
57 
SetUp()58   void SetUp() override {
59     manager_ = std::make_unique<HostResolverManager>(
60         HostResolver::ManagerOptions(),
61         nullptr /* system_dns_config_notifier */, nullptr /* net_log */);
62     manager_->SetLastIPv6ProbeResultForTesting(true);
63   }
64 
SetMockDnsRules(MockDnsClientRuleList rules)65   void SetMockDnsRules(MockDnsClientRuleList rules) {
66     IPAddress dns_ip(192, 168, 1, 0);
67     DnsConfig config;
68     config.nameservers.push_back(
69         IPEndPoint(dns_ip, dns_protocol::kDefaultPort));
70     config.dns_over_https_servers.emplace_back("example.com",
71                                                true /* use_post */);
72     EXPECT_TRUE(config.IsValid());
73 
74     auto dns_client =
75         std::make_unique<MockDnsClient>(std::move(config), std::move(rules));
76     dns_client->set_ignore_system_config_changes(true);
77     dns_client_ = dns_client.get();
78     manager_->SetDnsClientForTesting(std::move(dns_client));
79     manager_->SetInsecureDnsClientEnabled(true);
80 
81     // Ensure DnsClient is fully usable.
82     EXPECT_TRUE(dns_client_->CanUseInsecureDnsTransactions());
83     EXPECT_FALSE(dns_client_->FallbackFromInsecureTransactionPreferred());
84     EXPECT_TRUE(dns_client_->GetEffectiveConfig());
85 
86     scoped_refptr<HostResolverProc> proc = CreateCatchAllHostResolverProc();
87     manager_->set_proc_params_for_test(ProcTaskParams(proc.get(), 1u));
88   }
89 
90   MockDnsClient* dns_client_;
91   std::unique_ptr<HostResolverManager> manager_;
92 };
93 
TEST_F(ContextHostResolverTest,Resolve)94 TEST_F(ContextHostResolverTest, Resolve) {
95   URLRequestContext context;
96 
97   MockDnsClientRuleList rules;
98   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
99                      MockDnsClientRule::Result(BuildTestDnsResponse(
100                          "example.com", kEndpoint.address())),
101                      false /* delay */, &context);
102   rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */,
103                      MockDnsClientRule::Result(MockDnsClientRule::EMPTY),
104                      false /* delay */, &context);
105   SetMockDnsRules(std::move(rules));
106 
107   auto resolve_context =
108       std::make_unique<ResolveContext>(&context, false /* enable_caching */);
109   auto resolver = std::make_unique<ContextHostResolver>(
110       manager_.get(), std::move(resolve_context));
111   std::unique_ptr<HostResolver::ResolveHostRequest> request =
112       resolver->CreateRequest(HostPortPair("example.com", 100),
113                               NetworkIsolationKey(), NetLogWithSource(),
114                               base::nullopt);
115 
116   TestCompletionCallback callback;
117   int rv = request->Start(callback.callback());
118   EXPECT_THAT(callback.GetResult(rv), test::IsOk());
119   EXPECT_THAT(request->GetResolveErrorInfo().error, test::IsError(net::OK));
120   EXPECT_THAT(request->GetAddressResults().value().endpoints(),
121               testing::ElementsAre(kEndpoint));
122 }
123 
124 // Test that destroying a request silently cancels that request.
TEST_F(ContextHostResolverTest,DestroyRequest)125 TEST_F(ContextHostResolverTest, DestroyRequest) {
126   // Set up delayed results for "example.com".
127   MockDnsClientRuleList rules;
128   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
129                      MockDnsClientRule::Result(BuildTestDnsResponse(
130                          "example.com", IPAddress(1, 2, 3, 4))),
131                      true /* delay */);
132   rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */,
133                      MockDnsClientRule::Result(MockDnsClientRule::EMPTY),
134                      false /* delay */);
135   SetMockDnsRules(std::move(rules));
136 
137   auto resolver = std::make_unique<ContextHostResolver>(
138       manager_.get(),
139       std::make_unique<ResolveContext>(nullptr /* url_request_context */,
140                                        false /* enable_caching */));
141   std::unique_ptr<HostResolver::ResolveHostRequest> request =
142       resolver->CreateRequest(HostPortPair("example.com", 100),
143                               NetworkIsolationKey(), NetLogWithSource(),
144                               base::nullopt);
145   EXPECT_EQ(1u, resolver->GetNumActiveRequestsForTesting());
146 
147   TestCompletionCallback callback;
148   int rv = request->Start(callback.callback());
149 
150   // Cancel |request| before allowing delayed result to complete.
151   request = nullptr;
152   dns_client_->CompleteDelayedTransactions();
153 
154   // Ensure |request| never completes.
155   base::RunLoop().RunUntilIdle();
156   EXPECT_THAT(rv, test::IsError(ERR_IO_PENDING));
157   EXPECT_FALSE(callback.have_result());
158   EXPECT_EQ(0u, resolver->GetNumActiveRequestsForTesting());
159 }
160 
TEST_F(ContextHostResolverTest,DohProbeRequest)161 TEST_F(ContextHostResolverTest, DohProbeRequest) {
162   // Set empty MockDnsClient rules to ensure DnsClient is mocked out.
163   MockDnsClientRuleList rules;
164   SetMockDnsRules(std::move(rules));
165 
166   URLRequestContext context;
167   auto resolve_context =
168       std::make_unique<ResolveContext>(&context, true /* enable caching */);
169   auto resolver = std::make_unique<ContextHostResolver>(
170       manager_.get(), std::move(resolve_context));
171 
172   std::unique_ptr<HostResolver::ProbeRequest> request =
173       resolver->CreateDohProbeRequest();
174 
175   ASSERT_FALSE(dns_client_->factory()->doh_probes_running());
176 
177   EXPECT_THAT(request->Start(), test::IsError(ERR_IO_PENDING));
178   EXPECT_TRUE(dns_client_->factory()->doh_probes_running());
179 
180   request.reset();
181 
182   EXPECT_FALSE(dns_client_->factory()->doh_probes_running());
183 }
184 
TEST_F(ContextHostResolverTest,DohProbesFromSeparateContexts)185 TEST_F(ContextHostResolverTest, DohProbesFromSeparateContexts) {
186   // Set empty MockDnsClient rules to ensure DnsClient is mocked out.
187   MockDnsClientRuleList rules;
188   SetMockDnsRules(std::move(rules));
189 
190   auto resolve_context1 = std::make_unique<ResolveContext>(
191       nullptr /* url_request_context */, false /* enable_caching */);
192   auto resolver1 = std::make_unique<ContextHostResolver>(
193       manager_.get(), std::move(resolve_context1));
194   std::unique_ptr<HostResolver::ProbeRequest> request1 =
195       resolver1->CreateDohProbeRequest();
196 
197   auto resolve_context2 = std::make_unique<ResolveContext>(
198       nullptr /* url_request_context */, false /* enable_caching */);
199   auto resolver2 = std::make_unique<ContextHostResolver>(
200       manager_.get(), std::move(resolve_context2));
201   std::unique_ptr<HostResolver::ProbeRequest> request2 =
202       resolver2->CreateDohProbeRequest();
203 
204   EXPECT_FALSE(dns_client_->factory()->doh_probes_running());
205 
206   EXPECT_THAT(request1->Start(), test::IsError(ERR_IO_PENDING));
207   EXPECT_THAT(request2->Start(), test::IsError(ERR_IO_PENDING));
208 
209   EXPECT_TRUE(dns_client_->factory()->doh_probes_running());
210 
211   request1.reset();
212 
213   EXPECT_TRUE(dns_client_->factory()->doh_probes_running());
214 
215   request2.reset();
216 
217   EXPECT_FALSE(dns_client_->factory()->doh_probes_running());
218 }
219 
220 // Test that cancelling a resolver cancels its (and only its) requests.
TEST_F(ContextHostResolverTest,DestroyResolver)221 TEST_F(ContextHostResolverTest, DestroyResolver) {
222   // Set up delayed results for "example.com" and "google.com".
223   MockDnsClientRuleList rules;
224   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
225                      MockDnsClientRule::Result(BuildTestDnsResponse(
226                          "example.com", IPAddress(2, 3, 4, 5))),
227                      true /* delay */);
228   rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */,
229                      MockDnsClientRule::Result(MockDnsClientRule::EMPTY),
230                      false /* delay */);
231   rules.emplace_back("google.com", dns_protocol::kTypeA, false /* secure */,
232                      MockDnsClientRule::Result(BuildTestDnsResponse(
233                          "google.com", kEndpoint.address())),
234                      true /* delay */);
235   rules.emplace_back("google.com", dns_protocol::kTypeAAAA, false /* secure */,
236                      MockDnsClientRule::Result(MockDnsClientRule::EMPTY),
237                      false /* delay */);
238   SetMockDnsRules(std::move(rules));
239 
240   auto resolver1 = std::make_unique<ContextHostResolver>(
241       manager_.get(),
242       std::make_unique<ResolveContext>(nullptr /* url_request_context */,
243                                        false /* enable_caching */));
244   std::unique_ptr<HostResolver::ResolveHostRequest> request1 =
245       resolver1->CreateRequest(HostPortPair("example.com", 100),
246                                NetworkIsolationKey(), NetLogWithSource(),
247                                base::nullopt);
248   auto resolver2 = std::make_unique<ContextHostResolver>(
249       manager_.get(),
250       std::make_unique<ResolveContext>(nullptr /* url_request_context */,
251                                        false /* enable_caching */));
252   std::unique_ptr<HostResolver::ResolveHostRequest> request2 =
253       resolver2->CreateRequest(HostPortPair("google.com", 100),
254                                NetworkIsolationKey(), NetLogWithSource(),
255                                base::nullopt);
256 
257   TestCompletionCallback callback1;
258   int rv1 = request1->Start(callback1.callback());
259   TestCompletionCallback callback2;
260   int rv2 = request2->Start(callback2.callback());
261 
262   EXPECT_EQ(2u, manager_->num_jobs_for_testing());
263 
264   // Cancel |resolver1| before allowing delayed requests to complete.
265   resolver1 = nullptr;
266   dns_client_->CompleteDelayedTransactions();
267 
268   EXPECT_THAT(callback2.GetResult(rv2), test::IsOk());
269   EXPECT_THAT(request2->GetAddressResults().value().endpoints(),
270               testing::ElementsAre(kEndpoint));
271 
272   // Ensure |request1| never completes.
273   base::RunLoop().RunUntilIdle();
274   EXPECT_THAT(rv1, test::IsError(ERR_IO_PENDING));
275   EXPECT_FALSE(callback1.have_result());
276 }
277 
TEST_F(ContextHostResolverTest,DestroyResolver_CompletedRequests)278 TEST_F(ContextHostResolverTest, DestroyResolver_CompletedRequests) {
279   MockDnsClientRuleList rules;
280   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
281                      MockDnsClientRule::Result(BuildTestDnsResponse(
282                          "example.com", kEndpoint.address())),
283                      false /* delay */);
284   rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */,
285                      MockDnsClientRule::Result(MockDnsClientRule::EMPTY),
286                      false /* delay */);
287   SetMockDnsRules(std::move(rules));
288 
289   auto resolver = std::make_unique<ContextHostResolver>(
290       manager_.get(),
291       std::make_unique<ResolveContext>(nullptr /* url_request_context */,
292                                        false /* enable_caching */));
293   std::unique_ptr<HostResolver::ResolveHostRequest> request =
294       resolver->CreateRequest(HostPortPair("example.com", 100),
295                               NetworkIsolationKey(), NetLogWithSource(),
296                               base::nullopt);
297 
298   // Complete request and then destroy the resolver.
299   TestCompletionCallback callback;
300   int rv = request->Start(callback.callback());
301   ASSERT_THAT(callback.GetResult(rv), test::IsOk());
302   resolver = nullptr;
303 
304   // Expect completed results are still available.
305   EXPECT_THAT(request->GetResolveErrorInfo().error, test::IsError(net::OK));
306   EXPECT_THAT(request->GetAddressResults().value().endpoints(),
307               testing::ElementsAre(kEndpoint));
308 }
309 
TEST_F(ContextHostResolverTest,DestroyResolver_DohProbeRequest)310 TEST_F(ContextHostResolverTest, DestroyResolver_DohProbeRequest) {
311   // Set empty MockDnsClient rules to ensure DnsClient is mocked out.
312   MockDnsClientRuleList rules;
313   SetMockDnsRules(std::move(rules));
314 
315   URLRequestContext context;
316   auto resolve_context =
317       std::make_unique<ResolveContext>(&context, false /* enable_caching */);
318   auto resolver = std::make_unique<ContextHostResolver>(
319       manager_.get(), std::move(resolve_context));
320 
321   std::unique_ptr<HostResolver::ProbeRequest> request =
322       resolver->CreateDohProbeRequest();
323 
324   request->Start();
325   ASSERT_TRUE(dns_client_->factory()->doh_probes_running());
326 
327   resolver.reset();
328 
329   EXPECT_FALSE(dns_client_->factory()->doh_probes_running());
330 }
331 
332 // Test a request created before resolver destruction but not yet started.
TEST_F(ContextHostResolverTest,DestroyResolver_DelayedStartRequest)333 TEST_F(ContextHostResolverTest, DestroyResolver_DelayedStartRequest) {
334   // Set up delayed result for "example.com".
335   MockDnsClientRuleList rules;
336   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
337                      MockDnsClientRule::Result(BuildTestDnsResponse(
338                          "example.com", IPAddress(2, 3, 4, 5))),
339                      true /* delay */);
340   rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */,
341                      MockDnsClientRule::Result(MockDnsClientRule::EMPTY),
342                      false /* delay */);
343 
344   auto resolver = std::make_unique<ContextHostResolver>(
345       manager_.get(),
346       std::make_unique<ResolveContext>(nullptr /* url_request_context */,
347                                        false /* enable_caching */));
348   std::unique_ptr<HostResolver::ResolveHostRequest> request =
349       resolver->CreateRequest(HostPortPair("example.com", 100),
350                               NetworkIsolationKey(), NetLogWithSource(),
351                               base::nullopt);
352 
353   resolver = nullptr;
354 
355   TestCompletionCallback callback;
356   int rv = request->Start(callback.callback());
357 
358   EXPECT_THAT(callback.GetResult(rv), test::IsError(ERR_NAME_NOT_RESOLVED));
359   EXPECT_THAT(request->GetResolveErrorInfo().error, test::IsError(ERR_FAILED));
360   EXPECT_FALSE(request->GetAddressResults());
361 }
362 
TEST_F(ContextHostResolverTest,DestroyResolver_DelayedStartDohProbeRequest)363 TEST_F(ContextHostResolverTest, DestroyResolver_DelayedStartDohProbeRequest) {
364   // Set empty MockDnsClient rules to ensure DnsClient is mocked out.
365   MockDnsClientRuleList rules;
366   SetMockDnsRules(std::move(rules));
367 
368   URLRequestContext context;
369   auto resolve_context =
370       std::make_unique<ResolveContext>(&context, false /* enable_caching */);
371   auto resolver = std::make_unique<ContextHostResolver>(
372       manager_.get(), std::move(resolve_context));
373 
374   std::unique_ptr<HostResolver::ProbeRequest> request =
375       resolver->CreateDohProbeRequest();
376 
377   resolver = nullptr;
378 
379   EXPECT_THAT(request->Start(), test::IsError(ERR_FAILED));
380   EXPECT_FALSE(dns_client_->factory()->doh_probes_running());
381 }
382 
TEST_F(ContextHostResolverTest,OnShutdown_PendingRequest)383 TEST_F(ContextHostResolverTest, OnShutdown_PendingRequest) {
384   // Set up delayed result for "example.com".
385   MockDnsClientRuleList rules;
386   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
387                      MockDnsClientRule::Result(BuildTestDnsResponse(
388                          "example.com", IPAddress(2, 3, 4, 5))),
389                      true /* delay */);
390   rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */,
391                      MockDnsClientRule::Result(MockDnsClientRule::EMPTY),
392                      false /* delay */);
393   SetMockDnsRules(std::move(rules));
394 
395   URLRequestContext context;
396   auto resolve_context =
397       std::make_unique<ResolveContext>(&context, false /* enable_caching */);
398   auto resolver = std::make_unique<ContextHostResolver>(
399       manager_.get(), std::move(resolve_context));
400   std::unique_ptr<HostResolver::ResolveHostRequest> request =
401       resolver->CreateRequest(HostPortPair("example.com", 100),
402                               NetworkIsolationKey(), NetLogWithSource(),
403                               base::nullopt);
404 
405   TestCompletionCallback callback;
406   int rv = request->Start(callback.callback());
407 
408   // Trigger shutdown before allowing request to complete.
409   resolver->OnShutdown();
410   dns_client_->CompleteDelayedTransactions();
411 
412   // Ensure request never completes.
413   base::RunLoop().RunUntilIdle();
414   EXPECT_THAT(rv, test::IsError(ERR_IO_PENDING));
415   EXPECT_FALSE(callback.have_result());
416 }
417 
TEST_F(ContextHostResolverTest,OnShutdown_DohProbeRequest)418 TEST_F(ContextHostResolverTest, OnShutdown_DohProbeRequest) {
419   // Set empty MockDnsClient rules to ensure DnsClient is mocked out.
420   MockDnsClientRuleList rules;
421   SetMockDnsRules(std::move(rules));
422 
423   URLRequestContext context;
424   auto resolve_context =
425       std::make_unique<ResolveContext>(&context, false /* enable_caching */);
426   auto resolver = std::make_unique<ContextHostResolver>(
427       manager_.get(), std::move(resolve_context));
428 
429   std::unique_ptr<HostResolver::ProbeRequest> request =
430       resolver->CreateDohProbeRequest();
431 
432   request->Start();
433   ASSERT_TRUE(dns_client_->factory()->doh_probes_running());
434 
435   resolver->OnShutdown();
436 
437   EXPECT_FALSE(dns_client_->factory()->doh_probes_running());
438 }
439 
TEST_F(ContextHostResolverTest,OnShutdown_CompletedRequests)440 TEST_F(ContextHostResolverTest, OnShutdown_CompletedRequests) {
441   MockDnsClientRuleList rules;
442   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
443                      MockDnsClientRule::Result(BuildTestDnsResponse(
444                          "example.com", kEndpoint.address())),
445                      false /* delay */);
446   rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */,
447                      MockDnsClientRule::Result(MockDnsClientRule::EMPTY),
448                      false /* delay */);
449   SetMockDnsRules(std::move(rules));
450 
451   URLRequestContext context;
452   auto resolve_context =
453       std::make_unique<ResolveContext>(&context, false /* enable_caching */);
454   auto resolver = std::make_unique<ContextHostResolver>(
455       manager_.get(), std::move(resolve_context));
456   std::unique_ptr<HostResolver::ResolveHostRequest> request =
457       resolver->CreateRequest(HostPortPair("example.com", 100),
458                               NetworkIsolationKey(), NetLogWithSource(),
459                               base::nullopt);
460 
461   // Complete request and then shutdown the resolver.
462   TestCompletionCallback callback;
463   int rv = request->Start(callback.callback());
464   ASSERT_THAT(callback.GetResult(rv), test::IsOk());
465   resolver->OnShutdown();
466 
467   // Expect completed results are still available.
468   EXPECT_THAT(request->GetResolveErrorInfo().error, test::IsError(net::OK));
469   EXPECT_THAT(request->GetAddressResults().value().endpoints(),
470               testing::ElementsAre(kEndpoint));
471 }
472 
TEST_F(ContextHostResolverTest,OnShutdown_SubsequentRequests)473 TEST_F(ContextHostResolverTest, OnShutdown_SubsequentRequests) {
474   URLRequestContext context;
475   auto resolve_context =
476       std::make_unique<ResolveContext>(&context, false /* enable_caching */);
477   auto resolver = std::make_unique<ContextHostResolver>(
478       manager_.get(), std::move(resolve_context));
479   resolver->OnShutdown();
480 
481   std::unique_ptr<HostResolver::ResolveHostRequest> request1 =
482       resolver->CreateRequest(HostPortPair("example.com", 100),
483                               NetworkIsolationKey(), NetLogWithSource(),
484                               base::nullopt);
485   std::unique_ptr<HostResolver::ResolveHostRequest> request2 =
486       resolver->CreateRequest(HostPortPair("127.0.0.1", 100),
487                               NetworkIsolationKey(), NetLogWithSource(),
488                               base::nullopt);
489 
490   TestCompletionCallback callback1;
491   int rv1 = request1->Start(callback1.callback());
492   TestCompletionCallback callback2;
493   int rv2 = request2->Start(callback2.callback());
494 
495   EXPECT_THAT(callback1.GetResult(rv1), test::IsError(ERR_NAME_NOT_RESOLVED));
496   EXPECT_THAT(request1->GetResolveErrorInfo().error,
497               test::IsError(ERR_CONTEXT_SHUT_DOWN));
498   EXPECT_FALSE(request1->GetAddressResults());
499   EXPECT_THAT(callback2.GetResult(rv2), test::IsError(ERR_NAME_NOT_RESOLVED));
500   EXPECT_THAT(request2->GetResolveErrorInfo().error,
501               test::IsError(ERR_CONTEXT_SHUT_DOWN));
502   EXPECT_FALSE(request2->GetAddressResults());
503 }
504 
TEST_F(ContextHostResolverTest,OnShutdown_SubsequentDohProbeRequest)505 TEST_F(ContextHostResolverTest, OnShutdown_SubsequentDohProbeRequest) {
506   // Set empty MockDnsClient rules to ensure DnsClient is mocked out.
507   MockDnsClientRuleList rules;
508   SetMockDnsRules(std::move(rules));
509 
510   URLRequestContext context;
511   auto resolve_context =
512       std::make_unique<ResolveContext>(&context, false /* enable_caching */);
513   auto resolver = std::make_unique<ContextHostResolver>(
514       manager_.get(), std::move(resolve_context));
515   resolver->OnShutdown();
516 
517   std::unique_ptr<HostResolver::ProbeRequest> request =
518       resolver->CreateDohProbeRequest();
519 
520   EXPECT_THAT(request->Start(), test::IsError(ERR_CONTEXT_SHUT_DOWN));
521   EXPECT_FALSE(dns_client_->factory()->doh_probes_running());
522 }
523 
524 // Test a request created before shutdown but not yet started.
TEST_F(ContextHostResolverTest,OnShutdown_DelayedStartRequest)525 TEST_F(ContextHostResolverTest, OnShutdown_DelayedStartRequest) {
526   // Set up delayed result for "example.com".
527   MockDnsClientRuleList rules;
528   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
529                      MockDnsClientRule::Result(BuildTestDnsResponse(
530                          "example.com", IPAddress(2, 3, 4, 5))),
531                      true /* delay */);
532   rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */,
533                      MockDnsClientRule::Result(MockDnsClientRule::EMPTY),
534                      false /* delay */);
535 
536   URLRequestContext context;
537   auto resolve_context =
538       std::make_unique<ResolveContext>(&context, false /* enable_caching */);
539   auto resolver = std::make_unique<ContextHostResolver>(
540       manager_.get(), std::move(resolve_context));
541   std::unique_ptr<HostResolver::ResolveHostRequest> request =
542       resolver->CreateRequest(HostPortPair("example.com", 100),
543                               NetworkIsolationKey(), NetLogWithSource(),
544                               base::nullopt);
545 
546   resolver->OnShutdown();
547 
548   TestCompletionCallback callback;
549   int rv = request->Start(callback.callback());
550 
551   EXPECT_THAT(callback.GetResult(rv), test::IsError(ERR_NAME_NOT_RESOLVED));
552   EXPECT_THAT(request->GetResolveErrorInfo().error,
553               test::IsError(ERR_CONTEXT_SHUT_DOWN));
554   EXPECT_FALSE(request->GetAddressResults());
555 }
556 
TEST_F(ContextHostResolverTest,OnShutdown_DelayedStartDohProbeRequest)557 TEST_F(ContextHostResolverTest, OnShutdown_DelayedStartDohProbeRequest) {
558   // Set empty MockDnsClient rules to ensure DnsClient is mocked out.
559   MockDnsClientRuleList rules;
560   SetMockDnsRules(std::move(rules));
561 
562   URLRequestContext context;
563   auto resolve_context =
564       std::make_unique<ResolveContext>(&context, false /* enable_caching */);
565   auto resolver = std::make_unique<ContextHostResolver>(
566       manager_.get(), std::move(resolve_context));
567 
568   std::unique_ptr<HostResolver::ProbeRequest> request =
569       resolver->CreateDohProbeRequest();
570 
571   resolver->OnShutdown();
572 
573   EXPECT_THAT(request->Start(), test::IsError(ERR_CONTEXT_SHUT_DOWN));
574   EXPECT_FALSE(dns_client_->factory()->doh_probes_running());
575 }
576 
TEST_F(ContextHostResolverTest,ResolveFromCache)577 TEST_F(ContextHostResolverTest, ResolveFromCache) {
578   auto resolve_context = std::make_unique<ResolveContext>(
579       nullptr /* url_request_context */, true /* enable_caching */);
580   HostCache* host_cache = resolve_context->host_cache();
581   auto resolver = std::make_unique<ContextHostResolver>(
582       manager_.get(), std::move(resolve_context));
583 
584   // Create the cache entry after creating the ContextHostResolver, as
585   // registering into the HostResolverManager initializes and invalidates the
586   // cache.
587   base::SimpleTestTickClock clock;
588   clock.Advance(base::TimeDelta::FromDays(62));  // Arbitrary non-zero time.
589   AddressList expected(kEndpoint);
590   host_cache->Set(
591       HostCache::Key("example.com", DnsQueryType::UNSPECIFIED,
592                      0 /* host_resolver_flags */, HostResolverSource::ANY,
593                      NetworkIsolationKey()),
594       HostCache::Entry(OK, expected, HostCache::Entry::SOURCE_DNS,
595                        base::TimeDelta::FromDays(1)),
596       clock.NowTicks(), base::TimeDelta::FromDays(1));
597   resolver->SetTickClockForTesting(&clock);
598 
599   // Allow stale results and then confirm the result is not stale in order to
600   // make the issue more clear if something is invalidating the cache.
601   HostResolver::ResolveHostParameters parameters;
602   parameters.source = HostResolverSource::LOCAL_ONLY;
603   parameters.cache_usage =
604       HostResolver::ResolveHostParameters::CacheUsage::STALE_ALLOWED;
605   std::unique_ptr<HostResolver::ResolveHostRequest> request =
606       resolver->CreateRequest(HostPortPair("example.com", 100),
607                               NetworkIsolationKey(), NetLogWithSource(),
608                               parameters);
609 
610   TestCompletionCallback callback;
611   int rv = request->Start(callback.callback());
612   EXPECT_THAT(callback.GetResult(rv), test::IsOk());
613   EXPECT_THAT(request->GetResolveErrorInfo().error, test::IsError(net::OK));
614   EXPECT_THAT(request->GetAddressResults().value().endpoints(),
615               testing::ElementsAre(kEndpoint));
616   ASSERT_TRUE(request->GetStaleInfo());
617   EXPECT_EQ(0, request->GetStaleInfo().value().network_changes);
618   EXPECT_FALSE(request->GetStaleInfo().value().is_stale());
619 }
620 
TEST_F(ContextHostResolverTest,ResultsAddedToCache)621 TEST_F(ContextHostResolverTest, ResultsAddedToCache) {
622   MockDnsClientRuleList rules;
623   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
624                      MockDnsClientRule::Result(BuildTestDnsResponse(
625                          "example.com", kEndpoint.address())),
626                      false /* delay */);
627   rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */,
628                      MockDnsClientRule::Result(MockDnsClientRule::EMPTY),
629                      false /* delay */);
630   SetMockDnsRules(std::move(rules));
631 
632   auto resolve_context = std::make_unique<ResolveContext>(
633       nullptr /* url_request_context */, true /* enable_caching */);
634   auto resolver = std::make_unique<ContextHostResolver>(
635       manager_.get(), std::move(resolve_context));
636 
637   std::unique_ptr<HostResolver::ResolveHostRequest> caching_request =
638       resolver->CreateRequest(HostPortPair("example.com", 103),
639                               NetworkIsolationKey(), NetLogWithSource(),
640                               base::nullopt);
641   TestCompletionCallback caching_callback;
642   int rv = caching_request->Start(caching_callback.callback());
643   EXPECT_THAT(caching_callback.GetResult(rv), test::IsOk());
644 
645   HostResolver::ResolveHostParameters local_resolve_parameters;
646   local_resolve_parameters.source = HostResolverSource::LOCAL_ONLY;
647   std::unique_ptr<HostResolver::ResolveHostRequest> cached_request =
648       resolver->CreateRequest(HostPortPair("example.com", 100),
649                               NetworkIsolationKey(), NetLogWithSource(),
650                               local_resolve_parameters);
651 
652   TestCompletionCallback callback;
653   rv = cached_request->Start(callback.callback());
654   EXPECT_THAT(callback.GetResult(rv), test::IsOk());
655   EXPECT_THAT(cached_request->GetResolveErrorInfo().error,
656               test::IsError(net::OK));
657   EXPECT_THAT(cached_request->GetAddressResults().value().endpoints(),
658               testing::ElementsAre(kEndpoint));
659 }
660 
661 // Do a lookup with a NetworkIsolationKey, and then make sure the entry added to
662 // the cache is in fact using that NetworkIsolationKey.
TEST_F(ContextHostResolverTest,ResultsAddedToCacheWithNetworkIsolationKey)663 TEST_F(ContextHostResolverTest, ResultsAddedToCacheWithNetworkIsolationKey) {
664   const url::Origin kOrigin = url::Origin::Create(GURL("https://origin.test/"));
665   const NetworkIsolationKey kNetworkIsolationKey(kOrigin, kOrigin);
666 
667   base::test::ScopedFeatureList feature_list;
668   feature_list.InitAndEnableFeature(
669       features::kSplitHostCacheByNetworkIsolationKey);
670 
671   MockDnsClientRuleList rules;
672   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
673                      MockDnsClientRule::Result(BuildTestDnsResponse(
674                          "example.com", kEndpoint.address())),
675                      false /* delay */);
676   rules.emplace_back("example.com", dns_protocol::kTypeAAAA, false /* secure */,
677                      MockDnsClientRule::Result(MockDnsClientRule::EMPTY),
678                      false /* delay */);
679   SetMockDnsRules(std::move(rules));
680 
681   auto resolve_context = std::make_unique<ResolveContext>(
682       nullptr /* url_request_context */, true /* enable_caching */);
683   auto resolver = std::make_unique<ContextHostResolver>(
684       manager_.get(), std::move(resolve_context));
685 
686   std::unique_ptr<HostResolver::ResolveHostRequest> caching_request =
687       resolver->CreateRequest(HostPortPair("example.com", 103),
688                               kNetworkIsolationKey, NetLogWithSource(),
689                               base::nullopt);
690   TestCompletionCallback caching_callback;
691   int rv = caching_request->Start(caching_callback.callback());
692   EXPECT_THAT(caching_callback.GetResult(rv), test::IsOk());
693 
694   HostCache::Key cache_key("example.com", DnsQueryType::UNSPECIFIED,
695                            0 /* host_resolver_flags */, HostResolverSource::ANY,
696                            kNetworkIsolationKey);
697   EXPECT_TRUE(
698       resolver->GetHostCache()->Lookup(cache_key, base::TimeTicks::Now()));
699 
700   HostCache::Key cache_key_with_empty_nik(
701       "example.com", DnsQueryType::UNSPECIFIED, 0 /* host_resolver_flags */,
702       HostResolverSource::ANY, NetworkIsolationKey());
703   EXPECT_FALSE(resolver->GetHostCache()->Lookup(cache_key_with_empty_nik,
704                                                 base::TimeTicks::Now()));
705 }
706 
707 // Test that the underlying HostCache can receive invalidations from the manager
708 // and that it safely does not receive invalidations after the resolver (and the
709 // HostCache) is destroyed.
TEST_F(ContextHostResolverTest,HostCacheInvalidation)710 TEST_F(ContextHostResolverTest, HostCacheInvalidation) {
711   // Set empty MockDnsClient rules to ensure DnsClient is mocked out.
712   MockDnsClientRuleList rules;
713   SetMockDnsRules(std::move(rules));
714 
715   auto resolve_context = std::make_unique<ResolveContext>(
716       nullptr /* url_request_context */, true /* enable_caching */);
717   ResolveContext* resolve_context_ptr = resolve_context.get();
718   auto resolver = std::make_unique<ContextHostResolver>(
719       manager_.get(), std::move(resolve_context));
720 
721   // No invalidations yet (other than the initialization "invalidation" from
722   // registering the context).
723   ASSERT_EQ(resolve_context_ptr->current_session_for_testing(),
724             dns_client_->GetCurrentSession());
725   ASSERT_EQ(resolve_context_ptr->host_cache()->network_changes(), 1);
726 
727   manager_->InvalidateCachesForTesting();
728   EXPECT_EQ(resolve_context_ptr->current_session_for_testing(),
729             dns_client_->GetCurrentSession());
730   EXPECT_EQ(resolve_context_ptr->host_cache()->network_changes(), 2);
731 
732   // Expect manager to be able to safely do invalidations after an individual
733   // ContextHostResolver has been destroyed (and deregisters its ResolveContext)
734   resolver = nullptr;
735   manager_->InvalidateCachesForTesting();
736 }
737 
738 }  // namespace net
739