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/dns_client.h"
6
7 #include <utility>
8
9 #include "base/functional/bind.h"
10 #include "base/rand_util.h"
11 #include "base/test/task_environment.h"
12 #include "net/base/ip_address.h"
13 #include "net/base/ip_endpoint.h"
14 #include "net/dns/dns_config.h"
15 #include "net/dns/dns_session.h"
16 #include "net/dns/dns_test_util.h"
17 #include "net/dns/public/dns_over_https_config.h"
18 #include "net/dns/resolve_context.h"
19 #include "net/socket/socket_test_util.h"
20 #include "net/test/test_with_task_environment.h"
21 #include "net/url_request/url_request_context.h"
22 #include "net/url_request/url_request_context_builder.h"
23 #include "net/url_request/url_request_test_util.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "url/scheme_host_port.h"
27
28 namespace net {
29
30 class ClientSocketFactory;
31
32 namespace {
33
34 class AlwaysFailSocketFactory : public MockClientSocketFactory {
35 public:
CreateDatagramClientSocket(DatagramSocket::BindType bind_type,NetLog * net_log,const NetLogSource & source)36 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
37 DatagramSocket::BindType bind_type,
38 NetLog* net_log,
39 const NetLogSource& source) override {
40 return std::make_unique<MockUDPClientSocket>();
41 }
42 };
43
44 class DnsClientTest : public TestWithTaskEnvironment {
45 protected:
DnsClientTest()46 DnsClientTest()
47 : TestWithTaskEnvironment(
48 base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
49
SetUp()50 void SetUp() override {
51 client_ = DnsClient::CreateClient(nullptr /* net_log */);
52 auto context_builder = CreateTestURLRequestContextBuilder();
53 context_builder->set_client_socket_factory_for_testing(&socket_factory_);
54 request_context_ = context_builder->Build();
55 resolve_context_ = std::make_unique<ResolveContext>(
56 request_context_.get(), false /* enable_caching */);
57 }
58
BasicValidConfig()59 DnsConfig BasicValidConfig() {
60 DnsConfig config;
61 config.nameservers = {IPEndPoint(IPAddress(2, 3, 4, 5), 123)};
62 return config;
63 }
64
ValidConfigWithDoh(bool doh_only)65 DnsConfig ValidConfigWithDoh(bool doh_only) {
66 DnsConfig config;
67 if (!doh_only) {
68 config = BasicValidConfig();
69 }
70 config.doh_config =
71 *net::DnsOverHttpsConfig::FromString("https://www.doh.com/");
72 return config;
73 }
74
BasicValidOverrides()75 DnsConfigOverrides BasicValidOverrides() {
76 DnsConfigOverrides config;
77 config.nameservers.emplace({IPEndPoint(IPAddress(1, 2, 3, 4), 123)});
78 return config;
79 }
80
81 std::unique_ptr<URLRequestContext> request_context_;
82 std::unique_ptr<ResolveContext> resolve_context_;
83 std::unique_ptr<DnsClient> client_;
84 AlwaysFailSocketFactory socket_factory_;
85 };
86
TEST_F(DnsClientTest,NoConfig)87 TEST_F(DnsClientTest, NoConfig) {
88 client_->SetInsecureEnabled(/*enabled=*/true,
89 /*additional_types_enabled=*/true);
90
91 EXPECT_FALSE(client_->CanUseSecureDnsTransactions());
92 EXPECT_TRUE(
93 client_->FallbackFromSecureTransactionPreferred(resolve_context_.get()));
94 EXPECT_FALSE(client_->CanUseInsecureDnsTransactions());
95 EXPECT_TRUE(client_->FallbackFromInsecureTransactionPreferred());
96
97 EXPECT_FALSE(client_->GetEffectiveConfig());
98 EXPECT_FALSE(client_->GetHosts());
99 EXPECT_FALSE(client_->GetTransactionFactory());
100 EXPECT_FALSE(client_->GetCurrentSession());
101 }
102
TEST_F(DnsClientTest,InvalidConfig)103 TEST_F(DnsClientTest, InvalidConfig) {
104 client_->SetInsecureEnabled(/*enabled=*/true,
105 /*additional_types_enabled=*/true);
106 client_->SetSystemConfig(DnsConfig());
107
108 EXPECT_FALSE(client_->CanUseSecureDnsTransactions());
109 EXPECT_TRUE(
110 client_->FallbackFromSecureTransactionPreferred(resolve_context_.get()));
111 EXPECT_FALSE(client_->CanUseInsecureDnsTransactions());
112 EXPECT_TRUE(client_->FallbackFromInsecureTransactionPreferred());
113
114 EXPECT_FALSE(client_->GetEffectiveConfig());
115 EXPECT_FALSE(client_->GetHosts());
116 EXPECT_FALSE(client_->GetTransactionFactory());
117 EXPECT_FALSE(client_->GetCurrentSession());
118 }
119
TEST_F(DnsClientTest,CanUseSecureDnsTransactions_NoDohServers)120 TEST_F(DnsClientTest, CanUseSecureDnsTransactions_NoDohServers) {
121 client_->SetInsecureEnabled(/*enabled=*/true,
122 /*additional_types_enabled=*/true);
123 client_->SetSystemConfig(BasicValidConfig());
124
125 EXPECT_FALSE(client_->CanUseSecureDnsTransactions());
126 EXPECT_TRUE(
127 client_->FallbackFromSecureTransactionPreferred(resolve_context_.get()));
128 EXPECT_TRUE(client_->CanUseInsecureDnsTransactions());
129 EXPECT_TRUE(client_->CanQueryAdditionalTypesViaInsecureDns());
130 EXPECT_FALSE(client_->FallbackFromInsecureTransactionPreferred());
131
132 EXPECT_THAT(client_->GetEffectiveConfig(),
133 testing::Pointee(BasicValidConfig()));
134 EXPECT_TRUE(client_->GetHosts());
135 EXPECT_TRUE(client_->GetTransactionFactory());
136 EXPECT_EQ(client_->GetCurrentSession()->config(), BasicValidConfig());
137 }
138
TEST_F(DnsClientTest,InsecureNotEnabled)139 TEST_F(DnsClientTest, InsecureNotEnabled) {
140 client_->SetInsecureEnabled(/*enabled=*/false,
141 /*additional_types_enabled=*/false);
142 client_->SetSystemConfig(ValidConfigWithDoh(false /* doh_only */));
143
144 EXPECT_TRUE(client_->CanUseSecureDnsTransactions());
145 EXPECT_TRUE(
146 client_->FallbackFromSecureTransactionPreferred(resolve_context_.get()));
147 EXPECT_FALSE(client_->CanUseInsecureDnsTransactions());
148 EXPECT_TRUE(client_->FallbackFromInsecureTransactionPreferred());
149
150 EXPECT_THAT(client_->GetEffectiveConfig(),
151 testing::Pointee(ValidConfigWithDoh(false /* doh_only */)));
152 EXPECT_TRUE(client_->GetHosts());
153 EXPECT_TRUE(client_->GetTransactionFactory());
154 EXPECT_EQ(client_->GetCurrentSession()->config(),
155 ValidConfigWithDoh(false /* doh_only */));
156 }
157
TEST_F(DnsClientTest,RespectsAdditionalTypesDisabled)158 TEST_F(DnsClientTest, RespectsAdditionalTypesDisabled) {
159 client_->SetInsecureEnabled(/*enabled=*/true,
160 /*additional_types_enabled=*/false);
161 client_->SetSystemConfig(BasicValidConfig());
162
163 EXPECT_FALSE(client_->CanUseSecureDnsTransactions());
164 EXPECT_TRUE(
165 client_->FallbackFromSecureTransactionPreferred(resolve_context_.get()));
166 EXPECT_TRUE(client_->CanUseInsecureDnsTransactions());
167 EXPECT_FALSE(client_->CanQueryAdditionalTypesViaInsecureDns());
168 EXPECT_FALSE(client_->FallbackFromInsecureTransactionPreferred());
169 }
170
TEST_F(DnsClientTest,UnhandledOptions)171 TEST_F(DnsClientTest, UnhandledOptions) {
172 client_->SetInsecureEnabled(/*enabled=*/true,
173 /*additional_types_enabled=*/true);
174 DnsConfig config = ValidConfigWithDoh(false /* doh_only */);
175 config.unhandled_options = true;
176 client_->SetSystemConfig(config);
177
178 EXPECT_TRUE(client_->CanUseSecureDnsTransactions());
179 EXPECT_TRUE(
180 client_->FallbackFromSecureTransactionPreferred(resolve_context_.get()));
181 EXPECT_FALSE(client_->CanUseInsecureDnsTransactions());
182 EXPECT_TRUE(client_->FallbackFromInsecureTransactionPreferred());
183
184 DnsConfig expected_config = config;
185 expected_config.nameservers.clear();
186 EXPECT_THAT(client_->GetEffectiveConfig(), testing::Pointee(expected_config));
187 EXPECT_TRUE(client_->GetHosts());
188 EXPECT_TRUE(client_->GetTransactionFactory());
189 EXPECT_EQ(client_->GetCurrentSession()->config(), expected_config);
190 }
191
TEST_F(DnsClientTest,CanUseSecureDnsTransactions_ProbeSuccess)192 TEST_F(DnsClientTest, CanUseSecureDnsTransactions_ProbeSuccess) {
193 client_->SetSystemConfig(ValidConfigWithDoh(true /* doh_only */));
194 resolve_context_->InvalidateCachesAndPerSessionData(
195 client_->GetCurrentSession(), true /* network_change */);
196
197 EXPECT_TRUE(client_->CanUseSecureDnsTransactions());
198 EXPECT_TRUE(
199 client_->FallbackFromSecureTransactionPreferred(resolve_context_.get()));
200
201 resolve_context_->RecordServerSuccess(0u /* server_index */,
202 true /* is_doh_server */,
203 client_->GetCurrentSession());
204 EXPECT_TRUE(client_->CanUseSecureDnsTransactions());
205 EXPECT_FALSE(
206 client_->FallbackFromSecureTransactionPreferred(resolve_context_.get()));
207 }
208
TEST_F(DnsClientTest,DnsOverTlsActive)209 TEST_F(DnsClientTest, DnsOverTlsActive) {
210 client_->SetInsecureEnabled(/*enabled=*/true,
211 /*additional_types_enabled=*/true);
212 DnsConfig config = ValidConfigWithDoh(false /* doh_only */);
213 config.dns_over_tls_active = true;
214 client_->SetSystemConfig(config);
215
216 EXPECT_TRUE(client_->CanUseSecureDnsTransactions());
217 EXPECT_TRUE(
218 client_->FallbackFromSecureTransactionPreferred(resolve_context_.get()));
219 EXPECT_FALSE(client_->CanUseInsecureDnsTransactions());
220 EXPECT_TRUE(client_->FallbackFromInsecureTransactionPreferred());
221
222 EXPECT_THAT(client_->GetEffectiveConfig(), testing::Pointee(config));
223 EXPECT_TRUE(client_->GetHosts());
224 EXPECT_TRUE(client_->GetTransactionFactory());
225 EXPECT_EQ(client_->GetCurrentSession()->config(), config);
226 }
227
TEST_F(DnsClientTest,AllAllowed)228 TEST_F(DnsClientTest, AllAllowed) {
229 client_->SetInsecureEnabled(/*enabled=*/true,
230 /*additional_types_enabled=*/true);
231 client_->SetSystemConfig(ValidConfigWithDoh(false /* doh_only */));
232 resolve_context_->InvalidateCachesAndPerSessionData(
233 client_->GetCurrentSession(), false /* network_change */);
234 resolve_context_->RecordServerSuccess(0u /* server_index */,
235 true /* is_doh_server */,
236 client_->GetCurrentSession());
237
238 EXPECT_TRUE(client_->CanUseSecureDnsTransactions());
239 EXPECT_FALSE(
240 client_->FallbackFromSecureTransactionPreferred(resolve_context_.get()));
241 EXPECT_TRUE(client_->CanUseInsecureDnsTransactions());
242 EXPECT_TRUE(client_->CanQueryAdditionalTypesViaInsecureDns());
243 EXPECT_FALSE(client_->FallbackFromInsecureTransactionPreferred());
244
245 EXPECT_THAT(client_->GetEffectiveConfig(),
246 testing::Pointee(ValidConfigWithDoh(false /* doh_only */)));
247 EXPECT_TRUE(client_->GetHosts());
248 EXPECT_TRUE(client_->GetTransactionFactory());
249 EXPECT_EQ(client_->GetCurrentSession()->config(),
250 ValidConfigWithDoh(false /* doh_only */));
251 }
252
TEST_F(DnsClientTest,FallbackFromInsecureTransactionPreferred_Failures)253 TEST_F(DnsClientTest, FallbackFromInsecureTransactionPreferred_Failures) {
254 client_->SetInsecureEnabled(/*enabled=*/true,
255 /*additional_types_enabled=*/true);
256 client_->SetSystemConfig(ValidConfigWithDoh(false /* doh_only */));
257
258 for (int i = 0; i < DnsClient::kMaxInsecureFallbackFailures; ++i) {
259 EXPECT_TRUE(client_->CanUseSecureDnsTransactions());
260 EXPECT_TRUE(client_->FallbackFromSecureTransactionPreferred(
261 resolve_context_.get()));
262 EXPECT_TRUE(client_->CanUseInsecureDnsTransactions());
263 EXPECT_TRUE(client_->CanQueryAdditionalTypesViaInsecureDns());
264 EXPECT_FALSE(client_->FallbackFromInsecureTransactionPreferred());
265
266 client_->IncrementInsecureFallbackFailures();
267 }
268
269 EXPECT_TRUE(client_->CanUseSecureDnsTransactions());
270 EXPECT_TRUE(
271 client_->FallbackFromSecureTransactionPreferred(resolve_context_.get()));
272 EXPECT_TRUE(client_->CanUseInsecureDnsTransactions());
273 EXPECT_TRUE(client_->CanQueryAdditionalTypesViaInsecureDns());
274 EXPECT_TRUE(client_->FallbackFromInsecureTransactionPreferred());
275
276 client_->ClearInsecureFallbackFailures();
277
278 EXPECT_TRUE(client_->CanUseSecureDnsTransactions());
279 EXPECT_TRUE(
280 client_->FallbackFromSecureTransactionPreferred(resolve_context_.get()));
281 EXPECT_TRUE(client_->CanUseInsecureDnsTransactions());
282 EXPECT_TRUE(client_->CanQueryAdditionalTypesViaInsecureDns());
283 EXPECT_FALSE(client_->FallbackFromInsecureTransactionPreferred());
284 }
285
TEST_F(DnsClientTest,GetPresetAddrs)286 TEST_F(DnsClientTest, GetPresetAddrs) {
287 DnsConfig config;
288 config.doh_config = *net::DnsOverHttpsConfig::FromString(R"(
289 {
290 "servers": [{
291 "template": "https://www.doh.com/",
292 "endpoints": [{
293 "ips": ["4.3.2.1"]
294 }, {
295 "ips": ["4.3.2.2"]
296 }]
297 }]
298 }
299 )");
300 client_->SetSystemConfig(config);
301
302 EXPECT_FALSE(client_->GetPresetAddrs(
303 url::SchemeHostPort("https", "otherdomain.com", 443)));
304 EXPECT_FALSE(
305 client_->GetPresetAddrs(url::SchemeHostPort("http", "www.doh.com", 443)));
306 EXPECT_FALSE(client_->GetPresetAddrs(
307 url::SchemeHostPort("https", "www.doh.com", 9999)));
308
309 std::vector<IPEndPoint> expected({{{4, 3, 2, 1}, 443}, {{4, 3, 2, 2}, 443}});
310
311 EXPECT_THAT(
312 client_->GetPresetAddrs(url::SchemeHostPort("https", "www.doh.com", 443)),
313 testing::Optional(expected));
314 }
315
TEST_F(DnsClientTest,Override)316 TEST_F(DnsClientTest, Override) {
317 client_->SetSystemConfig(BasicValidConfig());
318 EXPECT_THAT(client_->GetEffectiveConfig(),
319 testing::Pointee(BasicValidConfig()));
320 EXPECT_EQ(client_->GetCurrentSession()->config(), BasicValidConfig());
321
322 client_->SetConfigOverrides(BasicValidOverrides());
323 EXPECT_THAT(client_->GetEffectiveConfig(),
324 testing::Pointee(
325 BasicValidOverrides().ApplyOverrides(BasicValidConfig())));
326 EXPECT_EQ(client_->GetCurrentSession()->config(),
327 BasicValidOverrides().ApplyOverrides(BasicValidConfig()));
328
329 client_->SetConfigOverrides(DnsConfigOverrides());
330 EXPECT_THAT(client_->GetEffectiveConfig(),
331 testing::Pointee(BasicValidConfig()));
332 EXPECT_EQ(client_->GetCurrentSession()->config(), BasicValidConfig());
333 }
334
335 // Cannot apply overrides without a system config unless everything is
336 // overridden
337 TEST_F(DnsClientTest, OverrideNoConfig) {
338 client_->SetConfigOverrides(BasicValidOverrides());
339 EXPECT_FALSE(client_->GetEffectiveConfig());
340 EXPECT_FALSE(client_->GetCurrentSession());
341
342 auto override_everything =
343 DnsConfigOverrides::CreateOverridingEverythingWithDefaults();
344 override_everything.nameservers.emplace(
345 {IPEndPoint(IPAddress(1, 2, 3, 4), 123)});
346 client_->SetConfigOverrides(override_everything);
347 EXPECT_THAT(
348 client_->GetEffectiveConfig(),
349 testing::Pointee(override_everything.ApplyOverrides(DnsConfig())));
350 EXPECT_EQ(client_->GetCurrentSession()->config(),
351 override_everything.ApplyOverrides(DnsConfig()));
352 }
353
354 TEST_F(DnsClientTest, OverrideInvalidConfig) {
355 client_->SetSystemConfig(DnsConfig());
356 EXPECT_FALSE(client_->GetEffectiveConfig());
357 EXPECT_FALSE(client_->GetCurrentSession());
358
359 client_->SetConfigOverrides(BasicValidOverrides());
360 EXPECT_THAT(client_->GetEffectiveConfig(),
361 testing::Pointee(
362 BasicValidOverrides().ApplyOverrides(BasicValidConfig())));
363 EXPECT_EQ(client_->GetCurrentSession()->config(),
364 BasicValidOverrides().ApplyOverrides(DnsConfig()));
365 }
366
367 TEST_F(DnsClientTest, OverrideToInvalid) {
368 client_->SetSystemConfig(BasicValidConfig());
369 EXPECT_THAT(client_->GetEffectiveConfig(),
370 testing::Pointee(BasicValidConfig()));
371 EXPECT_EQ(client_->GetCurrentSession()->config(), BasicValidConfig());
372
373 DnsConfigOverrides overrides;
374 overrides.nameservers.emplace();
375 client_->SetConfigOverrides(std::move(overrides));
376
377 EXPECT_FALSE(client_->GetEffectiveConfig());
378 EXPECT_FALSE(client_->GetCurrentSession());
379 }
380
381 TEST_F(DnsClientTest, ReplaceCurrentSession) {
382 client_->SetSystemConfig(BasicValidConfig());
383
384 base::WeakPtr<DnsSession> session_before =
385 client_->GetCurrentSession()->GetWeakPtr();
386 ASSERT_TRUE(session_before);
387
388 client_->ReplaceCurrentSession();
389
390 EXPECT_FALSE(session_before);
391 EXPECT_TRUE(client_->GetCurrentSession());
392 }
393
394 TEST_F(DnsClientTest, ReplaceCurrentSession_NoSession) {
395 ASSERT_FALSE(client_->GetCurrentSession());
396
397 client_->ReplaceCurrentSession();
398
399 EXPECT_FALSE(client_->GetCurrentSession());
400 }
401
402 } // namespace
403
404 } // namespace net
405