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 <string>
8 #include <utility>
9 #include <vector>
10
11 #include "base/check_op.h"
12 #include "base/strings/string_piece.h"
13 #include "base/time/tick_clock.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/network_anonymization_key.h"
16 #include "net/dns/dns_config.h"
17 #include "net/dns/host_cache.h"
18 #include "net/dns/host_resolver.h"
19 #include "net/dns/host_resolver_manager.h"
20 #include "net/dns/host_resolver_proc.h"
21 #include "net/dns/public/host_resolver_results.h"
22 #include "net/dns/public/resolve_error_info.h"
23 #include "net/dns/resolve_context.h"
24 #include "net/log/net_log_with_source.h"
25 #include "net/url_request/url_request_context.h"
26 #include "third_party/abseil-cpp/absl/types/optional.h"
27 #include "url/scheme_host_port.h"
28
29 namespace net {
30
ContextHostResolver(HostResolverManager * manager,std::unique_ptr<ResolveContext> resolve_context)31 ContextHostResolver::ContextHostResolver(
32 HostResolverManager* manager,
33 std::unique_ptr<ResolveContext> resolve_context)
34 : manager_(manager), resolve_context_(std::move(resolve_context)) {
35 DCHECK(manager_);
36 DCHECK(resolve_context_);
37
38 manager_->RegisterResolveContext(resolve_context_.get());
39 }
40
ContextHostResolver(std::unique_ptr<HostResolverManager> owned_manager,std::unique_ptr<ResolveContext> resolve_context)41 ContextHostResolver::ContextHostResolver(
42 std::unique_ptr<HostResolverManager> owned_manager,
43 std::unique_ptr<ResolveContext> resolve_context)
44 : ContextHostResolver(owned_manager.get(), std::move(resolve_context)) {
45 owned_manager_ = std::move(owned_manager);
46 }
47
~ContextHostResolver()48 ContextHostResolver::~ContextHostResolver() {
49 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
50 if (owned_manager_)
51 DCHECK_EQ(owned_manager_.get(), manager_);
52
53 // No |resolve_context_| to deregister if OnShutdown() was already called.
54 if (resolve_context_)
55 manager_->DeregisterResolveContext(resolve_context_.get());
56 }
57
OnShutdown()58 void ContextHostResolver::OnShutdown() {
59 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
60
61 DCHECK(resolve_context_);
62 manager_->DeregisterResolveContext(resolve_context_.get());
63 resolve_context_.reset();
64
65 DCHECK(!shutting_down_);
66 shutting_down_ = true;
67 }
68
69 std::unique_ptr<HostResolver::ResolveHostRequest>
CreateRequest(url::SchemeHostPort host,NetworkAnonymizationKey network_anonymization_key,NetLogWithSource source_net_log,absl::optional<ResolveHostParameters> optional_parameters)70 ContextHostResolver::CreateRequest(
71 url::SchemeHostPort host,
72 NetworkAnonymizationKey network_anonymization_key,
73 NetLogWithSource source_net_log,
74 absl::optional<ResolveHostParameters> optional_parameters) {
75 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
76
77 if (shutting_down_)
78 return HostResolver::CreateFailingRequest(ERR_CONTEXT_SHUT_DOWN);
79
80 return manager_->CreateRequest(
81 Host(std::move(host)), std::move(network_anonymization_key),
82 std::move(source_net_log), std::move(optional_parameters),
83 resolve_context_.get(), resolve_context_->host_cache());
84 }
85
86 std::unique_ptr<HostResolver::ResolveHostRequest>
CreateRequest(const HostPortPair & host,const NetworkAnonymizationKey & network_anonymization_key,const NetLogWithSource & source_net_log,const absl::optional<ResolveHostParameters> & optional_parameters)87 ContextHostResolver::CreateRequest(
88 const HostPortPair& host,
89 const NetworkAnonymizationKey& network_anonymization_key,
90 const NetLogWithSource& source_net_log,
91 const absl::optional<ResolveHostParameters>& optional_parameters) {
92 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
93
94 if (shutting_down_)
95 return HostResolver::CreateFailingRequest(ERR_CONTEXT_SHUT_DOWN);
96
97 return manager_->CreateRequest(
98 host, network_anonymization_key, source_net_log, optional_parameters,
99 resolve_context_.get(), resolve_context_->host_cache());
100 }
101
102 std::unique_ptr<HostResolver::ProbeRequest>
CreateDohProbeRequest()103 ContextHostResolver::CreateDohProbeRequest() {
104 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
105
106 if (shutting_down_)
107 return HostResolver::CreateFailingProbeRequest(ERR_CONTEXT_SHUT_DOWN);
108
109 return manager_->CreateDohProbeRequest(resolve_context_.get());
110 }
111
112 std::unique_ptr<HostResolver::MdnsListener>
CreateMdnsListener(const HostPortPair & host,DnsQueryType query_type)113 ContextHostResolver::CreateMdnsListener(const HostPortPair& host,
114 DnsQueryType query_type) {
115 return manager_->CreateMdnsListener(host, query_type);
116 }
117
GetHostCache()118 HostCache* ContextHostResolver::GetHostCache() {
119 return resolve_context_->host_cache();
120 }
121
GetDnsConfigAsValue() const122 base::Value::Dict ContextHostResolver::GetDnsConfigAsValue() const {
123 return manager_->GetDnsConfigAsValue();
124 }
125
SetRequestContext(URLRequestContext * request_context)126 void ContextHostResolver::SetRequestContext(
127 URLRequestContext* request_context) {
128 DCHECK(!shutting_down_);
129 DCHECK(resolve_context_);
130 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
131
132 resolve_context_->set_url_request_context(request_context);
133 }
134
GetManagerForTesting()135 HostResolverManager* ContextHostResolver::GetManagerForTesting() {
136 return manager_;
137 }
138
GetContextForTesting() const139 const URLRequestContext* ContextHostResolver::GetContextForTesting() const {
140 return resolve_context_ ? resolve_context_->url_request_context() : nullptr;
141 }
142
GetTargetNetworkForTesting() const143 handles::NetworkHandle ContextHostResolver::GetTargetNetworkForTesting() const {
144 return resolve_context_ ? resolve_context_->GetTargetNetwork()
145 : handles::kInvalidNetworkHandle;
146 }
147
LastRestoredCacheSize() const148 size_t ContextHostResolver::LastRestoredCacheSize() const {
149 return resolve_context_->host_cache()
150 ? resolve_context_->host_cache()->last_restore_size()
151 : 0;
152 }
153
CacheSize() const154 size_t ContextHostResolver::CacheSize() const {
155 return resolve_context_->host_cache() ? resolve_context_->host_cache()->size()
156 : 0;
157 }
158
SetHostResolverSystemParamsForTest(const HostResolverSystemTask::Params & host_resolver_system_params)159 void ContextHostResolver::SetHostResolverSystemParamsForTest(
160 const HostResolverSystemTask::Params& host_resolver_system_params) {
161 manager_->set_host_resolver_system_params_for_test( // IN-TEST
162 host_resolver_system_params);
163 }
164
SetTickClockForTesting(const base::TickClock * tick_clock)165 void ContextHostResolver::SetTickClockForTesting(
166 const base::TickClock* tick_clock) {
167 manager_->SetTickClockForTesting(tick_clock);
168 if (resolve_context_->host_cache())
169 resolve_context_->host_cache()->set_tick_clock_for_testing(tick_clock);
170 }
171
172 } // namespace net
173