• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Chromium Authors
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 <memory>
8 #include <utility>
9 
10 #include "base/containers/fixed_flat_map.h"
11 #include "base/functional/bind.h"
12 #include "base/memory/raw_ptr.h"
13 #include "base/run_loop.h"
14 #include "base/test/scoped_feature_list.h"
15 #include "base/test/simple_test_tick_clock.h"
16 #include "base/test/task_environment.h"
17 #include "base/time/time.h"
18 #include "net/base/features.h"
19 #include "net/base/host_port_pair.h"
20 #include "net/base/ip_address.h"
21 #include "net/base/ip_endpoint.h"
22 #include "net/base/mock_network_change_notifier.h"
23 #include "net/base/net_errors.h"
24 #include "net/base/network_isolation_key.h"
25 #include "net/base/schemeful_site.h"
26 #include "net/base/test_completion_callback.h"
27 #include "net/dns/dns_config.h"
28 #include "net/dns/dns_test_util.h"
29 #include "net/dns/dns_util.h"
30 #include "net/dns/host_cache.h"
31 #include "net/dns/host_resolver.h"
32 #include "net/dns/host_resolver_manager.h"
33 #include "net/dns/host_resolver_system_task.h"
34 #include "net/dns/mock_host_resolver.h"
35 #include "net/dns/public/dns_over_https_config.h"
36 #include "net/dns/public/dns_protocol.h"
37 #include "net/dns/public/host_resolver_source.h"
38 #include "net/dns/public/resolve_error_info.h"
39 #include "net/dns/resolve_context.h"
40 #include "net/log/net_log_with_source.h"
41 #include "net/test/gtest_util.h"
42 #include "net/test/test_with_task_environment.h"
43 #include "net/url_request/url_request_context.h"
44 #include "net/url_request/url_request_context_builder.h"
45 #include "net/url_request/url_request_test_util.h"
46 #include "testing/gmock/include/gmock/gmock.h"
47 #include "testing/gtest/include/gtest/gtest.h"
48 #include "third_party/abseil-cpp/absl/types/optional.h"
49 #include "url/gurl.h"
50 #include "url/scheme_host_port.h"
51 
52 #if BUILDFLAG(IS_ANDROID)
53 #include "base/android/build_info.h"
54 #include "net/android/network_change_notifier_factory_android.h"
55 #endif  // BUILDFLAG(IS_ANDROID)
56 
57 namespace net {
58 
59 namespace {
60 const IPEndPoint kEndpoint(IPAddress(1, 2, 3, 4), 100);
61 }
62 
63 class ContextHostResolverTest : public ::testing::Test,
64                                 public WithTaskEnvironment {
65  protected:
66   // Use mock time to prevent the HostResolverManager's injected IPv6 probe
67   // result from timing out.
ContextHostResolverTest()68   ContextHostResolverTest()
69       : WithTaskEnvironment(
70             base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
71 
72   ~ContextHostResolverTest() override = default;
73 
SetUp()74   void SetUp() override {
75     manager_ = std::make_unique<HostResolverManager>(
76         HostResolver::ManagerOptions(),
77         nullptr /* system_dns_config_notifier */, nullptr /* net_log */);
78     manager_->SetLastIPv6ProbeResultForTesting(true);
79   }
80 
SetMockDnsRules(MockDnsClientRuleList rules)81   void SetMockDnsRules(MockDnsClientRuleList rules) {
82     IPAddress dns_ip(192, 168, 1, 0);
83     DnsConfig config;
84     config.nameservers.emplace_back(dns_ip, dns_protocol::kDefaultPort);
85     config.doh_config = *DnsOverHttpsConfig::FromString("https://example.com");
86     EXPECT_TRUE(config.IsValid());
87 
88     auto dns_client =
89         std::make_unique<MockDnsClient>(std::move(config), std::move(rules));
90     dns_client->set_ignore_system_config_changes(true);
91     dns_client_ = dns_client.get();
92     manager_->SetDnsClientForTesting(std::move(dns_client));
93     manager_->SetInsecureDnsClientEnabled(
94         /*enabled=*/true,
95         /*additional_dns_types_enabled=*/true);
96 
97     // Ensure DnsClient is fully usable.
98     EXPECT_TRUE(dns_client_->CanUseInsecureDnsTransactions());
99     EXPECT_FALSE(dns_client_->FallbackFromInsecureTransactionPreferred());
100     EXPECT_TRUE(dns_client_->GetEffectiveConfig());
101 
102     scoped_refptr<HostResolverProc> proc = CreateCatchAllHostResolverProc();
103     manager_->set_host_resolver_system_params_for_test(
104         HostResolverSystemTask::Params(proc, 1u));
105   }
106 
107   raw_ptr<MockDnsClient, DanglingUntriaged> dns_client_;
108   std::unique_ptr<HostResolverManager> manager_;
109 };
110 
TEST_F(ContextHostResolverTest,Resolve)111 TEST_F(ContextHostResolverTest, Resolve) {
112   auto context = CreateTestURLRequestContextBuilder()->Build();
113 
114   MockDnsClientRuleList rules;
115   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
116                      MockDnsClientRule::Result(BuildTestDnsAddressResponse(
117                          "example.com", kEndpoint.address())),
118                      false /* delay */, context.get());
119   rules.emplace_back(
120       "example.com", dns_protocol::kTypeAAAA, false /* secure */,
121       MockDnsClientRule::Result(MockDnsClientRule::ResultType::kEmpty),
122       false /* delay */, context.get());
123   SetMockDnsRules(std::move(rules));
124 
125   auto resolve_context = std::make_unique<ResolveContext>(
126       context.get(), false /* enable_caching */);
127   auto resolver = std::make_unique<ContextHostResolver>(
128       manager_.get(), std::move(resolve_context));
129   std::unique_ptr<HostResolver::ResolveHostRequest> request =
130       resolver->CreateRequest(HostPortPair("example.com", 100),
131                               NetworkAnonymizationKey(), NetLogWithSource(),
132                               absl::nullopt);
133 
134   TestCompletionCallback callback;
135   int rv = request->Start(callback.callback());
136   EXPECT_THAT(callback.GetResult(rv), test::IsOk());
137   EXPECT_THAT(request->GetResolveErrorInfo().error, test::IsError(net::OK));
138   EXPECT_THAT(request->GetAddressResults()->endpoints(),
139               testing::ElementsAre(kEndpoint));
140 }
141 
TEST_F(ContextHostResolverTest,ResolveWithScheme)142 TEST_F(ContextHostResolverTest, ResolveWithScheme) {
143   auto context = CreateTestURLRequestContextBuilder()->Build();
144 
145   MockDnsClientRuleList rules;
146   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
147                      MockDnsClientRule::Result(BuildTestDnsAddressResponse(
148                          "example.com", kEndpoint.address())),
149                      false /* delay */, context.get());
150   rules.emplace_back(
151       "example.com", dns_protocol::kTypeAAAA, false /* secure */,
152       MockDnsClientRule::Result(MockDnsClientRule::ResultType::kEmpty),
153       false /* delay */, context.get());
154   SetMockDnsRules(std::move(rules));
155 
156   auto resolve_context = std::make_unique<ResolveContext>(
157       context.get(), false /* enable_caching */);
158   auto resolver = std::make_unique<ContextHostResolver>(
159       manager_.get(), std::move(resolve_context));
160   std::unique_ptr<HostResolver::ResolveHostRequest> request =
161       resolver->CreateRequest(
162           url::SchemeHostPort(url::kHttpsScheme, "example.com", 100),
163           NetworkAnonymizationKey(), NetLogWithSource(), absl::nullopt);
164 
165   TestCompletionCallback callback;
166   int rv = request->Start(callback.callback());
167   EXPECT_THAT(callback.GetResult(rv), test::IsOk());
168   EXPECT_THAT(request->GetResolveErrorInfo().error, test::IsError(net::OK));
169   EXPECT_THAT(request->GetAddressResults()->endpoints(),
170               testing::ElementsAre(kEndpoint));
171 }
172 
TEST_F(ContextHostResolverTest,ResolveWithSchemeAndIpLiteral)173 TEST_F(ContextHostResolverTest, ResolveWithSchemeAndIpLiteral) {
174   auto context = CreateTestURLRequestContextBuilder()->Build();
175 
176   IPAddress expected_address;
177   ASSERT_TRUE(expected_address.AssignFromIPLiteral("1234::5678"));
178 
179   auto resolve_context = std::make_unique<ResolveContext>(
180       context.get(), false /* enable_caching */);
181   auto resolver = std::make_unique<ContextHostResolver>(
182       manager_.get(), std::move(resolve_context));
183   std::unique_ptr<HostResolver::ResolveHostRequest> request =
184       resolver->CreateRequest(
185           url::SchemeHostPort(url::kHttpsScheme, "[1234::5678]", 100),
186           NetworkAnonymizationKey(), NetLogWithSource(), absl::nullopt);
187 
188   TestCompletionCallback callback;
189   int rv = request->Start(callback.callback());
190   EXPECT_THAT(callback.GetResult(rv), test::IsOk());
191   EXPECT_THAT(request->GetResolveErrorInfo().error, test::IsError(net::OK));
192   EXPECT_THAT(request->GetAddressResults()->endpoints(),
193               testing::ElementsAre(IPEndPoint(expected_address, 100)));
194 }
195 
196 // Test that destroying a request silently cancels that request.
TEST_F(ContextHostResolverTest,DestroyRequest)197 TEST_F(ContextHostResolverTest, DestroyRequest) {
198   // Set up delayed results for "example.com".
199   MockDnsClientRuleList rules;
200   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
201                      MockDnsClientRule::Result(BuildTestDnsAddressResponse(
202                          "example.com", IPAddress(1, 2, 3, 4))),
203                      true /* delay */);
204   rules.emplace_back(
205       "example.com", dns_protocol::kTypeAAAA, false /* secure */,
206       MockDnsClientRule::Result(MockDnsClientRule::ResultType::kEmpty),
207       false /* delay */);
208   SetMockDnsRules(std::move(rules));
209 
210   auto resolver = std::make_unique<ContextHostResolver>(
211       manager_.get(),
212       std::make_unique<ResolveContext>(nullptr /* url_request_context */,
213                                        false /* enable_caching */));
214   std::unique_ptr<HostResolver::ResolveHostRequest> request =
215       resolver->CreateRequest(HostPortPair("example.com", 100),
216                               NetworkAnonymizationKey(), NetLogWithSource(),
217                               absl::nullopt);
218 
219   TestCompletionCallback callback;
220   int rv = request->Start(callback.callback());
221 
222   // Cancel |request| before allowing delayed result to complete.
223   request = nullptr;
224   dns_client_->CompleteDelayedTransactions();
225 
226   // Ensure |request| never completes.
227   base::RunLoop().RunUntilIdle();
228   EXPECT_THAT(rv, test::IsError(ERR_IO_PENDING));
229   EXPECT_FALSE(callback.have_result());
230 }
231 
TEST_F(ContextHostResolverTest,DohProbeRequest)232 TEST_F(ContextHostResolverTest, DohProbeRequest) {
233   // Set empty MockDnsClient rules to ensure DnsClient is mocked out.
234   MockDnsClientRuleList rules;
235   SetMockDnsRules(std::move(rules));
236 
237   auto context = CreateTestURLRequestContextBuilder()->Build();
238   auto resolve_context = std::make_unique<ResolveContext>(
239       context.get(), true /* enable caching */);
240   auto resolver = std::make_unique<ContextHostResolver>(
241       manager_.get(), std::move(resolve_context));
242 
243   std::unique_ptr<HostResolver::ProbeRequest> request =
244       resolver->CreateDohProbeRequest();
245 
246   ASSERT_FALSE(dns_client_->factory()->doh_probes_running());
247 
248   EXPECT_THAT(request->Start(), test::IsError(ERR_IO_PENDING));
249   EXPECT_TRUE(dns_client_->factory()->doh_probes_running());
250 
251   request.reset();
252 
253   EXPECT_FALSE(dns_client_->factory()->doh_probes_running());
254 }
255 
TEST_F(ContextHostResolverTest,DohProbesFromSeparateContexts)256 TEST_F(ContextHostResolverTest, DohProbesFromSeparateContexts) {
257   // Set empty MockDnsClient rules to ensure DnsClient is mocked out.
258   MockDnsClientRuleList rules;
259   SetMockDnsRules(std::move(rules));
260 
261   auto resolve_context1 = std::make_unique<ResolveContext>(
262       nullptr /* url_request_context */, false /* enable_caching */);
263   auto resolver1 = std::make_unique<ContextHostResolver>(
264       manager_.get(), std::move(resolve_context1));
265   std::unique_ptr<HostResolver::ProbeRequest> request1 =
266       resolver1->CreateDohProbeRequest();
267 
268   auto resolve_context2 = std::make_unique<ResolveContext>(
269       nullptr /* url_request_context */, false /* enable_caching */);
270   auto resolver2 = std::make_unique<ContextHostResolver>(
271       manager_.get(), std::move(resolve_context2));
272   std::unique_ptr<HostResolver::ProbeRequest> request2 =
273       resolver2->CreateDohProbeRequest();
274 
275   EXPECT_FALSE(dns_client_->factory()->doh_probes_running());
276 
277   EXPECT_THAT(request1->Start(), test::IsError(ERR_IO_PENDING));
278   EXPECT_THAT(request2->Start(), test::IsError(ERR_IO_PENDING));
279 
280   EXPECT_TRUE(dns_client_->factory()->doh_probes_running());
281 
282   request1.reset();
283 
284   EXPECT_TRUE(dns_client_->factory()->doh_probes_running());
285 
286   request2.reset();
287 
288   EXPECT_FALSE(dns_client_->factory()->doh_probes_running());
289 }
290 
291 // Test that cancelling a resolver cancels its (and only its) requests.
TEST_F(ContextHostResolverTest,DestroyResolver)292 TEST_F(ContextHostResolverTest, DestroyResolver) {
293   // Set up delayed results for "example.com" and "google.com".
294   MockDnsClientRuleList rules;
295   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
296                      MockDnsClientRule::Result(BuildTestDnsAddressResponse(
297                          "example.com", IPAddress(2, 3, 4, 5))),
298                      true /* delay */);
299   rules.emplace_back(
300       "example.com", dns_protocol::kTypeAAAA, false /* secure */,
301       MockDnsClientRule::Result(MockDnsClientRule::ResultType::kEmpty),
302       false /* delay */);
303   rules.emplace_back("google.com", dns_protocol::kTypeA, false /* secure */,
304                      MockDnsClientRule::Result(BuildTestDnsAddressResponse(
305                          "google.com", kEndpoint.address())),
306                      true /* delay */);
307   rules.emplace_back(
308       "google.com", dns_protocol::kTypeAAAA, false /* secure */,
309       MockDnsClientRule::Result(MockDnsClientRule::ResultType::kEmpty),
310       false /* delay */);
311   SetMockDnsRules(std::move(rules));
312 
313   auto resolver1 = std::make_unique<ContextHostResolver>(
314       manager_.get(),
315       std::make_unique<ResolveContext>(nullptr /* url_request_context */,
316                                        false /* enable_caching */));
317   std::unique_ptr<HostResolver::ResolveHostRequest> request1 =
318       resolver1->CreateRequest(HostPortPair("example.com", 100),
319                                NetworkAnonymizationKey(), NetLogWithSource(),
320                                absl::nullopt);
321   auto resolver2 = std::make_unique<ContextHostResolver>(
322       manager_.get(),
323       std::make_unique<ResolveContext>(nullptr /* url_request_context */,
324                                        false /* enable_caching */));
325   std::unique_ptr<HostResolver::ResolveHostRequest> request2 =
326       resolver2->CreateRequest(HostPortPair("google.com", 100),
327                                NetworkAnonymizationKey(), NetLogWithSource(),
328                                absl::nullopt);
329 
330   TestCompletionCallback callback1;
331   int rv1 = request1->Start(callback1.callback());
332   TestCompletionCallback callback2;
333   int rv2 = request2->Start(callback2.callback());
334 
335   EXPECT_EQ(2u, manager_->num_jobs_for_testing());
336 
337   // Cancel |resolver1| before allowing delayed requests to complete.
338   resolver1 = nullptr;
339   dns_client_->CompleteDelayedTransactions();
340 
341   EXPECT_THAT(callback2.GetResult(rv2), test::IsOk());
342   EXPECT_THAT(request2->GetAddressResults()->endpoints(),
343               testing::ElementsAre(kEndpoint));
344 
345   // Ensure |request1| never completes.
346   base::RunLoop().RunUntilIdle();
347   EXPECT_THAT(rv1, test::IsError(ERR_IO_PENDING));
348   EXPECT_FALSE(callback1.have_result());
349 }
350 
TEST_F(ContextHostResolverTest,DestroyResolver_CompletedRequests)351 TEST_F(ContextHostResolverTest, DestroyResolver_CompletedRequests) {
352   MockDnsClientRuleList rules;
353   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
354                      MockDnsClientRule::Result(BuildTestDnsAddressResponse(
355                          "example.com", kEndpoint.address())),
356                      false /* delay */);
357   rules.emplace_back(
358       "example.com", dns_protocol::kTypeAAAA, false /* secure */,
359       MockDnsClientRule::Result(MockDnsClientRule::ResultType::kEmpty),
360       false /* delay */);
361   SetMockDnsRules(std::move(rules));
362 
363   auto resolver = std::make_unique<ContextHostResolver>(
364       manager_.get(),
365       std::make_unique<ResolveContext>(nullptr /* url_request_context */,
366                                        false /* enable_caching */));
367   std::unique_ptr<HostResolver::ResolveHostRequest> request =
368       resolver->CreateRequest(HostPortPair("example.com", 100),
369                               NetworkAnonymizationKey(), NetLogWithSource(),
370                               absl::nullopt);
371 
372   // Complete request and then destroy the resolver.
373   TestCompletionCallback callback;
374   int rv = request->Start(callback.callback());
375   ASSERT_THAT(callback.GetResult(rv), test::IsOk());
376   resolver = nullptr;
377 
378   // Expect completed results are still available.
379   EXPECT_THAT(request->GetResolveErrorInfo().error, test::IsError(net::OK));
380   EXPECT_THAT(request->GetAddressResults()->endpoints(),
381               testing::ElementsAre(kEndpoint));
382 }
383 
384 // Test a request created before resolver destruction but not yet started.
TEST_F(ContextHostResolverTest,DestroyResolver_DelayedStartRequest)385 TEST_F(ContextHostResolverTest, DestroyResolver_DelayedStartRequest) {
386   // Set up delayed result for "example.com".
387   MockDnsClientRuleList rules;
388   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
389                      MockDnsClientRule::Result(BuildTestDnsAddressResponse(
390                          "example.com", IPAddress(2, 3, 4, 5))),
391                      true /* delay */);
392   rules.emplace_back(
393       "example.com", dns_protocol::kTypeAAAA, false /* secure */,
394       MockDnsClientRule::Result(MockDnsClientRule::ResultType::kEmpty),
395       false /* delay */);
396 
397   auto resolver = std::make_unique<ContextHostResolver>(
398       manager_.get(),
399       std::make_unique<ResolveContext>(nullptr /* url_request_context */,
400                                        false /* enable_caching */));
401   std::unique_ptr<HostResolver::ResolveHostRequest> request =
402       resolver->CreateRequest(HostPortPair("example.com", 100),
403                               NetworkAnonymizationKey(), NetLogWithSource(),
404                               absl::nullopt);
405 
406   resolver = nullptr;
407 
408   TestCompletionCallback callback;
409   int rv = request->Start(callback.callback());
410 
411   EXPECT_THAT(callback.GetResult(rv), test::IsError(ERR_NAME_NOT_RESOLVED));
412   EXPECT_THAT(request->GetResolveErrorInfo().error,
413               test::IsError(ERR_CONTEXT_SHUT_DOWN));
414   EXPECT_FALSE(request->GetAddressResults());
415 }
416 
TEST_F(ContextHostResolverTest,DestroyResolver_DelayedStartDohProbeRequest)417 TEST_F(ContextHostResolverTest, DestroyResolver_DelayedStartDohProbeRequest) {
418   // Set empty MockDnsClient rules to ensure DnsClient is mocked out.
419   MockDnsClientRuleList rules;
420   SetMockDnsRules(std::move(rules));
421 
422   auto context = CreateTestURLRequestContextBuilder()->Build();
423   auto resolve_context = std::make_unique<ResolveContext>(
424       context.get(), false /* enable_caching */);
425   auto resolver = std::make_unique<ContextHostResolver>(
426       manager_.get(), std::move(resolve_context));
427 
428   std::unique_ptr<HostResolver::ProbeRequest> request =
429       resolver->CreateDohProbeRequest();
430 
431   resolver = nullptr;
432 
433   EXPECT_THAT(request->Start(), test::IsError(ERR_CONTEXT_SHUT_DOWN));
434   EXPECT_FALSE(dns_client_->factory()->doh_probes_running());
435 }
436 
TEST_F(ContextHostResolverTest,OnShutdown_PendingRequest)437 TEST_F(ContextHostResolverTest, OnShutdown_PendingRequest) {
438   // Set up delayed result for "example.com".
439   MockDnsClientRuleList rules;
440   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
441                      MockDnsClientRule::Result(BuildTestDnsAddressResponse(
442                          "example.com", IPAddress(2, 3, 4, 5))),
443                      true /* delay */);
444   rules.emplace_back(
445       "example.com", dns_protocol::kTypeAAAA, false /* secure */,
446       MockDnsClientRule::Result(MockDnsClientRule::ResultType::kEmpty),
447       false /* delay */);
448   SetMockDnsRules(std::move(rules));
449 
450   auto context = CreateTestURLRequestContextBuilder()->Build();
451   auto resolve_context = std::make_unique<ResolveContext>(
452       context.get(), false /* enable_caching */);
453   auto resolver = std::make_unique<ContextHostResolver>(
454       manager_.get(), std::move(resolve_context));
455   std::unique_ptr<HostResolver::ResolveHostRequest> request =
456       resolver->CreateRequest(HostPortPair("example.com", 100),
457                               NetworkAnonymizationKey(), NetLogWithSource(),
458                               absl::nullopt);
459 
460   TestCompletionCallback callback;
461   int rv = request->Start(callback.callback());
462 
463   // Trigger shutdown before allowing request to complete.
464   resolver->OnShutdown();
465   dns_client_->CompleteDelayedTransactions();
466 
467   // Ensure request never completes.
468   base::RunLoop().RunUntilIdle();
469   EXPECT_THAT(rv, test::IsError(ERR_IO_PENDING));
470   EXPECT_FALSE(callback.have_result());
471 }
472 
TEST_F(ContextHostResolverTest,OnShutdown_CompletedRequests)473 TEST_F(ContextHostResolverTest, OnShutdown_CompletedRequests) {
474   MockDnsClientRuleList rules;
475   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
476                      MockDnsClientRule::Result(BuildTestDnsAddressResponse(
477                          "example.com", kEndpoint.address())),
478                      false /* delay */);
479   rules.emplace_back(
480       "example.com", dns_protocol::kTypeAAAA, false /* secure */,
481       MockDnsClientRule::Result(MockDnsClientRule::ResultType::kEmpty),
482       false /* delay */);
483   SetMockDnsRules(std::move(rules));
484 
485   auto context = CreateTestURLRequestContextBuilder()->Build();
486   auto resolve_context = std::make_unique<ResolveContext>(
487       context.get(), false /* enable_caching */);
488   auto resolver = std::make_unique<ContextHostResolver>(
489       manager_.get(), std::move(resolve_context));
490   std::unique_ptr<HostResolver::ResolveHostRequest> request =
491       resolver->CreateRequest(HostPortPair("example.com", 100),
492                               NetworkAnonymizationKey(), NetLogWithSource(),
493                               absl::nullopt);
494 
495   // Complete request and then shutdown the resolver.
496   TestCompletionCallback callback;
497   int rv = request->Start(callback.callback());
498   ASSERT_THAT(callback.GetResult(rv), test::IsOk());
499   resolver->OnShutdown();
500 
501   // Expect completed results are still available.
502   EXPECT_THAT(request->GetResolveErrorInfo().error, test::IsError(net::OK));
503   EXPECT_THAT(request->GetAddressResults()->endpoints(),
504               testing::ElementsAre(kEndpoint));
505 }
506 
TEST_F(ContextHostResolverTest,OnShutdown_SubsequentRequests)507 TEST_F(ContextHostResolverTest, OnShutdown_SubsequentRequests) {
508   auto context = CreateTestURLRequestContextBuilder()->Build();
509   auto resolve_context = std::make_unique<ResolveContext>(
510       context.get(), false /* enable_caching */);
511   auto resolver = std::make_unique<ContextHostResolver>(
512       manager_.get(), std::move(resolve_context));
513   resolver->OnShutdown();
514 
515   std::unique_ptr<HostResolver::ResolveHostRequest> request1 =
516       resolver->CreateRequest(HostPortPair("example.com", 100),
517                               NetworkAnonymizationKey(), NetLogWithSource(),
518                               absl::nullopt);
519   std::unique_ptr<HostResolver::ResolveHostRequest> request2 =
520       resolver->CreateRequest(HostPortPair("127.0.0.1", 100),
521                               NetworkAnonymizationKey(), NetLogWithSource(),
522                               absl::nullopt);
523 
524   TestCompletionCallback callback1;
525   int rv1 = request1->Start(callback1.callback());
526   TestCompletionCallback callback2;
527   int rv2 = request2->Start(callback2.callback());
528 
529   EXPECT_THAT(callback1.GetResult(rv1), test::IsError(ERR_CONTEXT_SHUT_DOWN));
530   EXPECT_THAT(request1->GetResolveErrorInfo().error,
531               test::IsError(ERR_CONTEXT_SHUT_DOWN));
532   EXPECT_FALSE(request1->GetAddressResults());
533   EXPECT_THAT(callback2.GetResult(rv2), test::IsError(ERR_CONTEXT_SHUT_DOWN));
534   EXPECT_THAT(request2->GetResolveErrorInfo().error,
535               test::IsError(ERR_CONTEXT_SHUT_DOWN));
536   EXPECT_FALSE(request2->GetAddressResults());
537 }
538 
TEST_F(ContextHostResolverTest,OnShutdown_SubsequentDohProbeRequest)539 TEST_F(ContextHostResolverTest, OnShutdown_SubsequentDohProbeRequest) {
540   // Set empty MockDnsClient rules to ensure DnsClient is mocked out.
541   MockDnsClientRuleList rules;
542   SetMockDnsRules(std::move(rules));
543 
544   auto context = CreateTestURLRequestContextBuilder()->Build();
545   auto resolve_context = std::make_unique<ResolveContext>(
546       context.get(), false /* enable_caching */);
547   auto resolver = std::make_unique<ContextHostResolver>(
548       manager_.get(), std::move(resolve_context));
549   resolver->OnShutdown();
550 
551   std::unique_ptr<HostResolver::ProbeRequest> request =
552       resolver->CreateDohProbeRequest();
553 
554   EXPECT_THAT(request->Start(), test::IsError(ERR_CONTEXT_SHUT_DOWN));
555   EXPECT_FALSE(dns_client_->factory()->doh_probes_running());
556 }
557 
558 // Test a request created before shutdown but not yet started.
TEST_F(ContextHostResolverTest,OnShutdown_DelayedStartRequest)559 TEST_F(ContextHostResolverTest, OnShutdown_DelayedStartRequest) {
560   // Set up delayed result for "example.com".
561   MockDnsClientRuleList rules;
562   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
563                      MockDnsClientRule::Result(BuildTestDnsAddressResponse(
564                          "example.com", IPAddress(2, 3, 4, 5))),
565                      true /* delay */);
566   rules.emplace_back(
567       "example.com", dns_protocol::kTypeAAAA, false /* secure */,
568       MockDnsClientRule::Result(MockDnsClientRule::ResultType::kEmpty),
569       false /* delay */);
570 
571   auto context = CreateTestURLRequestContextBuilder()->Build();
572   auto resolve_context = std::make_unique<ResolveContext>(
573       context.get(), false /* enable_caching */);
574   auto resolver = std::make_unique<ContextHostResolver>(
575       manager_.get(), std::move(resolve_context));
576   std::unique_ptr<HostResolver::ResolveHostRequest> request =
577       resolver->CreateRequest(HostPortPair("example.com", 100),
578                               NetworkAnonymizationKey(), NetLogWithSource(),
579                               absl::nullopt);
580 
581   resolver->OnShutdown();
582 
583   TestCompletionCallback callback;
584   int rv = request->Start(callback.callback());
585 
586   EXPECT_THAT(callback.GetResult(rv), test::IsError(ERR_NAME_NOT_RESOLVED));
587   EXPECT_THAT(request->GetResolveErrorInfo().error,
588               test::IsError(ERR_CONTEXT_SHUT_DOWN));
589   EXPECT_FALSE(request->GetAddressResults());
590 }
591 
TEST_F(ContextHostResolverTest,OnShutdown_DelayedStartDohProbeRequest)592 TEST_F(ContextHostResolverTest, OnShutdown_DelayedStartDohProbeRequest) {
593   // Set empty MockDnsClient rules to ensure DnsClient is mocked out.
594   MockDnsClientRuleList rules;
595   SetMockDnsRules(std::move(rules));
596 
597   auto context = CreateTestURLRequestContextBuilder()->Build();
598   auto resolve_context = std::make_unique<ResolveContext>(
599       context.get(), false /* enable_caching */);
600   auto resolver = std::make_unique<ContextHostResolver>(
601       manager_.get(), std::move(resolve_context));
602 
603   std::unique_ptr<HostResolver::ProbeRequest> request =
604       resolver->CreateDohProbeRequest();
605 
606   resolver->OnShutdown();
607 
608   EXPECT_THAT(request->Start(), test::IsError(ERR_CONTEXT_SHUT_DOWN));
609   EXPECT_FALSE(dns_client_->factory()->doh_probes_running());
610 }
611 
TEST_F(ContextHostResolverTest,ResolveFromCache)612 TEST_F(ContextHostResolverTest, ResolveFromCache) {
613   auto resolve_context = std::make_unique<ResolveContext>(
614       nullptr /* url_request_context */, true /* enable_caching */);
615   HostCache* host_cache = resolve_context->host_cache();
616   auto resolver = std::make_unique<ContextHostResolver>(
617       manager_.get(), std::move(resolve_context));
618 
619   // Create the cache entry after creating the ContextHostResolver, as
620   // registering into the HostResolverManager initializes and invalidates the
621   // cache.
622   base::SimpleTestTickClock clock;
623   clock.Advance(base::Days(62));  // Arbitrary non-zero time.
624   std::vector<IPEndPoint> expected({kEndpoint});
625   host_cache->Set(
626       HostCache::Key("example.com", DnsQueryType::UNSPECIFIED,
627                      0 /* host_resolver_flags */, HostResolverSource::ANY,
628                      NetworkAnonymizationKey()),
629       HostCache::Entry(OK, expected,
630                        /*aliases=*/std::set<std::string>({"example.com"}),
631                        HostCache::Entry::SOURCE_DNS, base::Days(1)),
632       clock.NowTicks(), base::Days(1));
633   resolver->SetTickClockForTesting(&clock);
634 
635   // Allow stale results and then confirm the result is not stale in order to
636   // make the issue more clear if something is invalidating the cache.
637   HostResolver::ResolveHostParameters parameters;
638   parameters.source = HostResolverSource::LOCAL_ONLY;
639   parameters.cache_usage =
640       HostResolver::ResolveHostParameters::CacheUsage::STALE_ALLOWED;
641   std::unique_ptr<HostResolver::ResolveHostRequest> request =
642       resolver->CreateRequest(HostPortPair("example.com", 100),
643                               NetworkAnonymizationKey(), NetLogWithSource(),
644                               parameters);
645 
646   TestCompletionCallback callback;
647   int rv = request->Start(callback.callback());
648   EXPECT_THAT(callback.GetResult(rv), test::IsOk());
649   EXPECT_THAT(request->GetResolveErrorInfo().error, test::IsError(net::OK));
650   EXPECT_THAT(request->GetAddressResults()->endpoints(),
651               testing::ElementsAre(kEndpoint));
652   ASSERT_TRUE(request->GetStaleInfo());
653   EXPECT_EQ(0, request->GetStaleInfo().value().network_changes);
654   EXPECT_FALSE(request->GetStaleInfo().value().is_stale());
655 }
656 
TEST_F(ContextHostResolverTest,ResultsAddedToCache)657 TEST_F(ContextHostResolverTest, ResultsAddedToCache) {
658   MockDnsClientRuleList rules;
659   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
660                      MockDnsClientRule::Result(BuildTestDnsAddressResponse(
661                          "example.com", kEndpoint.address())),
662                      false /* delay */);
663   rules.emplace_back(
664       "example.com", dns_protocol::kTypeAAAA, false /* secure */,
665       MockDnsClientRule::Result(MockDnsClientRule::ResultType::kEmpty),
666       false /* delay */);
667   SetMockDnsRules(std::move(rules));
668 
669   auto resolve_context = std::make_unique<ResolveContext>(
670       nullptr /* url_request_context */, true /* enable_caching */);
671   auto resolver = std::make_unique<ContextHostResolver>(
672       manager_.get(), std::move(resolve_context));
673 
674   std::unique_ptr<HostResolver::ResolveHostRequest> caching_request =
675       resolver->CreateRequest(HostPortPair("example.com", 103),
676                               NetworkAnonymizationKey(), NetLogWithSource(),
677                               absl::nullopt);
678   TestCompletionCallback caching_callback;
679   int rv = caching_request->Start(caching_callback.callback());
680   EXPECT_THAT(caching_callback.GetResult(rv), test::IsOk());
681 
682   HostResolver::ResolveHostParameters local_resolve_parameters;
683   local_resolve_parameters.source = HostResolverSource::LOCAL_ONLY;
684   std::unique_ptr<HostResolver::ResolveHostRequest> cached_request =
685       resolver->CreateRequest(HostPortPair("example.com", 100),
686                               NetworkAnonymizationKey(), NetLogWithSource(),
687                               local_resolve_parameters);
688 
689   TestCompletionCallback callback;
690   rv = cached_request->Start(callback.callback());
691   EXPECT_THAT(callback.GetResult(rv), test::IsOk());
692   EXPECT_THAT(cached_request->GetResolveErrorInfo().error,
693               test::IsError(net::OK));
694   EXPECT_THAT(cached_request->GetAddressResults()->endpoints(),
695               testing::ElementsAre(kEndpoint));
696 }
697 
698 // Do a lookup with a NetworkIsolationKey, and then make sure the entry added to
699 // the cache is in fact using that NetworkIsolationKey.
TEST_F(ContextHostResolverTest,ResultsAddedToCacheWithNetworkIsolationKey)700 TEST_F(ContextHostResolverTest, ResultsAddedToCacheWithNetworkIsolationKey) {
701   const SchemefulSite kSite(GURL("https://origin.test/"));
702   const NetworkIsolationKey kNetworkIsolationKey(kSite, kSite);
703   auto kNetworkAnonymizationKey =
704       net::NetworkAnonymizationKey::CreateSameSite(kSite);
705 
706   base::test::ScopedFeatureList feature_list;
707   feature_list.InitAndEnableFeature(
708       features::kSplitHostCacheByNetworkIsolationKey);
709 
710   MockDnsClientRuleList rules;
711   rules.emplace_back("example.com", dns_protocol::kTypeA, false /* secure */,
712                      MockDnsClientRule::Result(BuildTestDnsAddressResponse(
713                          "example.com", kEndpoint.address())),
714                      false /* delay */);
715   rules.emplace_back(
716       "example.com", dns_protocol::kTypeAAAA, false /* secure */,
717       MockDnsClientRule::Result(MockDnsClientRule::ResultType::kEmpty),
718       false /* delay */);
719   SetMockDnsRules(std::move(rules));
720 
721   auto resolve_context = std::make_unique<ResolveContext>(
722       nullptr /* url_request_context */, true /* enable_caching */);
723   auto resolver = std::make_unique<ContextHostResolver>(
724       manager_.get(), std::move(resolve_context));
725 
726   std::unique_ptr<HostResolver::ResolveHostRequest> caching_request =
727       resolver->CreateRequest(HostPortPair("example.com", 103),
728                               kNetworkAnonymizationKey, NetLogWithSource(),
729                               absl::nullopt);
730   TestCompletionCallback caching_callback;
731   int rv = caching_request->Start(caching_callback.callback());
732   EXPECT_THAT(caching_callback.GetResult(rv), test::IsOk());
733 
734   HostCache::Key cache_key("example.com", DnsQueryType::UNSPECIFIED,
735                            0 /* host_resolver_flags */, HostResolverSource::ANY,
736                            kNetworkAnonymizationKey);
737   EXPECT_TRUE(
738       resolver->GetHostCache()->Lookup(cache_key, base::TimeTicks::Now()));
739 
740   HostCache::Key cache_key_with_empty_nak(
741       "example.com", DnsQueryType::UNSPECIFIED, 0 /* host_resolver_flags */,
742       HostResolverSource::ANY, NetworkAnonymizationKey());
743   EXPECT_FALSE(resolver->GetHostCache()->Lookup(cache_key_with_empty_nak,
744                                                 base::TimeTicks::Now()));
745 }
746 
747 // Test that the underlying HostCache can receive invalidations from the manager
748 // and that it safely does not receive invalidations after the resolver (and the
749 // HostCache) is destroyed.
TEST_F(ContextHostResolverTest,HostCacheInvalidation)750 TEST_F(ContextHostResolverTest, HostCacheInvalidation) {
751   // Set empty MockDnsClient rules to ensure DnsClient is mocked out.
752   MockDnsClientRuleList rules;
753   SetMockDnsRules(std::move(rules));
754 
755   auto resolve_context = std::make_unique<ResolveContext>(
756       nullptr /* url_request_context */, true /* enable_caching */);
757   ResolveContext* resolve_context_ptr = resolve_context.get();
758   auto resolver = std::make_unique<ContextHostResolver>(
759       manager_.get(), std::move(resolve_context));
760 
761   // No invalidations yet (other than the initialization "invalidation" from
762   // registering the context).
763   ASSERT_EQ(resolve_context_ptr->current_session_for_testing(),
764             dns_client_->GetCurrentSession());
765   ASSERT_EQ(resolve_context_ptr->host_cache()->network_changes(), 1);
766 
767   manager_->InvalidateCachesForTesting();
768   EXPECT_EQ(resolve_context_ptr->current_session_for_testing(),
769             dns_client_->GetCurrentSession());
770   EXPECT_EQ(resolve_context_ptr->host_cache()->network_changes(), 2);
771 
772   // Expect manager to be able to safely do invalidations after an individual
773   // ContextHostResolver has been destroyed (and deregisters its ResolveContext)
774   resolver = nullptr;
775   manager_->InvalidateCachesForTesting();
776 }
777 
778 class NetworkBoundResolveContext : public ResolveContext {
779  public:
NetworkBoundResolveContext(URLRequestContext * url_request_context,bool enable_caching,handles::NetworkHandle target_network)780   NetworkBoundResolveContext(URLRequestContext* url_request_context,
781                              bool enable_caching,
782                              handles::NetworkHandle target_network)
783       : ResolveContext(url_request_context, enable_caching),
784         target_network_(target_network) {}
785 
GetTargetNetwork() const786   handles::NetworkHandle GetTargetNetwork() const override {
787     return target_network_;
788   }
789 
790  private:
791   const handles::NetworkHandle target_network_;
792 };
793 
794 // A mock HostResolverProc which returns different IP addresses based on the
795 // `network` parameter received.
796 class NetworkAwareHostResolverProc : public HostResolverProc {
797  public:
NetworkAwareHostResolverProc()798   NetworkAwareHostResolverProc() : HostResolverProc(nullptr) {}
799 
800   NetworkAwareHostResolverProc(const NetworkAwareHostResolverProc&) = delete;
801   NetworkAwareHostResolverProc& operator=(const NetworkAwareHostResolverProc&) =
802       delete;
803 
Resolve(const std::string & host,AddressFamily address_family,HostResolverFlags host_resolver_flags,AddressList * addrlist,int * os_error,handles::NetworkHandle network)804   int Resolve(const std::string& host,
805               AddressFamily address_family,
806               HostResolverFlags host_resolver_flags,
807               AddressList* addrlist,
808               int* os_error,
809               handles::NetworkHandle network) override {
810     // Presume failure
811     *os_error = 1;
812     const auto* iter = kResults.find(network);
813     if (iter == kResults.end())
814       return ERR_NETWORK_CHANGED;
815 
816     *os_error = 0;
817     *addrlist = AddressList();
818     addrlist->push_back(ToIPEndPoint(iter->second));
819 
820     return OK;
821   }
822 
Resolve(const std::string & host,AddressFamily address_family,HostResolverFlags host_resolver_flags,AddressList * addrlist,int * os_error)823   int Resolve(const std::string& host,
824               AddressFamily address_family,
825               HostResolverFlags host_resolver_flags,
826               AddressList* addrlist,
827               int* os_error) override {
828     return Resolve(host, address_family, host_resolver_flags, addrlist,
829                    os_error, handles::kInvalidNetworkHandle);
830   }
831 
832   struct IPv4 {
833     uint8_t a;
834     uint8_t b;
835     uint8_t c;
836     uint8_t d;
837   };
838 
839   static constexpr int kPort = 100;
840   static constexpr auto kResults =
841       base::MakeFixedFlatMap<handles::NetworkHandle, IPv4>(
842           {{1, IPv4{1, 2, 3, 4}}, {2, IPv4{8, 8, 8, 8}}});
843 
ToIPEndPoint(const IPv4 & ipv4)844   static IPEndPoint ToIPEndPoint(const IPv4& ipv4) {
845     return IPEndPoint(IPAddress(ipv4.a, ipv4.b, ipv4.c, ipv4.d), kPort);
846   }
847 
848  protected:
849   ~NetworkAwareHostResolverProc() override = default;
850 };
851 
TEST_F(ContextHostResolverTest,ExistingNetworkBoundLookup)852 TEST_F(ContextHostResolverTest, ExistingNetworkBoundLookup) {
853 #if BUILDFLAG(IS_ANDROID)
854   auto scoped_mock_network_change_notifier =
855       std::make_unique<test::ScopedMockNetworkChangeNotifier>();
856   scoped_mock_network_change_notifier->mock_network_change_notifier()
857       ->ForceNetworkHandlesSupported();
858 
859   const url::SchemeHostPort host(url::kHttpsScheme, "example.com",
860                                  NetworkAwareHostResolverProc::kPort);
861   auto resolver_proc = base::MakeRefCounted<NetworkAwareHostResolverProc>();
862   ScopedDefaultHostResolverProc scoped_default_host_resolver;
863   scoped_default_host_resolver.Init(resolver_proc.get());
864 
865   // ResolveContexts bound to a specific network should end up in a call to
866   // Resolve with `network` == context.GetTargetNetwork(). Confirm that we do
867   // indeed receive the IP address associated with that network.
868   for (const auto& iter : NetworkAwareHostResolverProc::kResults) {
869     auto network = iter.first;
870     auto expected_ipv4 = iter.second;
871     auto resolve_context = std::make_unique<NetworkBoundResolveContext>(
872         nullptr /* url_request_context */, false /* enable_caching */, network);
873     // DNS lookups originated from network-bound ResolveContexts must be
874     // resolved through a HostResolverManager bound to the same network.
875     auto manager = HostResolverManager::CreateNetworkBoundHostResolverManager(
876         HostResolver::ManagerOptions(), network, nullptr /* net_log */);
877     auto resolver = std::make_unique<ContextHostResolver>(
878         manager.get(), std::move(resolve_context));
879     std::unique_ptr<HostResolver::ResolveHostRequest> request =
880         resolver->CreateRequest(host, NetworkAnonymizationKey(),
881                                 NetLogWithSource(), absl::nullopt);
882 
883     TestCompletionCallback callback;
884     int rv = request->Start(callback.callback());
885     EXPECT_THAT(callback.GetResult(rv), test::IsOk());
886     EXPECT_THAT(request->GetResolveErrorInfo().error, test::IsError(net::OK));
887     ASSERT_EQ(1u, request->GetAddressResults()->endpoints().size());
888     EXPECT_THAT(request->GetAddressResults()->endpoints(),
889                 testing::ElementsAre(
890                     NetworkAwareHostResolverProc::ToIPEndPoint(expected_ipv4)));
891   }
892 #else   // !BUILDFLAG(IS_ANDROID)
893   GTEST_SKIP()
894       << "Network-bound HostResolverManager are supported only on Android.";
895 #endif  // BUILDFLAG(IS_ANDROID)
896 }
897 
TEST_F(ContextHostResolverTest,NotExistingNetworkBoundLookup)898 TEST_F(ContextHostResolverTest, NotExistingNetworkBoundLookup) {
899   const url::SchemeHostPort host(url::kHttpsScheme, "example.com",
900                                  NetworkAwareHostResolverProc::kPort);
901   auto resolver_proc = base::MakeRefCounted<NetworkAwareHostResolverProc>();
902   ScopedDefaultHostResolverProc scoped_default_host_resolver;
903   scoped_default_host_resolver.Init(resolver_proc.get());
904 
905   // Non-bound ResolveContexts should end up with a call to Resolve with
906   // `network` == kInvalidNetwork, which NetworkAwareHostResolverProc fails to
907   // resolve.
908   auto resolve_context = std::make_unique<ResolveContext>(
909       nullptr /* url_request_context */, false /* enable_caching */);
910   auto resolver = std::make_unique<ContextHostResolver>(
911       manager_.get(), std::move(resolve_context));
912   std::unique_ptr<HostResolver::ResolveHostRequest> request =
913       resolver->CreateRequest(host, NetworkAnonymizationKey(),
914                               NetLogWithSource(), absl::nullopt);
915 
916   TestCompletionCallback callback;
917   int rv = request->Start(callback.callback());
918   EXPECT_THAT(callback.GetResult(rv),
919               test::IsError(net::ERR_NAME_NOT_RESOLVED));
920   EXPECT_THAT(request->GetResolveErrorInfo().error,
921               test::IsError(net::ERR_NETWORK_CHANGED));
922 }
923 
924 // Test that the underlying HostCache does not receive invalidations when its
925 // ResolveContext/HostResolverManager is bound to a network.
TEST_F(ContextHostResolverTest,NetworkBoundResolverCacheInvalidation)926 TEST_F(ContextHostResolverTest, NetworkBoundResolverCacheInvalidation) {
927 #if BUILDFLAG(IS_ANDROID)
928   auto scoped_mock_network_change_notifier =
929       std::make_unique<test::ScopedMockNetworkChangeNotifier>();
930   test::MockNetworkChangeNotifier* mock_ncn =
931       scoped_mock_network_change_notifier->mock_network_change_notifier();
932   mock_ncn->ForceNetworkHandlesSupported();
933 
934   // The actual network handle doesn't really matter, this test just wants to
935   // check that all the pieces are in place and configured correctly.
936   constexpr handles::NetworkHandle network = 2;
937   manager_ = HostResolverManager::CreateNetworkBoundHostResolverManager(
938       HostResolver::ManagerOptions(), network, nullptr /* net_log */);
939   manager_->SetLastIPv6ProbeResultForTesting(true);
940   // Set empty MockDnsClient rules to ensure DnsClient is mocked out.
941   MockDnsClientRuleList rules;
942   SetMockDnsRules(std::move(rules));
943 
944   auto resolve_context = std::make_unique<NetworkBoundResolveContext>(
945       nullptr /* url_request_context */, true /* enable_caching */, network);
946   ResolveContext* resolve_context_ptr = resolve_context.get();
947   auto resolver = std::make_unique<ContextHostResolver>(
948       manager_.get(), std::move(resolve_context));
949 
950   // Network events should not trigger cache invalidations
951   auto network_changes_before_events =
952       resolve_context_ptr->host_cache()->network_changes();
953   NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
954   NetworkChangeNotifier::NotifyObserversOfConnectionTypeChangeForTests(
955       NetworkChangeNotifier::CONNECTION_NONE);
956   base::RunLoop().RunUntilIdle();
957   EXPECT_EQ(network_changes_before_events,
958             resolve_context_ptr->host_cache()->network_changes());
959 #else   // !BUILDFLAG(IS_ANDROID)
960   GTEST_SKIP()
961       << "Network-bound HostResolverManagers are supported only on Android";
962 #endif  // BUILDFLAG(IS_ANDROID)
963 }
964 
965 }  // namespace net
966