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