1 // Copyright 2012 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 #ifndef NET_DNS_DNS_TEST_UTIL_H_ 6 #define NET_DNS_DNS_TEST_UTIL_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <memory> 12 #include <optional> 13 #include <set> 14 #include <string> 15 #include <string_view> 16 #include <utility> 17 #include <vector> 18 19 #include "base/containers/span.h" 20 #include "base/memory/raw_ptr.h" 21 #include "base/memory/scoped_refptr.h" 22 #include "base/memory/weak_ptr.h" 23 #include "base/synchronization/condition_variable.h" 24 #include "base/time/time.h" 25 #include "base/values.h" 26 #include "net/base/connection_endpoint_metadata.h" 27 #include "net/base/ip_endpoint.h" 28 #include "net/dns/dns_client.h" 29 #include "net/dns/dns_config.h" 30 #include "net/dns/dns_response.h" 31 #include "net/dns/dns_transaction.h" 32 #include "net/dns/dns_util.h" 33 #include "net/dns/public/dns_over_https_server_config.h" 34 #include "net/dns/public/dns_protocol.h" 35 #include "net/dns/public/secure_dns_mode.h" 36 #include "net/socket/socket_test_util.h" 37 #include "url/scheme_host_port.h" 38 39 namespace net { 40 41 //----------------------------------------------------------------------------- 42 // Query/response set for www.google.com, ID is fixed to 0. 43 static const char kT0HostName[] = "www.google.com"; 44 static const uint16_t kT0Qtype = dns_protocol::kTypeA; 45 static const char kT0DnsName[] = { 46 0x03, 'w', 'w', 'w', 47 0x06, 'g', 'o', 'o', 'g', 'l', 'e', 48 0x03, 'c', 'o', 'm', 49 0x00 50 }; 51 static const size_t kT0QuerySize = 32; 52 static const uint8_t kT0ResponseDatagram[] = { 53 // response contains one CNAME for www.l.google.com and the following 54 // IP addresses: 74.125.226.{179,180,176,177,178} 55 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 56 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 57 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x05, 58 0x00, 0x01, 0x00, 0x01, 0x4d, 0x13, 0x00, 0x08, 0x03, 0x77, 0x77, 0x77, 59 0x01, 0x6c, 0xc0, 0x10, 0xc0, 0x2c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 60 0x00, 0xe4, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb3, 0xc0, 0x2c, 0x00, 0x01, 61 0x00, 0x01, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb4, 62 0xc0, 0x2c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x04, 63 0x4a, 0x7d, 0xe2, 0xb0, 0xc0, 0x2c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 64 0x00, 0xe4, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb1, 0xc0, 0x2c, 0x00, 0x01, 65 0x00, 0x01, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb2}; 66 static const char* const kT0IpAddresses[] = { 67 "74.125.226.179", "74.125.226.180", "74.125.226.176", 68 "74.125.226.177", "74.125.226.178" 69 }; 70 static const char kT0CanonName[] = "www.l.google.com"; 71 static const base::TimeDelta kT0Ttl = base::Seconds(0x000000e4); 72 // +1 for the CNAME record. 73 static const unsigned kT0RecordCount = std::size(kT0IpAddresses) + 1; 74 75 //----------------------------------------------------------------------------- 76 // Query/response set for codereview.chromium.org, ID is fixed to 1. 77 static const char kT1HostName[] = "codereview.chromium.org"; 78 static const uint16_t kT1Qtype = dns_protocol::kTypeA; 79 static const char kT1DnsName[] = { 80 0x0a, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', 81 0x08, 'c', 'h', 'r', 'o', 'm', 'i', 'u', 'm', 82 0x03, 'o', 'r', 'g', 83 0x00 84 }; 85 static const size_t kT1QuerySize = 41; 86 static const uint8_t kT1ResponseDatagram[] = { 87 // response contains one CNAME for ghs.l.google.com and the following 88 // IP address: 64.233.169.121 89 0x00, 0x01, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 90 0x00, 0x0a, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x65, 0x76, 0x69, 0x65, 91 0x77, 0x08, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x03, 92 0x6f, 0x72, 0x67, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 93 0x05, 0x00, 0x01, 0x00, 0x01, 0x41, 0x75, 0x00, 0x12, 0x03, 0x67, 94 0x68, 0x73, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 95 0x03, 0x63, 0x6f, 0x6d, 0x00, 0xc0, 0x35, 0x00, 0x01, 0x00, 0x01, 96 0x00, 0x00, 0x01, 0x0b, 0x00, 0x04, 0x40, 0xe9, 0xa9, 0x79}; 97 static const char* const kT1IpAddresses[] = { 98 "64.233.169.121" 99 }; 100 static const char kT1CanonName[] = "ghs.l.google.com"; 101 static const base::TimeDelta kT1Ttl = base::Seconds(0x0000010b); 102 // +1 for the CNAME record. 103 static const unsigned kT1RecordCount = std::size(kT1IpAddresses) + 1; 104 105 //----------------------------------------------------------------------------- 106 // Query/response set for www.ccs.neu.edu, ID is fixed to 2. 107 static const char kT2HostName[] = "www.ccs.neu.edu"; 108 static const uint16_t kT2Qtype = dns_protocol::kTypeA; 109 static const char kT2DnsName[] = { 110 0x03, 'w', 'w', 'w', 111 0x03, 'c', 'c', 's', 112 0x03, 'n', 'e', 'u', 113 0x03, 'e', 'd', 'u', 114 0x00 115 }; 116 static const size_t kT2QuerySize = 33; 117 static const uint8_t kT2ResponseDatagram[] = { 118 // response contains one CNAME for vulcan.ccs.neu.edu and the following 119 // IP address: 129.10.116.81 120 0x00, 0x02, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 121 0x03, 0x77, 0x77, 0x77, 0x03, 0x63, 0x63, 0x73, 0x03, 0x6e, 0x65, 0x75, 122 0x03, 0x65, 0x64, 0x75, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 123 0x05, 0x00, 0x01, 0x00, 0x00, 0x01, 0x2c, 0x00, 0x09, 0x06, 0x76, 0x75, 124 0x6c, 0x63, 0x61, 0x6e, 0xc0, 0x10, 0xc0, 0x2d, 0x00, 0x01, 0x00, 0x01, 125 0x00, 0x00, 0x01, 0x2c, 0x00, 0x04, 0x81, 0x0a, 0x74, 0x51}; 126 static const char* const kT2IpAddresses[] = { 127 "129.10.116.81" 128 }; 129 static const char kT2CanonName[] = "vulcan.ccs.neu.edu"; 130 static const base::TimeDelta kT2Ttl = base::Seconds(0x0000012c); 131 // +1 for the CNAME record. 132 static const unsigned kT2RecordCount = std::size(kT2IpAddresses) + 1; 133 134 //----------------------------------------------------------------------------- 135 // Query/response set for www.google.az, ID is fixed to 3. 136 static const char kT3HostName[] = "www.google.az"; 137 static const uint16_t kT3Qtype = dns_protocol::kTypeA; 138 static const char kT3DnsName[] = { 139 0x03, 'w', 'w', 'w', 140 0x06, 'g', 'o', 'o', 'g', 'l', 'e', 141 0x02, 'a', 'z', 142 0x00 143 }; 144 static const size_t kT3QuerySize = 31; 145 static const uint8_t kT3ResponseDatagram[] = { 146 // response contains www.google.com as CNAME for www.google.az and 147 // www.l.google.com as CNAME for www.google.com and the following 148 // IP addresses: 74.125.226.{178,179,180,176,177} 149 // The TTLs on the records are: 0x00015099, 0x00025099, 0x00000415, 150 // 0x00003015, 0x00002015, 0x00000015, 0x00001015. 151 // The last record is an imaginary TXT record for t.google.com. 152 0x00, 0x03, 0x81, 0x80, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 153 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x02, 154 0x61, 0x7a, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x05, 0x00, 155 0x01, 0x00, 0x01, 0x50, 0x99, 0x00, 0x10, 0x03, 0x77, 0x77, 0x77, 0x06, 156 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0xc0, 157 0x2b, 0x00, 0x05, 0x00, 0x01, 0x00, 0x02, 0x50, 0x99, 0x00, 0x08, 0x03, 158 0x77, 0x77, 0x77, 0x01, 0x6c, 0xc0, 0x2f, 0xc0, 0x47, 0x00, 0x01, 0x00, 159 0x01, 0x00, 0x00, 0x04, 0x15, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb2, 0xc0, 160 0x47, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x30, 0x15, 0x00, 0x04, 0x4a, 161 0x7d, 0xe2, 0xb3, 0xc0, 0x47, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x20, 162 0x15, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb4, 0xc0, 0x47, 0x00, 0x01, 0x00, 163 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb0, 0xc0, 164 0x47, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10, 0x15, 0x00, 0x04, 0x4a, 165 0x7d, 0xe2, 0xb1, 0x01, 0x74, 0xc0, 0x2f, 0x00, 0x10, 0x00, 0x01, 0x00, 166 0x00, 0x00, 0x01, 0x00, 0x04, 0xde, 0xad, 0xfe, 0xed}; 167 static const char* const kT3IpAddresses[] = { 168 "74.125.226.178", "74.125.226.179", "74.125.226.180", 169 "74.125.226.176", "74.125.226.177" 170 }; 171 static const char kT3CanonName[] = "www.l.google.com"; 172 static const base::TimeDelta kT3Ttl = base::Seconds(0x00000015); 173 // +2 for the CNAME records, +1 for TXT record. 174 static const unsigned kT3RecordCount = std::size(kT3IpAddresses) + 3; 175 176 //----------------------------------------------------------------------------- 177 // Query/response set for www.gstatic.com, ID is fixed to 0. 178 static const char kT4HostName[] = "www.gstatic.com"; 179 static const uint16_t kT4Qtype = dns_protocol::kTypeA; 180 static const char kT4DnsName[] = {0x03, 'w', 'w', 'w', 0x07, 'g', 181 's', 't', 'a', 't', 'i', 'c', 182 0x03, 'c', 'o', 'm', 0x00}; 183 static const size_t kT4QuerySize = 33; 184 static const uint8_t kT4ResponseDatagram[] = { 185 // response contains the following IP addresses: 172.217.6.195. 186 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 187 0x00, 0x00, 0x03, 0x77, 0x77, 0x77, 0x07, 0x67, 0x73, 0x74, 188 0x61, 0x74, 0x69, 0x63, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 189 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 190 0x00, 0x01, 0x2b, 0x00, 0x04, 0xac, 0xd9, 0x06, 0xc3}; 191 192 static const char* const kT4IpAddresses[] = {"172.217.6.195"}; 193 static const base::TimeDelta kT4Ttl = base::Seconds(0x0000012b); 194 static const unsigned kT4RecordCount = std::size(kT0IpAddresses); 195 196 class AddressSorter; 197 class DnsClient; 198 class DnsSession; 199 class IPAddress; 200 class ResolveContext; 201 class URLRequestContext; 202 203 DnsConfig CreateValidDnsConfig(); 204 205 DnsResourceRecord BuildTestDnsRecord(std::string name, 206 uint16_t type, 207 std::string rdata, 208 base::TimeDelta ttl = base::Days(1)); 209 210 DnsResourceRecord BuildTestCnameRecord(std::string name, 211 std::string_view canonical_name, 212 base::TimeDelta ttl = base::Days(1)); 213 214 DnsResourceRecord BuildTestAddressRecord(std::string name, 215 const IPAddress& ip, 216 base::TimeDelta ttl = base::Days(1)); 217 218 DnsResourceRecord BuildTestTextRecord(std::string name, 219 std::vector<std::string> text_strings, 220 base::TimeDelta ttl = base::Days(1)); 221 222 DnsResourceRecord BuildTestHttpsAliasRecord( 223 std::string name, 224 std::string_view alias_name, 225 base::TimeDelta ttl = base::Days(1)); 226 227 std::pair<uint16_t, std::string> BuildTestHttpsServiceAlpnParam( 228 const std::vector<std::string>& alpns); 229 230 std::pair<uint16_t, std::string> BuildTestHttpsServiceEchConfigParam( 231 base::span<const uint8_t> ech_config_list); 232 233 std::pair<uint16_t, std::string> BuildTestHttpsServiceMandatoryParam( 234 std::vector<uint16_t> param_key_list); 235 236 std::pair<uint16_t, std::string> BuildTestHttpsServicePortParam(uint16_t port); 237 238 // `params` is a mapping from service param keys to a string containing the 239 // encoded bytes of a service param value (without the value length prefix which 240 // this method will automatically add). 241 DnsResourceRecord BuildTestHttpsServiceRecord( 242 std::string name, 243 uint16_t priority, 244 std::string_view service_name, 245 const std::map<uint16_t, std::string>& params, 246 base::TimeDelta ttl = base::Days(1)); 247 248 DnsResponse BuildTestDnsResponse( 249 std::string name, 250 uint16_t type, 251 const std::vector<DnsResourceRecord>& answers, 252 const std::vector<DnsResourceRecord>& authority = {}, 253 const std::vector<DnsResourceRecord>& additional = {}, 254 uint8_t rcode = dns_protocol::kRcodeNOERROR); 255 256 DnsResponse BuildTestDnsAddressResponse(std::string name, 257 const IPAddress& ip, 258 std::string answer_name = ""); 259 DnsResponse BuildTestDnsAddressResponseWithCname(std::string name, 260 const IPAddress& ip, 261 std::string cannonname, 262 std::string answer_name = ""); 263 264 // If |answer_name| is empty, |name| will be used for all answer records, as is 265 // the normal behavior. 266 DnsResponse BuildTestDnsTextResponse( 267 std::string name, 268 std::vector<std::vector<std::string>> text_records, 269 std::string answer_name = ""); 270 DnsResponse BuildTestDnsPointerResponse(std::string name, 271 std::vector<std::string> pointer_names, 272 std::string answer_name = ""); 273 274 struct TestServiceRecord { 275 uint16_t priority; 276 uint16_t weight; 277 uint16_t port; 278 std::string target; 279 }; 280 281 DnsResponse BuildTestDnsServiceResponse( 282 std::string name, 283 std::vector<TestServiceRecord> service_records, 284 std::string answer_name = ""); 285 286 struct MockDnsClientRule { 287 enum class ResultType { 288 // Fail asynchronously with ERR_NAME_NOT_RESOLVED and NXDOMAIN. 289 kNoDomain, 290 // Fail asynchronously with `net_error` or (if nullopt) 291 // ERR_NAME_NOT_RESOLVED and `response` if not nullopt. 292 kFail, 293 // Fail asynchronously with ERR_DNS_TIMED_OUT. 294 kTimeout, 295 // Simulates a slow transaction that will complete only with a lenient 296 // timeout. Fails asynchronously with ERR_DNS_TIMED_OUT only if the 297 // transaction was created with |fast_timeout|. Otherwise completes 298 // successfully as if the ResultType were |kOk|. 299 kSlow, 300 // Return an empty response. 301 kEmpty, 302 // "Succeed" but with an unparsable response. 303 kMalformed, 304 // Immediately records a test failure if queried. Used to catch unexpected 305 // queries. Alternately, if combined with `MockDnsClientRule::delay`, fails 306 // only if the query is allowed to complete without being cancelled. 307 kUnexpected, 308 309 // Results in the response in |Result::response| or, if null, results in a 310 // localhost IP response. 311 kOk, 312 }; 313 314 struct Result { 315 explicit Result(ResultType type, 316 std::optional<DnsResponse> response = std::nullopt, 317 std::optional<int> net_error = std::nullopt); 318 explicit Result(DnsResponse response); 319 Result(Result&&); 320 Result& operator=(Result&&); 321 ~Result(); 322 323 ResultType type; 324 std::optional<DnsResponse> response; 325 std::optional<int> net_error; 326 }; 327 328 // If |delay| is true, matching transactions will be delayed until triggered 329 // by the consumer. If |context| is non-null, it will only match transactions 330 // with the same context. 331 MockDnsClientRule(const std::string& prefix, 332 uint16_t qtype, 333 bool secure, 334 Result result, 335 bool delay, 336 URLRequestContext* context = nullptr); 337 MockDnsClientRule(MockDnsClientRule&& rule); 338 339 Result result; 340 std::string prefix; 341 uint16_t qtype; 342 bool secure; 343 bool delay; 344 raw_ptr<URLRequestContext, DanglingUntriaged> context; 345 }; 346 347 typedef std::vector<MockDnsClientRule> MockDnsClientRuleList; 348 349 // A DnsTransactionFactory which creates MockTransaction. 350 class MockDnsTransactionFactory : public DnsTransactionFactory { 351 public: 352 explicit MockDnsTransactionFactory(MockDnsClientRuleList rules); 353 ~MockDnsTransactionFactory() override; 354 355 std::unique_ptr<DnsTransaction> CreateTransaction( 356 std::string hostname, 357 uint16_t qtype, 358 const NetLogWithSource&, 359 bool secure, 360 SecureDnsMode secure_dns_mode, 361 ResolveContext* resolve_context, 362 bool fast_timeout) override; 363 364 std::unique_ptr<DnsProbeRunner> CreateDohProbeRunner( 365 ResolveContext* resolve_context) override; 366 367 void AddEDNSOption(std::unique_ptr<OptRecordRdata::Opt> opt) override; 368 369 SecureDnsMode GetSecureDnsModeForTest() override; 370 371 void CompleteDelayedTransactions(); 372 // If there are any pending transactions of the given type, 373 // completes one and returns true. Otherwise, returns false. 374 [[nodiscard]] bool CompleteOneDelayedTransactionOfType(DnsQueryType type); 375 doh_probes_running()376 bool doh_probes_running() { return !running_doh_probe_runners_.empty(); } CompleteDohProbeRuners()377 void CompleteDohProbeRuners() { running_doh_probe_runners_.clear(); } 378 set_force_doh_server_available(bool available)379 void set_force_doh_server_available(bool available) { 380 force_doh_server_available_ = available; 381 } 382 383 private: 384 class MockTransaction; 385 class MockDohProbeRunner; 386 using DelayedTransactionList = std::vector<base::WeakPtr<MockTransaction>>; 387 388 MockDnsClientRuleList rules_; 389 DelayedTransactionList delayed_transactions_; 390 391 bool force_doh_server_available_ = true; 392 std::set<raw_ptr<MockDohProbeRunner, SetExperimental>> 393 running_doh_probe_runners_; 394 395 base::WeakPtrFactory<MockDnsTransactionFactory> weak_ptr_factory_{this}; 396 }; 397 398 // MockDnsClient provides MockDnsTransactionFactory. 399 class MockDnsClient : public DnsClient { 400 public: 401 MockDnsClient(DnsConfig config, MockDnsClientRuleList rules); 402 ~MockDnsClient() override; 403 404 // DnsClient interface: 405 bool CanUseSecureDnsTransactions() const override; 406 bool CanUseInsecureDnsTransactions() const override; 407 bool CanQueryAdditionalTypesViaInsecureDns() const override; 408 void SetInsecureEnabled(bool enabled, bool additional_types_enabled) override; 409 bool FallbackFromSecureTransactionPreferred( 410 ResolveContext* resolve_context) const override; 411 bool FallbackFromInsecureTransactionPreferred() const override; 412 bool SetSystemConfig(std::optional<DnsConfig> system_config) override; 413 bool SetConfigOverrides(DnsConfigOverrides config_overrides) override; 414 void ReplaceCurrentSession() override; 415 DnsSession* GetCurrentSession() override; 416 const DnsConfig* GetEffectiveConfig() const override; 417 const DnsHosts* GetHosts() const override; 418 DnsTransactionFactory* GetTransactionFactory() override; 419 AddressSorter* GetAddressSorter() override; 420 void IncrementInsecureFallbackFailures() override; 421 void ClearInsecureFallbackFailures() override; 422 base::Value::Dict GetDnsConfigAsValueForNetLog() const override; 423 std::optional<DnsConfig> GetSystemConfigForTesting() const override; 424 DnsConfigOverrides GetConfigOverridesForTesting() const override; 425 void SetTransactionFactoryForTesting( 426 std::unique_ptr<DnsTransactionFactory> factory) override; 427 void SetAddressSorterForTesting( 428 std::unique_ptr<AddressSorter> address_sorter) override; 429 std::optional<std::vector<IPEndPoint>> GetPresetAddrs( 430 const url::SchemeHostPort& endpoint) const override; 431 432 // Completes all DnsTransactions that were delayed by a rule. 433 void CompleteDelayedTransactions(); 434 // If there are any pending transactions of the given type, 435 // completes one and returns true. Otherwise, returns false. 436 [[nodiscard]] bool CompleteOneDelayedTransactionOfType(DnsQueryType type); 437 set_max_fallback_failures(int max_fallback_failures)438 void set_max_fallback_failures(int max_fallback_failures) { 439 max_fallback_failures_ = max_fallback_failures; 440 } 441 set_ignore_system_config_changes(bool ignore_system_config_changes)442 void set_ignore_system_config_changes(bool ignore_system_config_changes) { 443 ignore_system_config_changes_ = ignore_system_config_changes; 444 } 445 set_preset_endpoint(std::optional<url::SchemeHostPort> endpoint)446 void set_preset_endpoint(std::optional<url::SchemeHostPort> endpoint) { 447 preset_endpoint_ = std::move(endpoint); 448 } 449 set_preset_addrs(std::vector<IPEndPoint> preset_addrs)450 void set_preset_addrs(std::vector<IPEndPoint> preset_addrs) { 451 preset_addrs_ = std::move(preset_addrs); 452 } 453 454 void SetForceDohServerAvailable(bool available); 455 factory()456 MockDnsTransactionFactory* factory() { return factory_.get(); } 457 458 private: 459 std::optional<DnsConfig> BuildEffectiveConfig(); 460 scoped_refptr<DnsSession> BuildSession(); 461 462 bool insecure_enabled_ = false; 463 bool additional_types_enabled_ = false; 464 int fallback_failures_ = 0; 465 int max_fallback_failures_ = DnsClient::kMaxInsecureFallbackFailures; 466 bool ignore_system_config_changes_ = false; 467 468 // If |true|, MockDnsClient will always pretend DoH servers are available and 469 // allow secure transactions no matter what the state is in the transaction 470 // ResolveContext. If |false|, the ResolveContext must contain at least one 471 // available DoH server to allow secure transactions. 472 bool force_doh_server_available_ = true; 473 474 MockClientSocketFactory socket_factory_; 475 std::optional<DnsConfig> config_; 476 scoped_refptr<DnsSession> session_; 477 DnsConfigOverrides overrides_; 478 std::optional<DnsConfig> effective_config_; 479 std::unique_ptr<MockDnsTransactionFactory> factory_; 480 std::unique_ptr<AddressSorter> address_sorter_; 481 std::optional<url::SchemeHostPort> preset_endpoint_; 482 std::optional<std::vector<IPEndPoint>> preset_addrs_; 483 }; 484 485 // A HostResolverProc that pushes each host mapped into a list and allows 486 // waiting for a specific number of requests. Unlike RuleBasedHostResolverProc 487 // it never calls SystemHostResolverCall. By default resolves all hostnames to 488 // "127.0.0.1". After AddRule(), it resolves only names explicitly specified. 489 class MockHostResolverProc : public HostResolverProc { 490 public: 491 struct ResolveKey { ResolveKeyResolveKey492 ResolveKey(const std::string& hostname, 493 AddressFamily address_family, 494 HostResolverFlags flags) 495 : hostname(hostname), address_family(address_family), flags(flags) {} 496 bool operator<(const ResolveKey& other) const { 497 return std::tie(address_family, hostname, flags) < 498 std::tie(other.address_family, other.hostname, other.flags); 499 } 500 std::string hostname; 501 AddressFamily address_family; 502 HostResolverFlags flags; 503 }; 504 505 typedef std::vector<ResolveKey> CaptureList; 506 507 MockHostResolverProc(); 508 509 MockHostResolverProc(const MockHostResolverProc&) = delete; 510 MockHostResolverProc& operator=(const MockHostResolverProc&) = delete; 511 512 // Waits until `count` calls to `Resolve` are blocked. Returns false when 513 // timed out. 514 bool WaitFor(unsigned count); 515 516 // Signals `count` waiting calls to `Resolve`. First come first served. 517 void SignalMultiple(unsigned count); 518 519 // Signals all waiting calls to `Resolve`. Beware of races. 520 void SignalAll(); 521 522 void AddRule(const std::string& hostname, 523 AddressFamily family, 524 const AddressList& result, 525 HostResolverFlags flags = 0); 526 527 void AddRule(const std::string& hostname, 528 AddressFamily family, 529 const std::string& ip_list, 530 HostResolverFlags flags = 0, 531 const std::string& canonical_name = ""); 532 533 void AddRuleForAllFamilies(const std::string& hostname, 534 const std::string& ip_list, 535 HostResolverFlags flags = 0, 536 const std::string& canonical_name = ""); 537 538 int Resolve(const std::string& hostname, 539 AddressFamily address_family, 540 HostResolverFlags host_resolver_flags, 541 AddressList* addrlist, 542 int* os_error) override; 543 544 CaptureList GetCaptureList() const; 545 546 void ClearCaptureList(); 547 548 bool HasBlockedRequests() const; 549 550 protected: 551 ~MockHostResolverProc() override; 552 553 private: 554 mutable base::Lock lock_; 555 std::map<ResolveKey, AddressList> rules_; 556 CaptureList capture_list_; 557 unsigned num_requests_waiting_ = 0; 558 unsigned num_slots_available_ = 0; 559 base::ConditionVariable requests_waiting_; 560 base::ConditionVariable slots_available_; 561 }; 562 563 } // namespace net 564 565 #endif // NET_DNS_DNS_TEST_UTIL_H_ 566