blob: 4c86ee8434d14321f68ba3cc007e6dae93ff2eb6 [file] [log] [blame]
[email protected]78eac2a2012-03-14 19:09:271// Copyright (c) 2012 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/dns_test_util.h"
6
Eric Orth3b26e3ba2020-11-12 22:43:137#include <string>
8#include <utility>
9#include <vector>
10
[email protected]d9806a972014-02-26 18:14:5711#include "base/big_endian.h"
[email protected]78eac2a2012-03-14 19:09:2712#include "base/bind.h"
Eric Orth3b26e3ba2020-11-12 22:43:1313#include "base/check.h"
skyostil4891b25b2015-06-11 11:43:4514#include "base/location.h"
Eric Orth828bd3ae2018-12-12 17:30:3615#include "base/numerics/safe_conversions.h"
skyostil4891b25b2015-06-11 11:43:4516#include "base/single_thread_task_runner.h"
[email protected]78eac2a2012-03-14 19:09:2717#include "base/sys_byteorder.h"
gabf767595f2016-05-11 18:50:3518#include "base/threading/thread_task_runner_handle.h"
Eric Orth3b26e3ba2020-11-12 22:43:1319#include "base/time/time.h"
[email protected]78eac2a2012-03-14 19:09:2720#include "net/base/io_buffer.h"
Eric Orth828bd3ae2018-12-12 17:30:3621#include "net/base/ip_address.h"
[email protected]78eac2a2012-03-14 19:09:2722#include "net/base/net_errors.h"
[email protected]0adcb2b2012-08-15 21:30:4623#include "net/dns/address_sorter.h"
Eric Orth394db1732019-08-27 20:09:3924#include "net/dns/dns_hosts.h"
[email protected]78eac2a2012-03-14 19:09:2725#include "net/dns/dns_query.h"
Eric Orthaf82b49a2020-02-01 01:48:5026#include "net/dns/dns_session.h"
Eric Orth9300cc62020-08-21 00:29:3427#include "net/dns/dns_socket_allocator.h"
tfarina77021d62015-10-11 20:19:0328#include "net/dns/dns_util.h"
Eric Orth069a3c6e2020-01-31 23:14:2429#include "net/dns/resolve_context.h"
[email protected]78eac2a2012-03-14 19:09:2730#include "testing/gtest/include/gtest/gtest.h"
31
32namespace net {
33namespace {
34
Eric Orth828bd3ae2018-12-12 17:30:3635const uint8_t kMalformedResponseHeader[] = {
36 // Header
37 0x00, 0x14, // Arbitrary ID
38 0x81, 0x80, // Standard query response, RA, no error
39 0x00, 0x01, // 1 question
40 0x00, 0x01, // 1 RR (answers)
41 0x00, 0x00, // 0 authority RRs
42 0x00, 0x00, // 0 additional RRs
43};
44
45// Create a response containing a valid question (as would normally be validated
46// in DnsTransaction) but completely missing a header-declared answer.
Eric Ortha97f0f72020-10-16 16:10:3247DnsResponse CreateMalformedResponse(std::string hostname, uint16_t type) {
Eric Orth828bd3ae2018-12-12 17:30:3648 std::string dns_name;
49 CHECK(DNSDomainFromDot(hostname, &dns_name));
50 DnsQuery query(0x14 /* id */, dns_name, type);
51
52 // Build response to simulate the barebones validation DnsResponse applies to
53 // responses received from the network.
54 auto buffer = base::MakeRefCounted<IOBufferWithSize>(
55 sizeof(kMalformedResponseHeader) + query.question().size());
56 memcpy(buffer->data(), kMalformedResponseHeader,
57 sizeof(kMalformedResponseHeader));
58 memcpy(buffer->data() + sizeof(kMalformedResponseHeader),
59 query.question().data(), query.question().size());
60
Eric Ortha97f0f72020-10-16 16:10:3261 DnsResponse response(buffer, buffer->size());
62 CHECK(response.InitParseWithoutQuery(buffer->size()));
Eric Orth828bd3ae2018-12-12 17:30:3663
64 return response;
65}
66
[email protected]daae1322013-09-05 18:26:5067class MockAddressSorter : public AddressSorter {
68 public:
Chris Watkins68b15032017-12-01 03:07:1369 ~MockAddressSorter() override = default;
Bence Békyd5e474c2018-08-02 18:45:0870 void Sort(const AddressList& list, CallbackType callback) const override {
[email protected]daae1322013-09-05 18:26:5071 // Do nothing.
Bence Békyd5e474c2018-08-02 18:45:0872 std::move(callback).Run(true, list);
[email protected]daae1322013-09-05 18:26:5073 }
74};
75
[email protected]daae1322013-09-05 18:26:5076} // namespace
[email protected]78eac2a2012-03-14 19:09:2777
Eric Orth8539e492020-10-19 20:09:5578DnsResourceRecord BuildTestDnsRecord(std::string name,
79 uint16_t type,
80 std::string rdata,
81 base::TimeDelta ttl) {
David Van Cleve34c74c72019-10-31 19:58:0182 DCHECK(!name.empty());
David Van Cleve34c74c72019-10-31 19:58:0183
84 DnsResourceRecord record;
85 record.name = std::move(name);
Eric Orth8539e492020-10-19 20:09:5586 record.type = type;
David Van Cleve34c74c72019-10-31 19:58:0187 record.klass = dns_protocol::kClassIN;
Eric Orth8539e492020-10-19 20:09:5588 record.ttl = ttl.InSeconds();
Eric Orth5d21f152020-10-21 19:15:4389
90 if (!rdata.empty())
91 record.SetOwnedRdata(std::move(rdata));
David Van Cleve34c74c72019-10-31 19:58:0192
93 return record;
94}
95
Eric Orth65fd3e32020-11-18 04:59:1796DnsResourceRecord BuildTestCnameRecord(std::string name,
97 base::StringPiece canonical_name,
98 base::TimeDelta ttl) {
99 DCHECK(!name.empty());
100 DCHECK(!canonical_name.empty());
101
102 std::string rdata;
103 CHECK(DNSDomainFromDot(canonical_name, &rdata));
104
105 return BuildTestDnsRecord(std::move(name), dns_protocol::kTypeCNAME,
106 std::move(rdata), ttl);
107}
108
Eric Orth8539e492020-10-19 20:09:55109DnsResourceRecord BuildTestAddressRecord(std::string name,
110 const IPAddress& ip,
111 base::TimeDelta ttl) {
112 DCHECK(!name.empty());
Eric Orth828bd3ae2018-12-12 17:30:36113 DCHECK(ip.IsValid());
114
Eric Orth8539e492020-10-19 20:09:55115 return BuildTestDnsRecord(
116 std::move(name),
117 ip.IsIPv4() ? dns_protocol::kTypeA : dns_protocol::kTypeAAAA,
118 net::IPAddressToPackedString(ip), ttl);
119}
120
Eric Orth3b26e3ba2020-11-12 22:43:13121DnsResourceRecord BuildTestTextRecord(std::string name,
122 std::vector<std::string> text_strings,
123 base::TimeDelta ttl) {
124 DCHECK(!text_strings.empty());
125
126 std::string rdata;
127 for (const std::string& text_string : text_strings) {
128 DCHECK(!text_string.empty());
129
130 rdata += base::checked_cast<unsigned char>(text_string.size());
131 rdata += text_string;
132 }
133
134 return BuildTestDnsRecord(std::move(name), dns_protocol::kTypeTXT,
Eric Orthd16fee6b2020-11-18 06:43:14135 std::move(rdata), ttl);
Eric Orth3b26e3ba2020-11-12 22:43:13136}
137
Eric Orth7139e0552020-11-04 02:41:11138DnsResourceRecord BuildTestHttpsAliasRecord(std::string name,
139 base::StringPiece alias_name,
140 base::TimeDelta ttl) {
141 DCHECK(!name.empty());
142
143 std::string rdata("\000\000", 2);
144
145 std::string alias_domain;
146 CHECK(DNSDomainFromDot(alias_name, &alias_domain));
147 rdata.append(alias_domain);
148
149 return BuildTestDnsRecord(std::move(name), dns_protocol::kTypeHttps,
150 std::move(rdata), ttl);
151}
152
153DnsResourceRecord BuildTestHttpsServiceRecord(
154 std::string name,
155 uint16_t priority,
156 base::StringPiece service_name,
157 const std::map<uint16_t, std::string>& params,
158 base::TimeDelta ttl) {
159 DCHECK(!name.empty());
160 DCHECK_NE(priority, 0);
161
162 std::string rdata;
163
164 char num_buffer[2];
165 base::WriteBigEndian(num_buffer, priority);
166 rdata.append(num_buffer, 2);
167
168 std::string service_domain;
169 CHECK(DNSDomainFromDot(service_name, &service_domain));
170 rdata.append(service_domain);
171
172 for (auto& param : params) {
173 base::WriteBigEndian(num_buffer, param.first);
174 rdata.append(num_buffer, 2);
175
176 base::WriteBigEndian(num_buffer,
177 base::checked_cast<uint16_t>(param.second.size()));
178 rdata.append(num_buffer, 2);
179
180 rdata.append(param.second);
181 }
182
183 return BuildTestDnsRecord(std::move(name), dns_protocol::kTypeHttps,
184 std::move(rdata), ttl);
185}
186
Eric Orth8539e492020-10-19 20:09:55187DnsResponse BuildTestDnsResponse(
188 std::string name,
189 uint16_t type,
Eric Orth69c25992020-11-10 16:55:12190 const std::vector<DnsResourceRecord>& answers,
191 const std::vector<DnsResourceRecord>& authority,
Eric Orth9cec76f2020-11-17 07:42:42192 const std::vector<DnsResourceRecord>& additional,
193 uint8_t rcode) {
Eric Orth8539e492020-10-19 20:09:55194 DCHECK(!name.empty());
195
Eric Orth828bd3ae2018-12-12 17:30:36196 std::string dns_name;
197 CHECK(DNSDomainFromDot(name, &dns_name));
Eric Orth8539e492020-10-19 20:09:55198
Anton Bikineev068d2912021-05-15 20:43:52199 absl::optional<DnsQuery> query(absl::in_place, 0, std::move(dns_name), type);
Eric Orth8539e492020-10-19 20:09:55200 return DnsResponse(0, true /* is_authoritative */, answers,
Eric Orth69c25992020-11-10 16:55:12201 authority /* authority_records */,
Eric Orth9cec76f2020-11-17 07:42:42202 additional /* additional_records */, query, rcode,
Eric Orthd16fee6b2020-11-18 06:43:14203 false /* validate_records */);
Eric Orth828bd3ae2018-12-12 17:30:36204}
205
Eric Orth8539e492020-10-19 20:09:55206DnsResponse BuildTestDnsAddressResponse(std::string name,
207 const IPAddress& ip,
208 std::string answer_name) {
209 DCHECK(ip.IsValid());
210
211 if (answer_name.empty())
212 answer_name = name;
213
214 std::vector<DnsResourceRecord> answers = {
215 BuildTestAddressRecord(std::move(answer_name), ip)};
216
217 return BuildTestDnsResponse(
218 std::move(name),
219 ip.IsIPv4() ? dns_protocol::kTypeA : dns_protocol::kTypeAAAA, answers);
220}
221
Eric Ortha97f0f72020-10-16 16:10:32222DnsResponse BuildTestDnsAddressResponseWithCname(std::string name,
223 const IPAddress& ip,
Eric Orth8539e492020-10-19 20:09:55224 std::string cannonname,
225 std::string answer_name) {
Eric Orth828bd3ae2018-12-12 17:30:36226 DCHECK(ip.IsValid());
227 DCHECK(!cannonname.empty());
228
Eric Orth8539e492020-10-19 20:09:55229 if (answer_name.empty())
230 answer_name = name;
231
232 std::string cname_rdata;
233 CHECK(DNSDomainFromDot(cannonname, &cname_rdata));
234
Eric Orth828bd3ae2018-12-12 17:30:36235 std::vector<DnsResourceRecord> answers = {
Eric Orth8539e492020-10-19 20:09:55236 BuildTestDnsRecord(std::move(answer_name), dns_protocol::kTypeCNAME,
237 std::move(cname_rdata)),
238 BuildTestAddressRecord(std::move(cannonname), ip)};
239
240 return BuildTestDnsResponse(
241 std::move(name),
242 ip.IsIPv4() ? dns_protocol::kTypeA : dns_protocol::kTypeAAAA, answers);
Eric Orth828bd3ae2018-12-12 17:30:36243}
244
Eric Ortha97f0f72020-10-16 16:10:32245DnsResponse BuildTestDnsTextResponse(
Eric Orth828bd3ae2018-12-12 17:30:36246 std::string name,
247 std::vector<std::vector<std::string>> text_records,
248 std::string answer_name) {
249 if (answer_name.empty())
250 answer_name = name;
251
252 std::vector<DnsResourceRecord> answers;
Eric Ortha625b042019-01-16 01:14:45253 for (std::vector<std::string>& text_record : text_records) {
Eric Orth3b26e3ba2020-11-12 22:43:13254 answers.push_back(BuildTestTextRecord(answer_name, std::move(text_record)));
Eric Orth828bd3ae2018-12-12 17:30:36255 }
256
Eric Orth8539e492020-10-19 20:09:55257 return BuildTestDnsResponse(std::move(name), dns_protocol::kTypeTXT, answers);
Eric Orth828bd3ae2018-12-12 17:30:36258}
259
Eric Ortha97f0f72020-10-16 16:10:32260DnsResponse BuildTestDnsPointerResponse(std::string name,
261 std::vector<std::string> pointer_names,
262 std::string answer_name) {
Eric Orthe9db8d232019-01-14 21:24:45263 if (answer_name.empty())
264 answer_name = name;
265
266 std::vector<DnsResourceRecord> answers;
Eric Ortha625b042019-01-16 01:14:45267 for (std::string& pointer_name : pointer_names) {
Eric Orth8539e492020-10-19 20:09:55268 std::string rdata;
269 CHECK(DNSDomainFromDot(pointer_name, &rdata));
270
271 answers.push_back(BuildTestDnsRecord(answer_name, dns_protocol::kTypePTR,
272 std::move(rdata)));
Eric Orthe9db8d232019-01-14 21:24:45273 }
274
Eric Orth8539e492020-10-19 20:09:55275 return BuildTestDnsResponse(std::move(name), dns_protocol::kTypePTR, answers);
Eric Orthe9db8d232019-01-14 21:24:45276}
277
Eric Ortha97f0f72020-10-16 16:10:32278DnsResponse BuildTestDnsServiceResponse(
Eric Ortha625b042019-01-16 01:14:45279 std::string name,
280 std::vector<TestServiceRecord> service_records,
281 std::string answer_name) {
282 if (answer_name.empty())
283 answer_name = name;
284
285 std::vector<DnsResourceRecord> answers;
286 for (TestServiceRecord& service_record : service_records) {
Eric Orth8539e492020-10-19 20:09:55287 std::string rdata;
288 char num_buffer[2];
289 base::WriteBigEndian(num_buffer, service_record.priority);
290 rdata.append(num_buffer, 2);
291 base::WriteBigEndian(num_buffer, service_record.weight);
292 rdata.append(num_buffer, 2);
293 base::WriteBigEndian(num_buffer, service_record.port);
294 rdata.append(num_buffer, 2);
295 std::string dns_name;
296 CHECK(DNSDomainFromDot(service_record.target, &dns_name));
297 rdata += dns_name;
298
299 answers.push_back(BuildTestDnsRecord(answer_name, dns_protocol::kTypeSRV,
300 std::move(rdata),
301 base::TimeDelta::FromHours(5)));
Eric Ortha625b042019-01-16 01:14:45302 }
303
Eric Orth8539e492020-10-19 20:09:55304 return BuildTestDnsResponse(std::move(name), dns_protocol::kTypeSRV, answers);
Daniel McArdle2daa3ec2020-06-03 16:05:48305}
306
Eric Orth89726dd2020-10-13 20:19:53307MockDnsClientRule::Result::Result(ResultType type,
Anton Bikineev068d2912021-05-15 20:43:52308 absl::optional<DnsResponse> response)
Eric Orth89726dd2020-10-13 20:19:53309 : type(type), response(std::move(response)) {}
Eric Orth828bd3ae2018-12-12 17:30:36310
Eric Ortha97f0f72020-10-16 16:10:32311MockDnsClientRule::Result::Result(DnsResponse response)
Eric Orth828bd3ae2018-12-12 17:30:36312 : type(OK), response(std::move(response)) {}
313
314MockDnsClientRule::Result::Result(Result&& result) = default;
315
316MockDnsClientRule::Result::~Result() = default;
317
318MockDnsClientRule::Result& MockDnsClientRule::Result::operator=(
319 Result&& result) = default;
320
Eric Orth502d5682019-04-12 00:21:33321MockDnsClientRule::MockDnsClientRule(const std::string& prefix,
322 uint16_t qtype,
dalyk4f4ac712019-05-31 16:33:13323 bool secure,
Eric Orth502d5682019-04-12 00:21:33324 Result result,
325 bool delay,
326 URLRequestContext* context)
327 : result(std::move(result)),
328 prefix(prefix),
329 qtype(qtype),
dalyk4f4ac712019-05-31 16:33:13330 secure(secure),
Eric Orth502d5682019-04-12 00:21:33331 delay(delay),
332 context(context) {}
333
334MockDnsClientRule::MockDnsClientRule(MockDnsClientRule&& rule) = default;
335
Eric Orth3421db382019-10-20 02:35:52336// A DnsTransaction which uses MockDnsClientRuleList to determine the response.
337class MockDnsTransactionFactory::MockTransaction
338 : public DnsTransaction,
339 public base::SupportsWeakPtr<MockTransaction> {
[email protected]78eac2a2012-03-14 19:09:27340 public:
Eric Orth3421db382019-10-20 02:35:52341 MockTransaction(const MockDnsClientRuleList& rules,
342 const std::string& hostname,
343 uint16_t qtype,
344 bool secure,
Eric Orth7dc18e92020-02-13 20:27:56345 bool force_doh_server_available,
Eric Ortha093b092020-09-24 23:13:02346 SecureDnsMode secure_dns_mode,
Eric Orth7dc18e92020-02-13 20:27:56347 ResolveContext* resolve_context,
Eric Orth89726dd2020-10-13 20:19:53348 bool fast_timeout,
Eric Orth3421db382019-10-20 02:35:52349 DnsTransactionFactory::CallbackType callback)
350 : result_(MockDnsClientRule::FAIL),
351 hostname_(hostname),
352 qtype_(qtype),
353 callback_(std::move(callback)),
354 started_(false),
355 delayed_(false) {
Eric Orth7dc18e92020-02-13 20:27:56356 // Do not allow matching any rules if transaction is secure and no DoH
357 // servers are available.
358 if (!secure || force_doh_server_available ||
359 resolve_context->NumAvailableDohServers(
360 resolve_context->current_session_for_testing()) > 0) {
361 // Find the relevant rule which matches |qtype|, |secure|, prefix of
362 // |hostname|, and |url_request_context| (iff the rule context is not
363 // null).
364 for (size_t i = 0; i < rules.size(); ++i) {
365 const std::string& prefix = rules[i].prefix;
366 if ((rules[i].qtype == qtype) && (rules[i].secure == secure) &&
367 (hostname.size() >= prefix.size()) &&
368 (hostname.compare(0, prefix.size(), prefix) == 0) &&
369 (!rules[i].context ||
370 rules[i].context == resolve_context->url_request_context())) {
371 const MockDnsClientRule::Result* result = &rules[i].result;
372 result_ = MockDnsClientRule::Result(result->type);
373 delayed_ = rules[i].delay;
[email protected]daae1322013-09-05 18:26:50374
Eric Orth7dc18e92020-02-13 20:27:56375 // Generate a DnsResponse when not provided with the rule.
376 std::vector<DnsResourceRecord> authority_records;
377 std::string dns_name;
378 CHECK(DNSDomainFromDot(hostname_, &dns_name));
Anton Bikineev068d2912021-05-15 20:43:52379 absl::optional<DnsQuery> query(absl::in_place, 22 /* id */, dns_name,
Eric Orth7dc18e92020-02-13 20:27:56380 qtype_);
381 switch (result->type) {
382 case MockDnsClientRule::NODOMAIN:
383 case MockDnsClientRule::EMPTY:
384 DCHECK(!result->response); // Not expected to be provided.
Eric Orth8539e492020-10-19 20:09:55385 authority_records = {BuildTestDnsRecord(
386 hostname_, dns_protocol::kTypeSOA, "fake rdata")};
Eric Ortha97f0f72020-10-16 16:10:32387 result_.response = DnsResponse(
Eric Orth7dc18e92020-02-13 20:27:56388 22 /* id */, false /* is_authoritative */,
389 std::vector<DnsResourceRecord>() /* answers */,
390 authority_records,
391 std::vector<DnsResourceRecord>() /* additional_records */,
392 query,
393 result->type == MockDnsClientRule::NODOMAIN
394 ? dns_protocol::kRcodeNXDOMAIN
395 : 0);
396 break;
397 case MockDnsClientRule::FAIL:
398 case MockDnsClientRule::TIMEOUT:
399 DCHECK(!result->response); // Not expected to be provided.
400 break;
Eric Orth89726dd2020-10-13 20:19:53401 case MockDnsClientRule::SLOW:
402 if (!fast_timeout)
403 SetResponse(result);
404 break;
Eric Orth7dc18e92020-02-13 20:27:56405 case MockDnsClientRule::OK:
Eric Orth89726dd2020-10-13 20:19:53406 SetResponse(result);
Eric Orth7dc18e92020-02-13 20:27:56407 break;
408 case MockDnsClientRule::MALFORMED:
409 DCHECK(!result->response); // Not expected to be provided.
410 result_.response = CreateMalformedResponse(hostname_, qtype_);
411 break;
412 }
Eric Orth2a61be82020-02-12 17:56:48413
Eric Orth7dc18e92020-02-13 20:27:56414 break;
415 }
Eric Orth3421db382019-10-20 02:35:52416 }
[email protected]daae1322013-09-05 18:26:50417 }
[email protected]0adcb2b2012-08-15 21:30:46418 }
419
Eric Orth3421db382019-10-20 02:35:52420 const std::string& GetHostname() const override { return hostname_; }
[email protected]daae1322013-09-05 18:26:50421
Eric Orth3421db382019-10-20 02:35:52422 uint16_t GetType() const override { return qtype_; }
423
424 void Start() override {
425 EXPECT_FALSE(started_);
426 started_ = true;
427 if (delayed_)
428 return;
429 // Using WeakPtr to cleanly cancel when transaction is destroyed.
430 base::ThreadTaskRunnerHandle::Get()->PostTask(
431 FROM_HERE, base::BindOnce(&MockTransaction::Finish, AsWeakPtr()));
432 }
433
434 void FinishDelayedTransaction() {
435 EXPECT_TRUE(delayed_);
436 delayed_ = false;
437 Finish();
438 }
439
440 bool delayed() const { return delayed_; }
441
442 private:
Eric Orth89726dd2020-10-13 20:19:53443 void SetResponse(const MockDnsClientRule::Result* result) {
444 if (result->response) {
445 // Copy response in case |result| is destroyed before the transaction
446 // completes.
Eric Ortha97f0f72020-10-16 16:10:32447 auto buffer_copy =
448 base::MakeRefCounted<IOBuffer>(result->response->io_buffer_size());
449 memcpy(buffer_copy->data(), result->response->io_buffer()->data(),
450 result->response->io_buffer_size());
451 result_.response = DnsResponse(std::move(buffer_copy),
452 result->response->io_buffer_size());
Eric Orth89726dd2020-10-13 20:19:53453 CHECK(result_.response->InitParseWithoutQuery(
454 result->response->io_buffer_size()));
455 } else {
456 // Generated response only available for address types.
457 DCHECK(qtype_ == dns_protocol::kTypeA ||
458 qtype_ == dns_protocol::kTypeAAAA);
Eric Ortha97f0f72020-10-16 16:10:32459 result_.response = BuildTestDnsAddressResponse(
460 hostname_, qtype_ == dns_protocol::kTypeA
461 ? IPAddress::IPv4Localhost()
462 : IPAddress::IPv6Localhost());
Eric Orth89726dd2020-10-13 20:19:53463 }
464 }
465
Eric Orth3421db382019-10-20 02:35:52466 void Finish() {
467 switch (result_.type) {
468 case MockDnsClientRule::NODOMAIN:
469 case MockDnsClientRule::FAIL:
Eric Ortha97f0f72020-10-16 16:10:32470 std::move(callback_).Run(
471 this, ERR_NAME_NOT_RESOLVED,
472 result_.response ? &result_.response.value() : nullptr,
Anton Bikineev068d2912021-05-15 20:43:52473 absl::nullopt);
Eric Orth3421db382019-10-20 02:35:52474 break;
475 case MockDnsClientRule::EMPTY:
476 case MockDnsClientRule::OK:
477 case MockDnsClientRule::MALFORMED:
Eric Ortha97f0f72020-10-16 16:10:32478 std::move(callback_).Run(
479 this, OK, result_.response ? &result_.response.value() : nullptr,
Anton Bikineev068d2912021-05-15 20:43:52480 absl::nullopt);
Eric Orth3421db382019-10-20 02:35:52481 break;
482 case MockDnsClientRule::TIMEOUT:
Daniel McArdle4e2037e2020-06-11 22:40:51483 std::move(callback_).Run(this, ERR_DNS_TIMED_OUT, nullptr,
Anton Bikineev068d2912021-05-15 20:43:52484 absl::nullopt);
Eric Orth3421db382019-10-20 02:35:52485 break;
Eric Orth89726dd2020-10-13 20:19:53486 case MockDnsClientRule::SLOW:
487 if (result_.response) {
Eric Ortha97f0f72020-10-16 16:10:32488 std::move(callback_).Run(
489 this, OK, result_.response ? &result_.response.value() : nullptr,
Anton Bikineev068d2912021-05-15 20:43:52490 absl::nullopt);
Eric Orth89726dd2020-10-13 20:19:53491 } else {
492 std::move(callback_).Run(this, ERR_DNS_TIMED_OUT, nullptr,
Anton Bikineev068d2912021-05-15 20:43:52493 absl::nullopt);
Eric Orth89726dd2020-10-13 20:19:53494 }
Eric Orth3421db382019-10-20 02:35:52495 }
496 }
497
498 void SetRequestPriority(RequestPriority priority) override {}
499
500 MockDnsClientRule::Result result_;
501 const std::string hostname_;
502 const uint16_t qtype_;
503 DnsTransactionFactory::CallbackType callback_;
504 bool started_;
505 bool delayed_;
[email protected]0adcb2b2012-08-15 21:30:46506};
507
Eric Orth41b249e02020-01-03 20:21:47508class MockDnsTransactionFactory::MockDohProbeRunner : public DnsProbeRunner {
509 public:
510 explicit MockDohProbeRunner(base::WeakPtr<MockDnsTransactionFactory> factory)
511 : factory_(std::move(factory)) {}
512
513 ~MockDohProbeRunner() override {
514 if (factory_)
515 factory_->running_doh_probe_runners_.erase(this);
516 }
517
Eric Orth020e5fe2020-03-12 17:43:43518 void Start(bool network_change) override {
Eric Orth41b249e02020-01-03 20:21:47519 DCHECK(factory_);
520 factory_->running_doh_probe_runners_.insert(this);
521 }
522
Eric Orth41b249e02020-01-03 20:21:47523 base::TimeDelta GetDelayUntilNextProbeForTest(
524 size_t doh_server_index) const override {
525 NOTREACHED();
526 return base::TimeDelta();
527 }
528
529 private:
530 base::WeakPtr<MockDnsTransactionFactory> factory_;
531};
532
Eric Orth3421db382019-10-20 02:35:52533MockDnsTransactionFactory::MockDnsTransactionFactory(
534 MockDnsClientRuleList rules)
535 : rules_(std::move(rules)) {}
536
537MockDnsTransactionFactory::~MockDnsTransactionFactory() = default;
538
539std::unique_ptr<DnsTransaction> MockDnsTransactionFactory::CreateTransaction(
540 const std::string& hostname,
541 uint16_t qtype,
542 DnsTransactionFactory::CallbackType callback,
543 const NetLogWithSource&,
544 bool secure,
Eric Ortha093b092020-09-24 23:13:02545 SecureDnsMode secure_dns_mode,
Eric Orth89726dd2020-10-13 20:19:53546 ResolveContext* resolve_context,
547 bool fast_timeout) {
Eric Orth3421db382019-10-20 02:35:52548 std::unique_ptr<MockTransaction> transaction =
Eric Orth069a3c6e2020-01-31 23:14:24549 std::make_unique<MockTransaction>(
Eric Orth7dc18e92020-02-13 20:27:56550 rules_, hostname, qtype, secure, force_doh_server_available_,
Eric Orth89726dd2020-10-13 20:19:53551 secure_dns_mode, resolve_context, fast_timeout, std::move(callback));
Eric Orth3421db382019-10-20 02:35:52552 if (transaction->delayed())
553 delayed_transactions_.push_back(transaction->AsWeakPtr());
554 return transaction;
555}
556
Eric Orth41b249e02020-01-03 20:21:47557std::unique_ptr<DnsProbeRunner> MockDnsTransactionFactory::CreateDohProbeRunner(
Eric Orth069a3c6e2020-01-31 23:14:24558 ResolveContext* resolve_context) {
Eric Orth41b249e02020-01-03 20:21:47559 return std::make_unique<MockDohProbeRunner>(weak_ptr_factory_.GetWeakPtr());
560}
561
Eric Orth3421db382019-10-20 02:35:52562void MockDnsTransactionFactory::AddEDNSOption(const OptRecordRdata::Opt& opt) {}
563
Eric Ortha093b092020-09-24 23:13:02564SecureDnsMode MockDnsTransactionFactory::GetSecureDnsModeForTest() {
565 return SecureDnsMode::kAutomatic;
Eric Orth3421db382019-10-20 02:35:52566}
567
568void MockDnsTransactionFactory::CompleteDelayedTransactions() {
569 DelayedTransactionList old_delayed_transactions;
570 old_delayed_transactions.swap(delayed_transactions_);
571 for (auto it = old_delayed_transactions.begin();
572 it != old_delayed_transactions.end(); ++it) {
573 if (it->get())
574 (*it)->FinishDelayedTransaction();
575 }
576}
577
David Van Cleve1fb5e8c2019-11-04 16:45:16578bool MockDnsTransactionFactory::CompleteOneDelayedTransactionOfType(
579 DnsQueryType type) {
580 for (base::WeakPtr<MockTransaction>& t : delayed_transactions_) {
581 if (t && t->GetType() == DnsQueryTypeToQtype(type)) {
582 t->FinishDelayedTransaction();
583 t.reset();
584 return true;
585 }
586 }
587 return false;
588}
589
Eric Orth394db1732019-08-27 20:09:39590MockDnsClient::MockDnsClient(DnsConfig config, MockDnsClientRuleList rules)
591 : config_(std::move(config)),
Eric Orth3421db382019-10-20 02:35:52592 factory_(new MockDnsTransactionFactory(std::move(rules))),
Eric Orth394db1732019-08-27 20:09:39593 address_sorter_(new MockAddressSorter()) {
594 effective_config_ = BuildEffectiveConfig();
Eric Orthaf82b49a2020-02-01 01:48:50595 session_ = BuildSession();
Eric Orth394db1732019-08-27 20:09:39596}
[email protected]78eac2a2012-03-14 19:09:27597
Chris Watkins68b15032017-12-01 03:07:13598MockDnsClient::~MockDnsClient() = default;
[email protected]78eac2a2012-03-14 19:09:27599
Eric Orth394db1732019-08-27 20:09:39600bool MockDnsClient::CanUseSecureDnsTransactions() const {
601 const DnsConfig* config = GetEffectiveConfig();
602 return config && config->IsValid() && !config->dns_over_https_servers.empty();
[email protected]daae1322013-09-05 18:26:50603}
[email protected]78eac2a2012-03-14 19:09:27604
Eric Orth394db1732019-08-27 20:09:39605bool MockDnsClient::CanUseInsecureDnsTransactions() const {
606 const DnsConfig* config = GetEffectiveConfig();
607 return config && config->IsValid() && insecure_enabled_ &&
608 !config->dns_over_tls_active;
609}
610
Eric Orth09746312021-05-05 15:44:58611bool MockDnsClient::CanQueryAdditionalTypesViaInsecureDns() const {
612 DCHECK(CanUseInsecureDnsTransactions());
613 return additional_types_enabled_;
614}
615
616void MockDnsClient::SetInsecureEnabled(bool enabled,
617 bool additional_types_enabled) {
Eric Orth394db1732019-08-27 20:09:39618 insecure_enabled_ = enabled;
Eric Orth09746312021-05-05 15:44:58619 additional_types_enabled_ = additional_types_enabled;
Eric Orth394db1732019-08-27 20:09:39620}
621
Eric Orth069a3c6e2020-01-31 23:14:24622bool MockDnsClient::FallbackFromSecureTransactionPreferred(
623 ResolveContext* context) const {
Eric Orth7dc18e92020-02-13 20:27:56624 bool doh_server_available =
625 force_doh_server_available_ ||
626 context->NumAvailableDohServers(session_.get()) > 0;
627 return !CanUseSecureDnsTransactions() || !doh_server_available;
dalykc2adf182019-09-02 14:31:22628}
629
Eric Orth394db1732019-08-27 20:09:39630bool MockDnsClient::FallbackFromInsecureTransactionPreferred() const {
631 return !CanUseInsecureDnsTransactions() ||
632 fallback_failures_ >= max_fallback_failures_;
633}
634
Anton Bikineev068d2912021-05-15 20:43:52635bool MockDnsClient::SetSystemConfig(absl::optional<DnsConfig> system_config) {
Eric Orth394db1732019-08-27 20:09:39636 if (ignore_system_config_changes_)
637 return false;
638
Anton Bikineev068d2912021-05-15 20:43:52639 absl::optional<DnsConfig> before = effective_config_;
Eric Orth394db1732019-08-27 20:09:39640 config_ = std::move(system_config);
641 effective_config_ = BuildEffectiveConfig();
Eric Orthaf82b49a2020-02-01 01:48:50642 session_ = BuildSession();
Eric Orth394db1732019-08-27 20:09:39643 return before != effective_config_;
644}
645
646bool MockDnsClient::SetConfigOverrides(DnsConfigOverrides config_overrides) {
Anton Bikineev068d2912021-05-15 20:43:52647 absl::optional<DnsConfig> before = effective_config_;
Eric Orth394db1732019-08-27 20:09:39648 overrides_ = std::move(config_overrides);
649 effective_config_ = BuildEffectiveConfig();
Eric Orthaf82b49a2020-02-01 01:48:50650 session_ = BuildSession();
Eric Orth394db1732019-08-27 20:09:39651 return before != effective_config_;
652}
653
Eric Orth020e5fe2020-03-12 17:43:43654void MockDnsClient::ReplaceCurrentSession() {
655 // Noop if no current effective config.
656 session_ = BuildSession();
657}
658
Eric Orthaf82b49a2020-02-01 01:48:50659DnsSession* MockDnsClient::GetCurrentSession() {
660 return session_.get();
661}
662
Eric Orth394db1732019-08-27 20:09:39663const DnsConfig* MockDnsClient::GetEffectiveConfig() const {
664 return effective_config_.has_value() ? &effective_config_.value() : nullptr;
665}
666
667const DnsHosts* MockDnsClient::GetHosts() const {
668 const DnsConfig* config = GetEffectiveConfig();
669 if (!config)
670 return nullptr;
671
672 return &config->hosts;
[email protected]daae1322013-09-05 18:26:50673}
[email protected]78eac2a2012-03-14 19:09:27674
[email protected]daae1322013-09-05 18:26:50675DnsTransactionFactory* MockDnsClient::GetTransactionFactory() {
Eric Orth394db1732019-08-27 20:09:39676 return GetEffectiveConfig() ? factory_.get() : nullptr;
[email protected]daae1322013-09-05 18:26:50677}
[email protected]78eac2a2012-03-14 19:09:27678
[email protected]daae1322013-09-05 18:26:50679AddressSorter* MockDnsClient::GetAddressSorter() {
Eric Orth394db1732019-08-27 20:09:39680 return GetEffectiveConfig() ? address_sorter_.get() : nullptr;
681}
682
683void MockDnsClient::IncrementInsecureFallbackFailures() {
684 ++fallback_failures_;
685}
686
687void MockDnsClient::ClearInsecureFallbackFailures() {
688 fallback_failures_ = 0;
689}
690
Anton Bikineev068d2912021-05-15 20:43:52691absl::optional<DnsConfig> MockDnsClient::GetSystemConfigForTesting() const {
Eric Orth394db1732019-08-27 20:09:39692 return config_;
693}
694
695DnsConfigOverrides MockDnsClient::GetConfigOverridesForTesting() const {
696 return overrides_;
[email protected]daae1322013-09-05 18:26:50697}
[email protected]0adcb2b2012-08-15 21:30:46698
Eric Orth3421db382019-10-20 02:35:52699void MockDnsClient::SetTransactionFactoryForTesting(
700 std::unique_ptr<DnsTransactionFactory> factory) {
701 NOTREACHED();
702}
703
[email protected]daae1322013-09-05 18:26:50704void MockDnsClient::CompleteDelayedTransactions() {
705 factory_->CompleteDelayedTransactions();
[email protected]78eac2a2012-03-14 19:09:27706}
707
David Van Cleve1fb5e8c2019-11-04 16:45:16708bool MockDnsClient::CompleteOneDelayedTransactionOfType(DnsQueryType type) {
709 return factory_->CompleteOneDelayedTransactionOfType(type);
710}
711
Eric Orth7dc18e92020-02-13 20:27:56712void MockDnsClient::SetForceDohServerAvailable(bool available) {
713 force_doh_server_available_ = available;
714 factory_->set_force_doh_server_available(available);
715}
716
Anton Bikineev068d2912021-05-15 20:43:52717absl::optional<DnsConfig> MockDnsClient::BuildEffectiveConfig() {
Eric Orth394db1732019-08-27 20:09:39718 if (overrides_.OverridesEverything())
719 return overrides_.ApplyOverrides(DnsConfig());
720 if (!config_ || !config_.value().IsValid())
Anton Bikineev068d2912021-05-15 20:43:52721 return absl::nullopt;
Eric Orth394db1732019-08-27 20:09:39722
723 return overrides_.ApplyOverrides(config_.value());
724}
725
Eric Orthaf82b49a2020-02-01 01:48:50726scoped_refptr<DnsSession> MockDnsClient::BuildSession() {
727 if (!effective_config_)
728 return nullptr;
729
730 // Session not expected to be used for anything that will actually require
731 // random numbers.
732 auto null_random_callback =
733 base::BindRepeating([](int, int) -> int { IMMEDIATE_CRASH(); });
734
Eric Orth9300cc62020-08-21 00:29:34735 auto socket_allocator = std::make_unique<DnsSocketAllocator>(
Eric Orth990a74a92020-08-20 18:41:26736 &socket_factory_, effective_config_.value().nameservers,
737 nullptr /* net_log */);
738
Eric Orthaf82b49a2020-02-01 01:48:50739 return base::MakeRefCounted<DnsSession>(
Eric Orth9300cc62020-08-21 00:29:34740 effective_config_.value(), std::move(socket_allocator),
741 null_random_callback, nullptr /* net_log */);
Eric Orthaf82b49a2020-02-01 01:48:50742}
743
[email protected]78eac2a2012-03-14 19:09:27744} // namespace net