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