1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define LOG_TAG "resolv" 18 19 #include <aidl/android/net/IDnsResolver.h> 20 #include <android-base/stringprintf.h> 21 #include <arpa/inet.h> 22 #include <gmock/gmock-matchers.h> 23 #include <gtest/gtest.h> 24 #include <netdb.h> 25 #include <netdutils/InternetAddresses.h> 26 #include <resolv_stats_test_utils.h> 27 28 #include "dns_responder.h" 29 #include "getaddrinfo.h" 30 #include "gethnamaddr.h" 31 #include "resolv_cache.h" 32 #include "stats.pb.h" 33 #include "tests/resolv_test_utils.h" 34 35 #define NAME(variable) #variable 36 37 namespace android { 38 namespace net { 39 40 using aidl::android::net::IDnsResolver; 41 using android::base::StringPrintf; 42 using android::net::NetworkDnsEventReported; 43 using android::netdutils::ScopedAddrinfo; 44 45 // The buffer size of resolv_gethostbyname(). 46 constexpr unsigned int MAXPACKET = 8 * 1024; 47 48 // Specifying 0 in ai_socktype or ai_protocol of struct addrinfo indicates 49 // that any type or protocol can be returned by getaddrinfo(). 50 constexpr unsigned int ANY = 0; 51 52 class TestBase : public ::testing::Test { 53 protected: 54 struct DnsMessage { 55 std::string host_name; // host name 56 ns_type type; // record type 57 test::DNSHeader header; // dns header 58 }; 59 60 void SetUp() override { 61 // Create cache for test 62 resolv_create_cache_for_net(TEST_NETID); 63 } 64 void TearDown() override { 65 // Delete cache for test 66 resolv_delete_cache_for_net(TEST_NETID); 67 } 68 69 test::DNSRecord MakeAnswerRecord(const std::string& name, unsigned rclass, unsigned rtype, 70 const std::string& rdata, unsigned ttl = kAnswerRecordTtlSec) { 71 test::DNSRecord record{ 72 .name = {.name = name}, 73 .rtype = rtype, 74 .rclass = rclass, 75 .ttl = ttl, 76 }; 77 EXPECT_TRUE(test::DNSResponder::fillRdata(rdata, record)); 78 return record; 79 } 80 81 DnsMessage MakeDnsMessage(const std::string& qname, ns_type qtype, 82 const std::vector<std::string>& rdata) { 83 const unsigned qclass = ns_c_in; 84 // Build a DNSHeader in the following format. 85 // Question 86 // <qname> IN <qtype> 87 // Answer 88 // <qname> IN <qtype> <rdata[0]> 89 // .. 90 // <qname> IN <qtype> <rdata[n]> 91 // 92 // Example: 93 // Question 94 // hello.example.com. IN A 95 // Answer 96 // hello.example.com. IN A 1.2.3.1 97 // .. 98 // hello.example.com. IN A 1.2.3.9 99 test::DNSHeader header(kDefaultDnsHeader); 100 101 // Question section 102 test::DNSQuestion question{ 103 .qname = {.name = qname}, 104 .qtype = qtype, 105 .qclass = qclass, 106 }; 107 header.questions.push_back(std::move(question)); 108 109 // Answer section 110 for (const auto& r : rdata) { 111 test::DNSRecord record = MakeAnswerRecord(qname, qclass, qtype, r); 112 header.answers.push_back(std::move(record)); 113 } 114 // TODO: Perhaps add support for authority RRs and additional RRs. 115 return {qname, qtype, header}; 116 } 117 118 void StartDns(test::DNSResponder& dns, const std::vector<DnsMessage>& messages) { 119 for (const auto& m : messages) { 120 dns.addMappingDnsHeader(m.host_name, m.type, m.header); 121 } 122 ASSERT_TRUE(dns.startServer()); 123 dns.clearQueries(); 124 } 125 126 int SetResolvers() { return SetResolvers(servers); } 127 128 int SetResolvers(std::vector<std::string> servers) { 129 return resolv_set_nameservers(TEST_NETID, servers, domains, params, std::nullopt); 130 } 131 132 const android_net_context mNetcontext = { 133 .app_netid = TEST_NETID, 134 .app_mark = MARK_UNSET, 135 .dns_netid = TEST_NETID, 136 .dns_mark = MARK_UNSET, 137 .uid = NET_CONTEXT_INVALID_UID, 138 }; 139 const std::vector<std::string> servers = {test::kDefaultListenAddr}; 140 const std::vector<std::string> domains = {"example.com"}; 141 const res_params params = { 142 .sample_validity = 300, 143 .success_threshold = 25, 144 .min_samples = 8, 145 .max_samples = 8, 146 .base_timeout_msec = 1000, 147 .retry_count = 2, 148 }; 149 }; 150 151 class ResolvGetAddrInfoTest : public TestBase {}; 152 class GetHostByNameForNetContextTest : public TestBase {}; 153 class ResolvCommonFunctionTest : public TestBase {}; 154 155 TEST_F(ResolvGetAddrInfoTest, InvalidParameters) { 156 // Both null "netcontext" and null "res" of resolv_getaddrinfo() are not tested 157 // here because they are checked by assert() without returning any error number. 158 159 // Invalid hostname and servname. 160 // Both hostname and servname are null pointers. Expect error number EAI_NONAME. 161 { 162 addrinfo* result = nullptr; 163 NetworkDnsEventReported event; 164 int rv = resolv_getaddrinfo(nullptr /*hostname*/, nullptr /*servname*/, nullptr /*hints*/, 165 &mNetcontext, &result, &event); 166 ScopedAddrinfo result_cleanup(result); 167 EXPECT_EQ(EAI_NONAME, rv); 168 } 169 170 // Invalid hints. 171 // These place holders are used to test function call with unrequired parameters. 172 // The content is not important because function call returns error directly if 173 // there have any unrequired parameter. 174 char placeholder_cname[] = "invalid_cname"; 175 sockaddr placeholder_addr = {}; 176 addrinfo placeholder_next = {}; 177 static const struct TestConfig { 178 int ai_flags; 179 socklen_t ai_addrlen; 180 char* ai_canonname; 181 sockaddr* ai_addr; 182 addrinfo* ai_next; 183 184 int expected_eai_error; 185 186 std::string asParameters() const { 187 return StringPrintf("0x%x/%u/%s/%p/%p", ai_flags, ai_addrlen, 188 ai_canonname ? ai_canonname : "(null)", (void*)ai_addr, 189 (void*)ai_next); 190 } 191 } testConfigs[]{ 192 {0, sizeof(in_addr) /*bad*/, nullptr, nullptr, nullptr, EAI_BADHINTS}, 193 {0, 0, placeholder_cname /*bad*/, nullptr, nullptr, EAI_BADHINTS}, 194 {0, 0, nullptr, &placeholder_addr /*bad*/, nullptr, EAI_BADHINTS}, 195 {0, 0, nullptr, nullptr, &placeholder_next /*bad*/, EAI_BADHINTS}, 196 {AI_ALL /*bad*/, 0, nullptr, nullptr, nullptr, EAI_BADFLAGS}, 197 {AI_V4MAPPED_CFG /*bad*/, 0, nullptr, nullptr, nullptr, EAI_BADFLAGS}, 198 {AI_V4MAPPED /*bad*/, 0, nullptr, nullptr, nullptr, EAI_BADFLAGS}, 199 {AI_DEFAULT /*bad*/, 0, nullptr, nullptr, nullptr, EAI_BADFLAGS}, 200 }; 201 202 for (const auto& config : testConfigs) { 203 SCOPED_TRACE(config.asParameters()); 204 205 addrinfo* result = nullptr; 206 // In current test configuration set, ai_family, ai_protocol and ai_socktype are not 207 // checked because other fields cause hints error check failed first. 208 const addrinfo hints = { 209 .ai_flags = config.ai_flags, 210 .ai_family = AF_UNSPEC, 211 .ai_socktype = ANY, 212 .ai_protocol = ANY, 213 .ai_addrlen = config.ai_addrlen, 214 .ai_canonname = config.ai_canonname, 215 .ai_addr = config.ai_addr, 216 .ai_next = config.ai_next, 217 }; 218 NetworkDnsEventReported event; 219 int rv = resolv_getaddrinfo("localhost", nullptr /*servname*/, &hints, &mNetcontext, 220 &result, &event); 221 ScopedAddrinfo result_cleanup(result); 222 EXPECT_EQ(config.expected_eai_error, rv); 223 } 224 } 225 226 TEST_F(ResolvGetAddrInfoTest, InvalidParameters_Family) { 227 for (int family = 0; family < AF_MAX; ++family) { 228 if (family == AF_UNSPEC || family == AF_INET || family == AF_INET6) { 229 continue; // skip supported family 230 } 231 SCOPED_TRACE(StringPrintf("family: %d", family)); 232 233 addrinfo* result = nullptr; 234 const addrinfo hints = { 235 .ai_family = family, // unsupported family 236 }; 237 NetworkDnsEventReported event; 238 int rv = resolv_getaddrinfo("localhost", nullptr /*servname*/, &hints, &mNetcontext, 239 &result, &event); 240 ScopedAddrinfo result_cleanup(result); 241 EXPECT_EQ(EAI_FAMILY, rv); 242 } 243 } 244 245 TEST_F(ResolvGetAddrInfoTest, InvalidParameters_SocketType) { 246 for (const auto& family : {AF_INET, AF_INET6, AF_UNSPEC}) { 247 for (int protocol = 0; protocol < IPPROTO_MAX; ++protocol) { 248 // Socket types which are not in explore_options. 249 for (const auto& socktype : {SOCK_RDM, SOCK_SEQPACKET, SOCK_DCCP, SOCK_PACKET}) { 250 const addrinfo hints = { 251 .ai_family = family, 252 .ai_socktype = socktype, 253 .ai_protocol = protocol, 254 }; 255 for (const char* service : {static_cast<const char*>(nullptr), // service is null 256 "80", 257 "", // empty service name 258 "ftp", 259 "65536", // out of valid port range from 0 to 65535 260 "invalid"}) { 261 SCOPED_TRACE(StringPrintf("family: %d, socktype: %d, protocol: %d, service: %s", 262 family, socktype, protocol, 263 service ? service : "service is nullptr")); 264 addrinfo* result = nullptr; 265 NetworkDnsEventReported event; 266 int rv = resolv_getaddrinfo("localhost", service, &hints, &mNetcontext, &result, 267 &event); 268 ScopedAddrinfo result_cleanup(result); 269 EXPECT_EQ(EAI_SOCKTYPE, rv); 270 } 271 } 272 } 273 } 274 } 275 276 TEST_F(ResolvGetAddrInfoTest, InvalidParameters_MeaningfulSocktypeAndProtocolCombination) { 277 static const int families[] = {PF_INET, PF_INET6, PF_UNSPEC}; 278 // Skip to test socket type SOCK_RAW in meaningful combination (explore_options[]) of 279 // system\netd\resolv\getaddrinfo.cpp. In explore_options[], the socket type SOCK_RAW always 280 // comes with protocol ANY which causes skipping meaningful socktype/protocol combination 281 // check. So it nerver returns error number EAI_BADHINTS which we want to test in this test 282 // case. 283 static const int socktypes[] = {SOCK_STREAM, SOCK_DGRAM}; 284 285 // If both socktype/protocol are specified, check non-meaningful combination returns 286 // expected error number EAI_BADHINTS. See meaningful combination in explore_options[] of 287 // system\netd\resolv\getaddrinfo.cpp. 288 for (const auto& family : families) { 289 for (const auto& socktype : socktypes) { 290 for (int protocol = 0; protocol < IPPROTO_MAX; ++protocol) { 291 SCOPED_TRACE(StringPrintf("family: %d, socktype: %d, protocol: %d", family, 292 socktype, protocol)); 293 294 // Both socktype/protocol need to be specified. 295 if (!socktype || !protocol) continue; 296 297 // Skip meaningful combination in explore_options[] of 298 // system\netd\resolv\getaddrinfo.cpp. 299 if ((family == AF_INET6 && socktype == SOCK_DGRAM && protocol == IPPROTO_UDP) || 300 (family == AF_INET6 && socktype == SOCK_STREAM && protocol == IPPROTO_TCP) || 301 (family == AF_INET && socktype == SOCK_DGRAM && protocol == IPPROTO_UDP) || 302 (family == AF_INET && socktype == SOCK_STREAM && protocol == IPPROTO_TCP) || 303 (family == AF_UNSPEC && socktype == SOCK_DGRAM && protocol == IPPROTO_UDP) || 304 (family == AF_UNSPEC && socktype == SOCK_STREAM && protocol == IPPROTO_TCP)) { 305 continue; 306 } 307 308 addrinfo* result = nullptr; 309 const addrinfo hints = { 310 .ai_family = family, 311 .ai_socktype = socktype, 312 .ai_protocol = protocol, 313 }; 314 NetworkDnsEventReported event; 315 int rv = resolv_getaddrinfo("localhost", nullptr /*servname*/, &hints, &mNetcontext, 316 &result, &event); 317 ScopedAddrinfo result_cleanup(result); 318 EXPECT_EQ(EAI_BADHINTS, rv); 319 } 320 } 321 } 322 } 323 324 // The test configs are used for verifying the error path of get_port(). 325 // Note that the EAI_SOCKTYPE verification are moved to an independent 326 // test case because validateHints() verify invalid socket type early now. 327 // See also InvalidParameters_SocketType. 328 TEST_F(ResolvGetAddrInfoTest, InvalidParameters_PortNameAndNumber) { 329 constexpr char http_portno[] = "80"; 330 constexpr char invalid_portno[] = "65536"; // out of valid port range from 0 to 65535 331 constexpr char http_portname[] = "http"; 332 constexpr char invalid_portname[] = "invalid_portname"; 333 334 static const struct TestConfig { 335 int ai_flags; 336 int ai_family; 337 int ai_socktype; 338 const char* servname; 339 340 int expected_eai_error; 341 342 std::string asParameters() const { 343 return StringPrintf("0x%x/%d/%d/%s", ai_flags, ai_family, ai_socktype, 344 servname ? servname : "(null)"); 345 } 346 } testConfigs[]{ 347 {0, AF_INET, SOCK_RAW /*bad*/, http_portno, EAI_SERVICE}, 348 {0, AF_INET6, SOCK_RAW /*bad*/, http_portno, EAI_SERVICE}, 349 {0, AF_UNSPEC, SOCK_RAW /*bad*/, http_portno, EAI_SERVICE}, 350 {0, AF_INET, ANY, invalid_portno /*bad*/, EAI_SERVICE}, 351 {0, AF_INET, SOCK_STREAM, invalid_portno /*bad*/, EAI_SERVICE}, 352 {0, AF_INET, SOCK_DGRAM, invalid_portno /*bad*/, EAI_SERVICE}, 353 {0, AF_INET6, ANY, invalid_portno /*bad*/, EAI_SERVICE}, 354 {0, AF_INET6, SOCK_STREAM, invalid_portno /*bad*/, EAI_SERVICE}, 355 {0, AF_INET6, SOCK_DGRAM, invalid_portno /*bad*/, EAI_SERVICE}, 356 {0, AF_UNSPEC, ANY, invalid_portno /*bad*/, EAI_SERVICE}, 357 {0, AF_UNSPEC, SOCK_STREAM, invalid_portno /*bad*/, EAI_SERVICE}, 358 {0, AF_UNSPEC, SOCK_DGRAM, invalid_portno /*bad*/, EAI_SERVICE}, 359 {AI_NUMERICSERV, AF_INET, ANY, http_portname /*bad*/, EAI_NONAME}, 360 {AI_NUMERICSERV, AF_INET, SOCK_STREAM, http_portname /*bad*/, EAI_NONAME}, 361 {AI_NUMERICSERV, AF_INET, SOCK_DGRAM, http_portname /*bad*/, EAI_NONAME}, 362 {AI_NUMERICSERV, AF_INET6, ANY, http_portname /*bad*/, EAI_NONAME}, 363 {AI_NUMERICSERV, AF_INET6, SOCK_STREAM, http_portname /*bad*/, EAI_NONAME}, 364 {AI_NUMERICSERV, AF_INET6, SOCK_DGRAM, http_portname /*bad*/, EAI_NONAME}, 365 {AI_NUMERICSERV, AF_UNSPEC, ANY, http_portname /*bad*/, EAI_NONAME}, 366 {AI_NUMERICSERV, AF_UNSPEC, SOCK_STREAM, http_portname /*bad*/, EAI_NONAME}, 367 {AI_NUMERICSERV, AF_UNSPEC, SOCK_DGRAM, http_portname /*bad*/, EAI_NONAME}, 368 {0, AF_INET, ANY, invalid_portname /*bad*/, EAI_SERVICE}, 369 {0, AF_INET, SOCK_STREAM, invalid_portname /*bad*/, EAI_SERVICE}, 370 {0, AF_INET, SOCK_DGRAM, invalid_portname /*bad*/, EAI_SERVICE}, 371 {0, AF_INET6, ANY, invalid_portname /*bad*/, EAI_SERVICE}, 372 {0, AF_INET6, SOCK_STREAM, invalid_portname /*bad*/, EAI_SERVICE}, 373 {0, AF_INET6, SOCK_DGRAM, invalid_portname /*bad*/, EAI_SERVICE}, 374 {0, AF_UNSPEC, ANY, invalid_portname /*bad*/, EAI_SERVICE}, 375 {0, AF_UNSPEC, SOCK_STREAM, invalid_portname /*bad*/, EAI_SERVICE}, 376 {0, AF_UNSPEC, SOCK_DGRAM, invalid_portname /*bad*/, EAI_SERVICE}, 377 }; 378 379 for (const auto& config : testConfigs) { 380 const std::string testParameters = config.asParameters(); 381 SCOPED_TRACE(testParameters); 382 383 const addrinfo hints = { 384 .ai_flags = config.ai_flags, 385 .ai_family = config.ai_family, 386 .ai_socktype = config.ai_socktype, 387 }; 388 389 addrinfo* result = nullptr; 390 NetworkDnsEventReported event; 391 int rv = resolv_getaddrinfo("localhost", config.servname, &hints, &mNetcontext, &result, 392 &event); 393 ScopedAddrinfo result_cleanup(result); 394 EXPECT_EQ(config.expected_eai_error, rv); 395 } 396 } 397 398 TEST_F(ResolvGetAddrInfoTest, AlphabeticalHostname_NoData) { 399 constexpr char v4_host_name[] = "v4only.example.com."; 400 // Following fields will not be verified during the test in proto NetworkDnsEventReported. 401 // So don't need to config those values: event_type, return_code, latency_micros, 402 // hints_ai_flags, res_nsend_flags, network_type, private_dns_modes. 403 constexpr char event_ipv6[] = R"Event( 404 NetworkDnsEventReported { 405 dns_query_events: 406 { 407 dns_query_event:[ 408 { 409 rcode: 0, 410 type: 28, 411 cache_hit: 1, 412 ip_version: 1, 413 protocol: 1, 414 retry_times: 0, 415 dns_server_index: 0, 416 connected: 0, 417 latency_micros: 0, 418 linux_errno: 0, 419 }, 420 { 421 rcode: 0, 422 type: 28, 423 cache_hit: 1, 424 ip_version: 1, 425 protocol: 1, 426 retry_times: 0, 427 dns_server_index: 0, 428 connected: 0, 429 latency_micros: 0, 430 linux_errno: 0, 431 }, 432 { 433 rcode: 0, 434 type: 28, 435 cache_hit: 1, 436 ip_version: 1, 437 protocol: 1, 438 retry_times: 0, 439 dns_server_index: 0, 440 connected: 0, 441 latency_micros: 0, 442 linux_errno: 0, 443 }, 444 { 445 rcode: 0, 446 type: 28, 447 cache_hit: 1, 448 ip_version: 1, 449 protocol: 1, 450 retry_times: 0, 451 dns_server_index: 0, 452 connected: 0, 453 latency_micros: 0, 454 linux_errno: 0, 455 } 456 ] 457 } 458 })Event"; 459 460 test::DNSResponder dns; 461 dns.addMapping(v4_host_name, ns_type::ns_t_a, "1.2.3.3"); 462 ASSERT_TRUE(dns.startServer()); 463 ASSERT_EQ(0, SetResolvers()); 464 465 // Want AAAA answer but DNS server has A answer only. 466 addrinfo* result = nullptr; 467 const addrinfo hints = {.ai_family = AF_INET6}; 468 NetworkDnsEventReported event; 469 int rv = resolv_getaddrinfo("v4only", nullptr, &hints, &mNetcontext, &result, &event); 470 EXPECT_THAT(event, NetworkDnsEventEq(fromNetworkDnsEventReportedStr(event_ipv6))); 471 ScopedAddrinfo result_cleanup(result); 472 EXPECT_LE(1U, GetNumQueries(dns, v4_host_name)); 473 EXPECT_EQ(nullptr, result); 474 EXPECT_EQ(EAI_NODATA, rv); 475 } 476 477 TEST_F(ResolvGetAddrInfoTest, AlphabeticalHostname) { 478 constexpr char host_name[] = "sawadee.example.com."; 479 constexpr char v4addr[] = "1.2.3.4"; 480 constexpr char v6addr[] = "::1.2.3.4"; 481 // Following fields will not be verified during the test in proto NetworkDnsEventReported. 482 // So don't need to config those values: event_type, return_code, latency_micros, 483 // hints_ai_flags, res_nsend_flags, network_type, private_dns_modes. 484 constexpr char event_ipv4[] = R"Event( 485 NetworkDnsEventReported { 486 dns_query_events: 487 { 488 dns_query_event:[ 489 { 490 rcode: 0, 491 type: 1, 492 cache_hit: 1, 493 ip_version: 1, 494 protocol: 1, 495 retry_times: 0, 496 dns_server_index: 0, 497 connected: 0, 498 linux_errno: 0, 499 }, 500 { 501 rcode: 0, 502 type: 1, 503 cache_hit: 2, 504 ip_version: 0, 505 protocol: 0, 506 retry_times: 0, 507 dns_server_index: 0, 508 connected: 0, 509 linux_errno: 0, 510 } 511 ] 512 } 513 })Event"; 514 515 constexpr char event_ipv6[] = R"Event( 516 NetworkDnsEventReported { 517 dns_query_events: 518 { 519 dns_query_event:[ 520 { 521 rcode: 0, 522 type: 28, 523 cache_hit: 1, 524 ip_version: 1, 525 protocol: 1, 526 retry_times: 0, 527 dns_server_index: 0, 528 connected: 0, 529 linux_errno: 0, 530 }, 531 { 532 rcode: 0, 533 type: 28, 534 cache_hit: 2, 535 ip_version: 0, 536 protocol: 0, 537 retry_times: 0, 538 dns_server_index: 0, 539 connected: 0, 540 linux_errno: 0, 541 } 542 ] 543 } 544 })Event"; 545 test::DNSResponder dns; 546 dns.addMapping(host_name, ns_type::ns_t_a, v4addr); 547 dns.addMapping(host_name, ns_type::ns_t_aaaa, v6addr); 548 ASSERT_TRUE(dns.startServer()); 549 ASSERT_EQ(0, SetResolvers()); 550 551 static const struct TestConfig { 552 int ai_family; 553 const std::string expected_addr; 554 const std::string expected_event; 555 } testConfigs[]{ 556 {AF_INET, v4addr, event_ipv4}, 557 {AF_INET6, v6addr, event_ipv6}, 558 }; 559 560 for (const auto& config : testConfigs) { 561 SCOPED_TRACE(StringPrintf("family: %d", config.ai_family)); 562 dns.clearQueries(); 563 564 addrinfo* result = nullptr; 565 const addrinfo hints = {.ai_family = config.ai_family}; 566 NetworkDnsEventReported event; 567 int rv = resolv_getaddrinfo("sawadee", nullptr, &hints, &mNetcontext, &result, &event); 568 EXPECT_THAT(event, 569 NetworkDnsEventEq(fromNetworkDnsEventReportedStr(config.expected_event))); 570 ScopedAddrinfo result_cleanup(result); 571 EXPECT_EQ(0, rv); 572 EXPECT_TRUE(result != nullptr); 573 EXPECT_EQ(1U, GetNumQueries(dns, host_name)); 574 EXPECT_EQ(config.expected_addr, ToString(result)); 575 } 576 } 577 578 TEST_F(ResolvGetAddrInfoTest, IllegalHostname) { 579 test::DNSResponder dns; 580 ASSERT_TRUE(dns.startServer()); 581 ASSERT_EQ(0, SetResolvers()); 582 583 // Illegal hostname is verified by res_hnok() in system/netd/resolv/res_comp.cpp. 584 static constexpr char const* illegalHostnames[] = { 585 kBadCharAfterPeriodHost, 586 kBadCharBeforePeriodHost, 587 kBadCharAtTheEndHost, 588 kBadCharInTheMiddleOfLabelHost, 589 }; 590 591 for (const auto& hostname : illegalHostnames) { 592 // Expect to get no address because hostname format is illegal. 593 // 594 // Ex: 595 // ANSWER SECTION: 596 // a.ex^ample.com. IN A 1.2.3.3 597 // a.ex^ample.com. IN AAAA 2001:db8::42 598 // 599 // In this example, querying "a.ex^ample.com" should get no address because 600 // "a.ex^ample.com" has an illegal char '^' in the middle of label. 601 dns.addMapping(hostname, ns_type::ns_t_a, "1.2.3.3"); 602 dns.addMapping(hostname, ns_type::ns_t_aaaa, "2001:db8::42"); 603 604 for (const auto& family : {AF_INET, AF_INET6, AF_UNSPEC}) { 605 SCOPED_TRACE(StringPrintf("family: %d, config.name: %s", family, hostname)); 606 607 addrinfo* res = nullptr; 608 const addrinfo hints = {.ai_family = family}; 609 NetworkDnsEventReported event; 610 int rv = resolv_getaddrinfo(hostname, nullptr, &hints, &mNetcontext, &res, &event); 611 ScopedAddrinfo result(res); 612 EXPECT_EQ(nullptr, result); 613 EXPECT_EQ(EAI_FAIL, rv); 614 } 615 } 616 } 617 618 TEST_F(ResolvGetAddrInfoTest, ServerResponseError) { 619 constexpr char host_name[] = "hello.example.com."; 620 621 static const struct TestConfig { 622 ns_rcode rcode; 623 int expected_eai_error; 624 625 // Only test failure RCODE [1..5] in RFC 1035 section 4.1.1 and skip successful RCODE 0 626 // which means no error. 627 } testConfigs[]{ 628 // clang-format off 629 {ns_rcode::ns_r_formerr, EAI_FAIL}, 630 {ns_rcode::ns_r_servfail, EAI_AGAIN}, 631 {ns_rcode::ns_r_nxdomain, EAI_NODATA}, 632 {ns_rcode::ns_r_notimpl, EAI_FAIL}, 633 {ns_rcode::ns_r_refused, EAI_FAIL}, 634 // clang-format on 635 }; 636 637 for (const auto& config : testConfigs) { 638 SCOPED_TRACE(StringPrintf("rcode: %d", config.rcode)); 639 640 test::DNSResponder dns(config.rcode); 641 dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.4"); 642 dns.setResponseProbability(0.0); // always ignore requests and response preset rcode 643 ASSERT_TRUE(dns.startServer()); 644 ASSERT_EQ(0, SetResolvers()); 645 646 addrinfo* result = nullptr; 647 const addrinfo hints = {.ai_family = AF_UNSPEC}; 648 NetworkDnsEventReported event; 649 int rv = resolv_getaddrinfo(host_name, nullptr, &hints, &mNetcontext, &result, &event); 650 EXPECT_EQ(config.expected_eai_error, rv); 651 } 652 } 653 654 // TODO: Add private DNS server timeout test. 655 TEST_F(ResolvGetAddrInfoTest, ServerTimeout) { 656 constexpr char host_name[] = "hello.example.com."; 657 // Following fields will not be verified during the test in proto NetworkDnsEventReported. 658 // So don't need to config those values: event_type, return_code, latency_micros, 659 // hints_ai_flags, res_nsend_flags, network_type, private_dns_modes. 660 // Expected_event is 16 DNS queries and only "type" and "retry_times" fields are changed. 661 // 2(T_AAAA + T_A) * 2(w/ retry) * 2(query w/ and w/o domain) * 2(SOCK_DGRAM and SOCK_STREAM) 662 constexpr char expected_event[] = R"Event( 663 NetworkDnsEventReported { 664 dns_query_events: 665 { 666 dns_query_event:[ 667 { 668 rcode: 255, 669 type: 28, 670 cache_hit: 1, 671 ip_version: 1, 672 protocol: 1, 673 retry_times: 0, 674 dns_server_index: 0, 675 connected: 0, 676 linux_errno: 110, 677 }, 678 { 679 rcode: 255, 680 type: 28, 681 cache_hit: 1, 682 ip_version: 1, 683 protocol: 1, 684 retry_times: 1, 685 dns_server_index: 0, 686 connected: 0, 687 linux_errno: 110, 688 } 689 { 690 rcode: 255, 691 type: 1, 692 cache_hit: 1, 693 ip_version: 1, 694 protocol: 1, 695 retry_times: 0, 696 dns_server_index: 0, 697 connected: 0, 698 linux_errno: 110, 699 }, 700 { 701 rcode: 255, 702 type: 1, 703 cache_hit: 1, 704 ip_version: 1, 705 protocol: 1, 706 retry_times: 1, 707 dns_server_index: 0, 708 connected: 0, 709 linux_errno: 110, 710 }, 711 { 712 rcode: 255, 713 type: 28, 714 cache_hit: 1, 715 ip_version: 1, 716 protocol: 1, 717 retry_times: 0, 718 dns_server_index: 0, 719 connected: 0, 720 linux_errno: 110, 721 }, 722 { 723 rcode: 255, 724 type: 28, 725 cache_hit: 1, 726 ip_version: 1, 727 protocol: 1, 728 retry_times: 1, 729 dns_server_index: 0, 730 connected: 0, 731 linux_errno: 110, 732 } 733 { 734 rcode: 255, 735 type: 1, 736 cache_hit: 1, 737 ip_version: 1, 738 protocol: 1, 739 retry_times: 0, 740 dns_server_index: 0, 741 connected: 0, 742 linux_errno: 110, 743 }, 744 { 745 rcode: 255, 746 type: 1, 747 cache_hit: 1, 748 ip_version: 1, 749 protocol: 1, 750 retry_times: 1, 751 dns_server_index: 0, 752 connected: 0, 753 linux_errno: 110, 754 }, 755 { 756 rcode: 255, 757 type: 28, 758 cache_hit: 1, 759 ip_version: 1, 760 protocol: 1, 761 retry_times: 0, 762 dns_server_index: 0, 763 connected: 0, 764 linux_errno: 110, 765 }, 766 { 767 rcode: 255, 768 type: 28, 769 cache_hit: 1, 770 ip_version: 1, 771 protocol: 1, 772 retry_times: 1, 773 dns_server_index: 0, 774 connected: 0, 775 linux_errno: 110, 776 } 777 { 778 rcode: 255, 779 type: 1, 780 cache_hit: 1, 781 ip_version: 1, 782 protocol: 1, 783 retry_times: 0, 784 dns_server_index: 0, 785 connected: 0, 786 linux_errno: 110, 787 }, 788 { 789 rcode: 255, 790 type: 1, 791 cache_hit: 1, 792 ip_version: 1, 793 protocol: 1, 794 retry_times: 1, 795 dns_server_index: 0, 796 connected: 0, 797 linux_errno: 110, 798 }, 799 { 800 rcode: 255, 801 type: 28, 802 cache_hit: 1, 803 ip_version: 1, 804 protocol: 1, 805 retry_times: 0, 806 dns_server_index: 0, 807 connected: 0, 808 linux_errno: 110, 809 }, 810 { 811 rcode: 255, 812 type: 28, 813 cache_hit: 1, 814 ip_version: 1, 815 protocol: 1, 816 retry_times: 1, 817 dns_server_index: 0, 818 connected: 0, 819 linux_errno: 110, 820 } 821 { 822 rcode: 255, 823 type: 1, 824 cache_hit: 1, 825 ip_version: 1, 826 protocol: 1, 827 retry_times: 0, 828 dns_server_index: 0, 829 connected: 0, 830 linux_errno: 110, 831 }, 832 { 833 rcode: 255, 834 type: 1, 835 cache_hit: 1, 836 ip_version: 1, 837 protocol: 1, 838 retry_times: 1, 839 dns_server_index: 0, 840 connected: 0, 841 linux_errno: 110, 842 }, 843 ] 844 } 845 })Event"; 846 test::DNSResponder dns(static_cast<ns_rcode>(-1) /*no response*/); 847 dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.4"); 848 dns.setResponseProbability(0.0); // always ignore requests and don't response 849 ASSERT_TRUE(dns.startServer()); 850 ASSERT_EQ(0, SetResolvers()); 851 852 addrinfo* result = nullptr; 853 const addrinfo hints = {.ai_family = AF_UNSPEC}; 854 NetworkDnsEventReported event; 855 int rv = resolv_getaddrinfo("hello", nullptr, &hints, &mNetcontext, &result, &event); 856 EXPECT_THAT(event, NetworkDnsEventEq(fromNetworkDnsEventReportedStr(expected_event))); 857 EXPECT_EQ(NETD_RESOLV_TIMEOUT, rv); 858 } 859 860 TEST_F(ResolvGetAddrInfoTest, CnamesNoIpAddress) { 861 constexpr char ACNAME[] = "acname"; // expect a cname in answer 862 constexpr char CNAMES[] = "cnames"; // expect cname chain in answer 863 864 test::DNSResponder dns; 865 dns.addMapping("cnames.example.com.", ns_type::ns_t_cname, "acname.example.com."); 866 dns.addMapping("acname.example.com.", ns_type::ns_t_cname, "hello.example.com."); 867 ASSERT_TRUE(dns.startServer()); 868 ASSERT_EQ(0, SetResolvers()); 869 870 static const struct TestConfig { 871 const char* name; 872 int family; 873 } testConfigs[]{ 874 // clang-format off 875 {ACNAME, AF_INET}, 876 {ACNAME, AF_INET6}, 877 {ACNAME, AF_UNSPEC}, 878 {CNAMES, AF_INET}, 879 {CNAMES, AF_INET6}, 880 {CNAMES, AF_UNSPEC}, 881 // clang-format on 882 }; 883 884 for (const auto& config : testConfigs) { 885 SCOPED_TRACE( 886 StringPrintf("config.family: %d, config.name: %s", config.family, config.name)); 887 888 addrinfo* res = nullptr; 889 const addrinfo hints = {.ai_family = config.family}; 890 NetworkDnsEventReported event; 891 int rv = resolv_getaddrinfo(config.name, nullptr, &hints, &mNetcontext, &res, &event); 892 ScopedAddrinfo result(res); 893 EXPECT_EQ(nullptr, result); 894 EXPECT_EQ(EAI_FAIL, rv); 895 } 896 } 897 898 TEST_F(ResolvGetAddrInfoTest, CnamesBrokenChainByIllegalCname) { 899 test::DNSResponder dns; 900 ASSERT_TRUE(dns.startServer()); 901 ASSERT_EQ(0, SetResolvers()); 902 903 static const struct TestConfig { 904 const char* name; 905 const char* cname; 906 std::string asHostName() const { return StringPrintf("%s.example.com.", name); } 907 908 // Illegal cname is verified by res_hnok() in system/netd/resolv/res_comp.cpp. 909 } testConfigs[]{ 910 // clang-format off 911 {NAME(kBadCharAfterPeriodHost), kBadCharAfterPeriodHost}, 912 {NAME(kBadCharBeforePeriodHost), kBadCharBeforePeriodHost}, 913 {NAME(kBadCharAtTheEndHost), kBadCharAtTheEndHost}, 914 {NAME(kBadCharInTheMiddleOfLabelHost), kBadCharInTheMiddleOfLabelHost}, 915 // clang-format on 916 }; 917 918 for (const auto& config : testConfigs) { 919 const std::string testHostName = config.asHostName(); 920 921 // Expect to get no address because the cname chain is broken by an illegal cname format. 922 // 923 // Ex: 924 // ANSWER SECTION: 925 // hello.example.com. IN CNAME a.ex^ample.com. 926 // a.ex^ample.com. IN A 1.2.3.3 927 // a.ex^ample.com. IN AAAA 2001:db8::42 928 // 929 // In this example, querying hello.example.com should get no address because 930 // "a.ex^ample.com" has an illegal char '^' in the middle of label. 931 dns.addMapping(testHostName.c_str(), ns_type::ns_t_cname, config.cname); 932 dns.addMapping(config.cname, ns_type::ns_t_a, "1.2.3.3"); 933 dns.addMapping(config.cname, ns_type::ns_t_aaaa, "2001:db8::42"); 934 935 for (const auto& family : {AF_INET, AF_INET6, AF_UNSPEC}) { 936 SCOPED_TRACE( 937 StringPrintf("family: %d, testHostName: %s", family, testHostName.c_str())); 938 939 addrinfo* res = nullptr; 940 const addrinfo hints = {.ai_family = family}; 941 NetworkDnsEventReported event; 942 int rv = resolv_getaddrinfo(config.name, nullptr, &hints, &mNetcontext, &res, &event); 943 ScopedAddrinfo result(res); 944 EXPECT_EQ(nullptr, result); 945 EXPECT_EQ(EAI_FAIL, rv); 946 } 947 } 948 } 949 950 TEST_F(ResolvGetAddrInfoTest, CnamesInfiniteLoop) { 951 test::DNSResponder dns; 952 dns.addMapping("hello.example.com.", ns_type::ns_t_cname, "a.example.com."); 953 dns.addMapping("a.example.com.", ns_type::ns_t_cname, "hello.example.com."); 954 ASSERT_TRUE(dns.startServer()); 955 ASSERT_EQ(0, SetResolvers()); 956 957 for (const auto& family : {AF_INET, AF_INET6, AF_UNSPEC}) { 958 SCOPED_TRACE(StringPrintf("family: %d", family)); 959 960 addrinfo* res = nullptr; 961 const addrinfo hints = {.ai_family = family}; 962 NetworkDnsEventReported event; 963 int rv = resolv_getaddrinfo("hello", nullptr, &hints, &mNetcontext, &res, &event); 964 ScopedAddrinfo result(res); 965 EXPECT_EQ(nullptr, result); 966 EXPECT_EQ(EAI_FAIL, rv); 967 } 968 } 969 970 TEST_F(ResolvGetAddrInfoTest, MultiAnswerSections) { 971 test::DNSResponder dns(test::DNSResponder::MappingType::DNS_HEADER); 972 // Answer section for query type {A, AAAA} 973 // Type A: 974 // hello.example.com. IN A 1.2.3.1 975 // hello.example.com. IN A 1.2.3.2 976 // Type AAAA: 977 // hello.example.com. IN AAAA 2001:db8::41 978 // hello.example.com. IN AAAA 2001:db8::42 979 StartDns(dns, {MakeDnsMessage(kHelloExampleCom, ns_type::ns_t_a, {"1.2.3.1", "1.2.3.2"}), 980 MakeDnsMessage(kHelloExampleCom, ns_type::ns_t_aaaa, 981 {"2001:db8::41", "2001:db8::42"})}); 982 ASSERT_EQ(0, SetResolvers()); 983 984 for (const auto& family : {AF_INET, AF_INET6, AF_UNSPEC}) { 985 SCOPED_TRACE(StringPrintf("family: %d", family)); 986 987 addrinfo* res = nullptr; 988 // If the socket type is not specified, every address will appear twice, once for 989 // SOCK_STREAM and one for SOCK_DGRAM. Just pick one because the addresses for 990 // the second query of different socket type are responded by the cache. 991 const addrinfo hints = {.ai_family = family, .ai_socktype = SOCK_STREAM}; 992 NetworkDnsEventReported event; 993 int rv = resolv_getaddrinfo("hello", nullptr, &hints, &mNetcontext, &res, &event); 994 ScopedAddrinfo result(res); 995 ASSERT_NE(nullptr, result); 996 ASSERT_EQ(0, rv); 997 998 const std::vector<std::string> result_strs = ToStrings(result); 999 if (family == AF_INET) { 1000 EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom)); 1001 EXPECT_THAT(result_strs, testing::UnorderedElementsAreArray({"1.2.3.1", "1.2.3.2"})); 1002 } else if (family == AF_INET6) { 1003 EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom)); 1004 EXPECT_THAT(result_strs, 1005 testing::UnorderedElementsAreArray({"2001:db8::41", "2001:db8::42"})); 1006 } else if (family == AF_UNSPEC) { 1007 EXPECT_EQ(0U, GetNumQueries(dns, kHelloExampleCom)); // no query because of the cache 1008 EXPECT_THAT(result_strs, 1009 testing::UnorderedElementsAreArray( 1010 {"1.2.3.1", "1.2.3.2", "2001:db8::41", "2001:db8::42"})); 1011 } 1012 dns.clearQueries(); 1013 } 1014 } 1015 1016 TEST_F(ResolvGetAddrInfoTest, TruncatedResponse) { 1017 // Following fields will not be verified during the test in proto NetworkDnsEventReported. 1018 // So don't need to config those values: event_type, return_code, latency_micros, 1019 // hints_ai_flags, res_nsend_flags, network_type, private_dns_modes. 1020 constexpr char event_ipv4[] = R"Event( 1021 NetworkDnsEventReported { 1022 dns_query_events: 1023 { 1024 dns_query_event:[ 1025 { 1026 rcode: 254, 1027 type: 1, 1028 cache_hit: 1, 1029 ip_version: 1, 1030 protocol: 1, 1031 retry_times: 0, 1032 dns_server_index: 0, 1033 connected: 0, 1034 linux_errno: 7, 1035 }, 1036 { 1037 rcode: 0, 1038 type: 1, 1039 cache_hit: 1, 1040 ip_version: 1, 1041 protocol: 2, 1042 retry_times: 0, 1043 dns_server_index: 0, 1044 connected: 0, 1045 linux_errno: 0, 1046 }, 1047 { 1048 rcode: 0, 1049 type: 1, 1050 cache_hit: 2, 1051 ip_version: 0, 1052 protocol: 0, 1053 retry_times: 0, 1054 dns_server_index: 0, 1055 connected: 0, 1056 linux_errno: 0, 1057 } 1058 ] 1059 } 1060 })Event"; 1061 1062 constexpr char event_ipv6[] = R"Event( 1063 NetworkDnsEventReported { 1064 dns_query_events: 1065 { 1066 dns_query_event:[ 1067 { 1068 rcode: 254, 1069 type: 28, 1070 cache_hit: 1, 1071 ip_version: 1, 1072 protocol: 1, 1073 retry_times: 0, 1074 dns_server_index: 0, 1075 connected: 0, 1076 linux_errno: 7, 1077 }, 1078 { 1079 rcode: 0, 1080 type: 28, 1081 cache_hit: 1, 1082 ip_version: 1, 1083 protocol: 2, 1084 retry_times: 0, 1085 dns_server_index: 0, 1086 connected: 0, 1087 linux_errno: 0, 1088 }, 1089 { 1090 rcode: 0, 1091 type: 28, 1092 cache_hit: 2, 1093 ip_version: 0, 1094 protocol: 0, 1095 retry_times: 0, 1096 dns_server_index: 0, 1097 connected: 0, 1098 linux_errno: 0, 1099 } 1100 ] 1101 } 1102 })Event"; 1103 1104 test::DNSResponder dns; 1105 dns.addMapping(kHelloExampleCom, ns_type::ns_t_cname, kCnameA); 1106 dns.addMapping(kCnameA, ns_type::ns_t_cname, kCnameB); 1107 dns.addMapping(kCnameB, ns_type::ns_t_cname, kCnameC); 1108 dns.addMapping(kCnameC, ns_type::ns_t_cname, kCnameD); 1109 dns.addMapping(kCnameD, ns_type::ns_t_a, kHelloExampleComAddrV4); 1110 dns.addMapping(kCnameD, ns_type::ns_t_aaaa, kHelloExampleComAddrV6); 1111 ASSERT_TRUE(dns.startServer()); 1112 ASSERT_EQ(0, SetResolvers()); 1113 1114 static const struct TestConfig { 1115 int ai_family; 1116 const std::string expected_addr; 1117 const std::string expected_event; 1118 } testConfigs[]{ 1119 {AF_INET, kHelloExampleComAddrV4, event_ipv4}, 1120 {AF_INET6, kHelloExampleComAddrV6, event_ipv6}, 1121 }; 1122 1123 for (const auto& config : testConfigs) { 1124 SCOPED_TRACE(StringPrintf("family: %d", config.ai_family)); 1125 dns.clearQueries(); 1126 1127 addrinfo* result = nullptr; 1128 const addrinfo hints = {.ai_family = config.ai_family}; 1129 NetworkDnsEventReported event; 1130 int rv = resolv_getaddrinfo("hello", nullptr, &hints, &mNetcontext, &result, &event); 1131 EXPECT_THAT(event, 1132 NetworkDnsEventEq(fromNetworkDnsEventReportedStr(config.expected_event))); 1133 ScopedAddrinfo result_cleanup(result); 1134 EXPECT_EQ(rv, 0); 1135 EXPECT_TRUE(result != nullptr); 1136 // Expect UDP response is truncated. The resolver retries over TCP. See RFC 1035 1137 // section 4.2.1. 1138 EXPECT_EQ(GetNumQueriesForProtocol(dns, IPPROTO_UDP, kHelloExampleCom), 1U); 1139 EXPECT_EQ(GetNumQueriesForProtocol(dns, IPPROTO_TCP, kHelloExampleCom), 1U); 1140 EXPECT_EQ(ToString(result), config.expected_addr); 1141 } 1142 } 1143 1144 // Audit if Resolver read out of bounds, which needs HWAddressSanitizer build to trigger SIGABRT. 1145 TEST_F(ResolvGetAddrInfoTest, OverlengthResp) { 1146 std::vector<std::string> nameList; 1147 // Construct a long enough record that exceeds 8192 bytes (the maximum buffer size): 1148 // Header: (Transaction ID, Flags, ...) = 12 bytes 1149 // Query: 19(Name)+2(Type)+2(Class) = 23 bytes 1150 // The 1st answer RR: 19(Name)+2(Type)+2(Class)+4(TTL)+2(Len)+77(CNAME) = 106 bytes 1151 // 2nd-50th answer RRs: 49*(77(Name)+2(Type)+2(Class)+4(TTL)+2(Len)+77(CNAME)) = 8036 bytes 1152 // The last answer RR: 77(Name)+2(Type)+2(Class)+4(TTL)+2(Len)+4(Address) = 91 bytes 1153 // ---------------------------------------------------------------------------------------- 1154 // Sum: 8268 bytes 1155 for (int i = 0; i < 10; i++) { 1156 std::string domain(kMaxmiumLabelSize / 2, 'a' + i); 1157 for (int j = 0; j < 5; j++) { 1158 nameList.push_back(domain + std::string(kMaxmiumLabelSize / 2 + 1, '0' + j) + 1159 kExampleComDomain + "."); 1160 } 1161 } 1162 test::DNSResponder dns; 1163 dns.addMapping(kHelloExampleCom, ns_type::ns_t_cname, nameList[0]); 1164 for (size_t i = 0; i < nameList.size() - 1; i++) { 1165 dns.addMapping(nameList[i], ns_type::ns_t_cname, nameList[i + 1]); 1166 } 1167 dns.addMapping(nameList[nameList.size() - 1], ns_type::ns_t_a, kHelloExampleComAddrV4); 1168 1169 ASSERT_TRUE(dns.startServer()); 1170 ASSERT_EQ(0, SetResolvers()); 1171 addrinfo* result = nullptr; 1172 const addrinfo hints = {.ai_family = AF_INET}; 1173 NetworkDnsEventReported event; 1174 int rv = resolv_getaddrinfo("hello", nullptr, &hints, &mNetcontext, &result, &event); 1175 ScopedAddrinfo result_cleanup(result); 1176 EXPECT_EQ(rv, EAI_FAIL); 1177 EXPECT_TRUE(result == nullptr); 1178 EXPECT_EQ(GetNumQueriesForProtocol(dns, IPPROTO_UDP, kHelloExampleCom), 2U); 1179 EXPECT_EQ(GetNumQueriesForProtocol(dns, IPPROTO_TCP, kHelloExampleCom), 2U); 1180 } 1181 1182 TEST_F(GetHostByNameForNetContextTest, AlphabeticalHostname) { 1183 constexpr char host_name[] = "jiababuei.example.com."; 1184 constexpr char v4addr[] = "1.2.3.4"; 1185 constexpr char v6addr[] = "::1.2.3.4"; 1186 // Following fields will not be verified during the test in proto NetworkDnsEventReported. 1187 // So don't need to config those values: event_type, return_code, latency_micros, 1188 // hints_ai_flags, res_nsend_flags, network_type, private_dns_modes. 1189 constexpr char event_ipv4[] = R"Event( 1190 NetworkDnsEventReported { 1191 dns_query_events: 1192 { 1193 dns_query_event:[ 1194 { 1195 rcode: 0, 1196 type: 1, 1197 cache_hit: 1, 1198 ip_version: 1, 1199 protocol: 1, 1200 retry_times: 0, 1201 dns_server_index: 0, 1202 connected: 0, 1203 latency_micros: 0, 1204 linux_errno: 0, 1205 } 1206 ] 1207 } 1208 })Event"; 1209 1210 constexpr char event_ipv6[] = R"Event( 1211 NetworkDnsEventReported { 1212 dns_query_events: 1213 { 1214 dns_query_event:[ 1215 { 1216 rcode: 0, 1217 type: 28, 1218 cache_hit: 1, 1219 ip_version: 1, 1220 protocol: 1, 1221 retry_times: 0, 1222 dns_server_index: 0, 1223 connected: 0, 1224 latency_micros: 0, 1225 linux_errno: 0, 1226 } 1227 ] 1228 } 1229 })Event"; 1230 test::DNSResponder dns; 1231 dns.addMapping(host_name, ns_type::ns_t_a, v4addr); 1232 dns.addMapping(host_name, ns_type::ns_t_aaaa, v6addr); 1233 ASSERT_TRUE(dns.startServer()); 1234 ASSERT_EQ(0, SetResolvers()); 1235 1236 static const struct TestConfig { 1237 int ai_family; 1238 const std::string expected_addr; 1239 const std::string expected_event; 1240 } testConfigs[]{ 1241 {AF_INET, v4addr, event_ipv4}, 1242 {AF_INET6, v6addr, event_ipv6}, 1243 }; 1244 1245 for (const auto& config : testConfigs) { 1246 SCOPED_TRACE(StringPrintf("family: %d", config.ai_family)); 1247 dns.clearQueries(); 1248 1249 hostent* hp = nullptr; 1250 hostent hbuf; 1251 char tmpbuf[MAXPACKET]; 1252 NetworkDnsEventReported event; 1253 int rv = resolv_gethostbyname("jiababuei", config.ai_family, &hbuf, tmpbuf, sizeof(tmpbuf), 1254 &mNetcontext, &hp, &event); 1255 EXPECT_THAT(event, 1256 NetworkDnsEventEq(fromNetworkDnsEventReportedStr(config.expected_event))); 1257 EXPECT_EQ(0, rv); 1258 EXPECT_TRUE(hp != nullptr); 1259 EXPECT_EQ(1U, GetNumQueries(dns, host_name)); 1260 EXPECT_EQ(config.expected_addr, ToString(hp)); 1261 } 1262 } 1263 1264 TEST_F(GetHostByNameForNetContextTest, IllegalHostname) { 1265 test::DNSResponder dns; 1266 ASSERT_TRUE(dns.startServer()); 1267 ASSERT_EQ(0, SetResolvers()); 1268 1269 // Illegal hostname is verified by res_hnok() in system/netd/resolv/res_comp.cpp. 1270 static constexpr char const* illegalHostnames[] = { 1271 kBadCharAfterPeriodHost, 1272 kBadCharBeforePeriodHost, 1273 kBadCharAtTheEndHost, 1274 kBadCharInTheMiddleOfLabelHost, 1275 }; 1276 1277 for (const auto& hostname : illegalHostnames) { 1278 // Expect to get no address because hostname format is illegal. 1279 // 1280 // Ex: 1281 // ANSWER SECTION: 1282 // a.ex^ample.com. IN A 1.2.3.3 1283 // a.ex^ample.com. IN AAAA 2001:db8::42 1284 // 1285 // In this example, querying "a.ex^ample.com" should get no address because 1286 // "a.ex^ample.com" has an illegal char '^' in the middle of label. 1287 dns.addMapping(hostname, ns_type::ns_t_a, "1.2.3.3"); 1288 dns.addMapping(hostname, ns_type::ns_t_aaaa, "2001:db8::42"); 1289 1290 for (const auto& family : {AF_INET, AF_INET6}) { 1291 SCOPED_TRACE(StringPrintf("family: %d, config.name: %s", family, hostname)); 1292 1293 struct hostent* hp = nullptr; 1294 hostent hbuf; 1295 char tmpbuf[MAXPACKET]; 1296 NetworkDnsEventReported event; 1297 int rv = resolv_gethostbyname(hostname, family, &hbuf, tmpbuf, sizeof(tmpbuf), 1298 &mNetcontext, &hp, &event); 1299 EXPECT_EQ(nullptr, hp); 1300 EXPECT_EQ(EAI_FAIL, rv); 1301 } 1302 } 1303 } 1304 1305 TEST_F(GetHostByNameForNetContextTest, NoData) { 1306 constexpr char v4_host_name[] = "v4only.example.com."; 1307 1308 test::DNSResponder dns; 1309 dns.addMapping(v4_host_name, ns_type::ns_t_a, "1.2.3.3"); 1310 ASSERT_TRUE(dns.startServer()); 1311 ASSERT_EQ(0, SetResolvers()); 1312 dns.clearQueries(); 1313 1314 // Want AAAA answer but DNS server has A answer only. 1315 hostent* hp = nullptr; 1316 hostent hbuf; 1317 char tmpbuf[MAXPACKET]; 1318 NetworkDnsEventReported event; 1319 int rv = resolv_gethostbyname("v4only", AF_INET6, &hbuf, tmpbuf, sizeof tmpbuf, &mNetcontext, 1320 &hp, &event); 1321 EXPECT_LE(1U, GetNumQueries(dns, v4_host_name)); 1322 EXPECT_EQ(nullptr, hp); 1323 EXPECT_EQ(EAI_NODATA, rv); 1324 } 1325 1326 TEST_F(GetHostByNameForNetContextTest, ServerResponseError) { 1327 constexpr char host_name[] = "hello.example.com."; 1328 1329 static const struct TestConfig { 1330 ns_rcode rcode; 1331 int expected_eai_error; // expected result 1332 1333 // Only test failure RCODE [1..5] in RFC 1035 section 4.1.1 and skip successful RCODE 0 1334 // which means no error. Note that the return error codes aren't mapped by rcode in the 1335 // test case SERVFAIL, NOTIMP and REFUSED. See the comment of res_nsend() 1336 // in system\netd\resolv\res_query.cpp for more detail. 1337 } testConfigs[]{ 1338 // clang-format off 1339 {ns_rcode::ns_r_formerr, EAI_FAIL}, 1340 {ns_rcode::ns_r_servfail, EAI_AGAIN}, // Not mapped by rcode. 1341 {ns_rcode::ns_r_nxdomain, EAI_NODATA}, 1342 {ns_rcode::ns_r_notimpl, EAI_AGAIN}, // Not mapped by rcode. 1343 {ns_rcode::ns_r_refused, EAI_AGAIN}, // Not mapped by rcode. 1344 // clang-format on 1345 }; 1346 1347 for (const auto& config : testConfigs) { 1348 SCOPED_TRACE(StringPrintf("rcode: %d", config.rcode)); 1349 1350 test::DNSResponder dns(config.rcode); 1351 dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.4"); 1352 dns.setResponseProbability(0.0); // always ignore requests and response preset rcode 1353 ASSERT_TRUE(dns.startServer()); 1354 ASSERT_EQ(0, SetResolvers()); 1355 1356 hostent* hp = nullptr; 1357 hostent hbuf; 1358 char tmpbuf[MAXPACKET]; 1359 NetworkDnsEventReported event; 1360 int rv = resolv_gethostbyname(host_name, AF_INET, &hbuf, tmpbuf, sizeof tmpbuf, 1361 &mNetcontext, &hp, &event); 1362 EXPECT_EQ(nullptr, hp); 1363 EXPECT_EQ(config.expected_eai_error, rv); 1364 } 1365 } 1366 1367 // TODO: Add private DNS server timeout test. 1368 TEST_F(GetHostByNameForNetContextTest, ServerTimeout) { 1369 constexpr char host_name[] = "hello.example.com."; 1370 test::DNSResponder dns(static_cast<ns_rcode>(-1) /*no response*/); 1371 dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.4"); 1372 dns.setResponseProbability(0.0); // always ignore requests and don't response 1373 ASSERT_TRUE(dns.startServer()); 1374 ASSERT_EQ(0, SetResolvers()); 1375 1376 hostent* hp = nullptr; 1377 hostent hbuf; 1378 char tmpbuf[MAXPACKET]; 1379 NetworkDnsEventReported event; 1380 int rv = resolv_gethostbyname(host_name, AF_INET, &hbuf, tmpbuf, sizeof tmpbuf, &mNetcontext, 1381 &hp, &event); 1382 EXPECT_EQ(NETD_RESOLV_TIMEOUT, rv); 1383 } 1384 1385 TEST_F(GetHostByNameForNetContextTest, CnamesNoIpAddress) { 1386 constexpr char ACNAME[] = "acname"; // expect a cname in answer 1387 constexpr char CNAMES[] = "cnames"; // expect cname chain in answer 1388 1389 test::DNSResponder dns; 1390 dns.addMapping("cnames.example.com.", ns_type::ns_t_cname, "acname.example.com."); 1391 dns.addMapping("acname.example.com.", ns_type::ns_t_cname, "hello.example.com."); 1392 ASSERT_TRUE(dns.startServer()); 1393 ASSERT_EQ(0, SetResolvers()); 1394 1395 static const struct TestConfig { 1396 const char* name; 1397 int family; 1398 } testConfigs[]{ 1399 {ACNAME, AF_INET}, 1400 {ACNAME, AF_INET6}, 1401 {CNAMES, AF_INET}, 1402 {CNAMES, AF_INET6}, 1403 }; 1404 1405 for (const auto& config : testConfigs) { 1406 SCOPED_TRACE( 1407 StringPrintf("config.family: %d, config.name: %s", config.family, config.name)); 1408 1409 struct hostent* hp = nullptr; 1410 hostent hbuf; 1411 char tmpbuf[MAXPACKET]; 1412 NetworkDnsEventReported event; 1413 int rv = resolv_gethostbyname(config.name, config.family, &hbuf, tmpbuf, sizeof tmpbuf, 1414 &mNetcontext, &hp, &event); 1415 EXPECT_EQ(nullptr, hp); 1416 EXPECT_EQ(EAI_FAIL, rv); 1417 } 1418 } 1419 1420 TEST_F(GetHostByNameForNetContextTest, CnamesBrokenChainByIllegalCname) { 1421 test::DNSResponder dns; 1422 ASSERT_TRUE(dns.startServer()); 1423 ASSERT_EQ(0, SetResolvers()); 1424 1425 static const struct TestConfig { 1426 const char* name; 1427 const char* cname; 1428 std::string asHostName() const { return StringPrintf("%s.example.com.", name); } 1429 1430 // Illegal cname is verified by res_hnok() in system/netd/resolv/res_comp.cpp 1431 } testConfigs[]{ 1432 // clang-format off 1433 {NAME(kBadCharAfterPeriodHost), kBadCharAfterPeriodHost}, 1434 {NAME(kBadCharBeforePeriodHost), kBadCharBeforePeriodHost}, 1435 {NAME(kBadCharAtTheEndHost), kBadCharAtTheEndHost}, 1436 {NAME(kBadCharInTheMiddleOfLabelHost), kBadCharInTheMiddleOfLabelHost}, 1437 // clang-format on 1438 }; 1439 1440 for (const auto& config : testConfigs) { 1441 const std::string testHostName = config.asHostName(); 1442 1443 // Expect to get no address because the cname chain is broken by an illegal cname format. 1444 // 1445 // Ex: 1446 // ANSWER SECTION: 1447 // hello.example.com. IN CNAME a.ex^ample.com. 1448 // a.ex^ample.com. IN A 1.2.3.3 1449 // a.ex^ample.com. IN AAAA 2001:db8::42 1450 // 1451 // In this example, querying hello.example.com should get no address because 1452 // "a.ex^ample.com" has an illegal char '^' in the middle of label. 1453 dns.addMapping(testHostName.c_str(), ns_type::ns_t_cname, config.cname); 1454 dns.addMapping(config.cname, ns_type::ns_t_a, "1.2.3.3"); 1455 dns.addMapping(config.cname, ns_type::ns_t_aaaa, "2001:db8::42"); 1456 1457 for (const auto& family : {AF_INET, AF_INET6}) { 1458 SCOPED_TRACE( 1459 StringPrintf("family: %d, testHostName: %s", family, testHostName.c_str())); 1460 1461 struct hostent* hp = nullptr; 1462 hostent hbuf; 1463 char tmpbuf[MAXPACKET]; 1464 NetworkDnsEventReported event; 1465 int rv = resolv_gethostbyname(config.name, family, &hbuf, tmpbuf, sizeof tmpbuf, 1466 &mNetcontext, &hp, &event); 1467 EXPECT_EQ(nullptr, hp); 1468 EXPECT_EQ(EAI_FAIL, rv); 1469 } 1470 } 1471 } 1472 1473 TEST_F(GetHostByNameForNetContextTest, CnamesInfiniteLoop) { 1474 test::DNSResponder dns; 1475 dns.addMapping("hello.example.com.", ns_type::ns_t_cname, "a.example.com."); 1476 dns.addMapping("a.example.com.", ns_type::ns_t_cname, "hello.example.com."); 1477 ASSERT_TRUE(dns.startServer()); 1478 ASSERT_EQ(0, SetResolvers()); 1479 1480 for (const auto& family : {AF_INET, AF_INET6}) { 1481 SCOPED_TRACE(StringPrintf("family: %d", family)); 1482 1483 struct hostent* hp = nullptr; 1484 hostent hbuf; 1485 char tmpbuf[MAXPACKET]; 1486 NetworkDnsEventReported event; 1487 int rv = resolv_gethostbyname("hello", family, &hbuf, tmpbuf, sizeof tmpbuf, &mNetcontext, 1488 &hp, &event); 1489 EXPECT_EQ(nullptr, hp); 1490 EXPECT_EQ(EAI_FAIL, rv); 1491 } 1492 } 1493 1494 TEST_F(ResolvCommonFunctionTest, GetCustTableByName) { 1495 const char custAddrV4[] = "1.2.3.4"; 1496 const char custAddrV6[] = "::1.2.3.4"; 1497 const char hostnameV4V6[] = "v4v6.example.com."; 1498 const aidl::android::net::ResolverOptionsParcel& resolverOptions = { 1499 { 1500 {custAddrV4, hostnameV4V6}, 1501 {custAddrV6, hostnameV4V6}, 1502 }, 1503 aidl::android::net::IDnsResolver::TC_MODE_DEFAULT}; 1504 const std::vector<int32_t>& transportTypes = {IDnsResolver::TRANSPORT_WIFI}; 1505 EXPECT_EQ(0, resolv_set_nameservers(TEST_NETID, servers, domains, params, resolverOptions, 1506 transportTypes)); 1507 EXPECT_THAT(getCustomizedTableByName(TEST_NETID, hostnameV4V6), 1508 testing::UnorderedElementsAreArray({custAddrV4, custAddrV6})); 1509 1510 // Query address by mismatch hostname. 1511 ASSERT_TRUE(getCustomizedTableByName(TEST_NETID, "not.in.cust.table").empty()); 1512 1513 // Query address by different netid. 1514 ASSERT_TRUE(getCustomizedTableByName(TEST_NETID + 1, hostnameV4V6).empty()); 1515 resolv_create_cache_for_net(TEST_NETID + 1); 1516 EXPECT_EQ(0, resolv_set_nameservers(TEST_NETID + 1, servers, domains, params, resolverOptions, 1517 transportTypes)); 1518 EXPECT_THAT(getCustomizedTableByName(TEST_NETID + 1, hostnameV4V6), 1519 testing::UnorderedElementsAreArray({custAddrV4, custAddrV6})); 1520 } 1521 1522 TEST_F(ResolvCommonFunctionTest, GetNetworkTypesForNet) { 1523 const aidl::android::net::ResolverOptionsParcel& resolverOptions = { 1524 {} /* hosts */, aidl::android::net::IDnsResolver::TC_MODE_DEFAULT}; 1525 const std::vector<int32_t>& transportTypes = {IDnsResolver::TRANSPORT_WIFI, 1526 IDnsResolver::TRANSPORT_VPN}; 1527 EXPECT_EQ(0, resolv_set_nameservers(TEST_NETID, servers, domains, params, resolverOptions, 1528 transportTypes)); 1529 EXPECT_EQ(android::net::NT_WIFI_VPN, resolv_get_network_types_for_net(TEST_NETID)); 1530 } 1531 1532 TEST_F(ResolvCommonFunctionTest, ConvertTransportsToNetworkType) { 1533 static const struct TestConfig { 1534 int32_t networkType; 1535 std::vector<int32_t> transportTypes; 1536 } testConfigs[] = { 1537 {android::net::NT_CELLULAR, {IDnsResolver::TRANSPORT_CELLULAR}}, 1538 {android::net::NT_WIFI, {IDnsResolver::TRANSPORT_WIFI}}, 1539 {android::net::NT_BLUETOOTH, {IDnsResolver::TRANSPORT_BLUETOOTH}}, 1540 {android::net::NT_ETHERNET, {IDnsResolver::TRANSPORT_ETHERNET}}, 1541 {android::net::NT_VPN, {IDnsResolver::TRANSPORT_VPN}}, 1542 {android::net::NT_WIFI_AWARE, {IDnsResolver::TRANSPORT_WIFI_AWARE}}, 1543 {android::net::NT_LOWPAN, {IDnsResolver::TRANSPORT_LOWPAN}}, 1544 {android::net::NT_CELLULAR_VPN, 1545 {IDnsResolver::TRANSPORT_CELLULAR, IDnsResolver::TRANSPORT_VPN}}, 1546 {android::net::NT_CELLULAR_VPN, 1547 {IDnsResolver::TRANSPORT_VPN, IDnsResolver::TRANSPORT_CELLULAR}}, 1548 {android::net::NT_WIFI_VPN, 1549 {IDnsResolver::TRANSPORT_WIFI, IDnsResolver::TRANSPORT_VPN}}, 1550 {android::net::NT_WIFI_VPN, 1551 {IDnsResolver::TRANSPORT_VPN, IDnsResolver::TRANSPORT_WIFI}}, 1552 {android::net::NT_BLUETOOTH_VPN, 1553 {IDnsResolver::TRANSPORT_BLUETOOTH, IDnsResolver::TRANSPORT_VPN}}, 1554 {android::net::NT_BLUETOOTH_VPN, 1555 {IDnsResolver::TRANSPORT_VPN, IDnsResolver::TRANSPORT_BLUETOOTH}}, 1556 {android::net::NT_ETHERNET_VPN, 1557 {IDnsResolver::TRANSPORT_ETHERNET, IDnsResolver::TRANSPORT_VPN}}, 1558 {android::net::NT_ETHERNET_VPN, 1559 {IDnsResolver::TRANSPORT_VPN, IDnsResolver::TRANSPORT_ETHERNET}}, 1560 {android::net::NT_UNKNOWN, {IDnsResolver::TRANSPORT_VPN, IDnsResolver::TRANSPORT_VPN}}, 1561 {android::net::NT_UNKNOWN, 1562 {IDnsResolver::TRANSPORT_WIFI, IDnsResolver::TRANSPORT_LOWPAN}}, 1563 {android::net::NT_UNKNOWN, {}}, 1564 {android::net::NT_UNKNOWN, 1565 {IDnsResolver::TRANSPORT_CELLULAR, IDnsResolver::TRANSPORT_BLUETOOTH, 1566 IDnsResolver::TRANSPORT_VPN}}, 1567 {android::net::NT_WIFI_CELLULAR_VPN, 1568 {IDnsResolver::TRANSPORT_CELLULAR, IDnsResolver::TRANSPORT_WIFI, 1569 IDnsResolver::TRANSPORT_VPN}}, 1570 {android::net::NT_WIFI_CELLULAR_VPN, 1571 {IDnsResolver::TRANSPORT_VPN, IDnsResolver::TRANSPORT_WIFI, 1572 IDnsResolver::TRANSPORT_CELLULAR}}, 1573 }; 1574 for (const auto& config : testConfigs) { 1575 EXPECT_EQ(config.networkType, convert_network_type(config.transportTypes)); 1576 } 1577 } 1578 1579 // Note that local host file function, files_getaddrinfo(), of resolv_getaddrinfo() 1580 // is not tested because it only returns a boolean (success or failure) without any error number. 1581 1582 // TODO: Add test for resolv_getaddrinfo(). 1583 // - DNS response message parsing. 1584 // - Unexpected type of resource record (RR). 1585 // - Invalid length CNAME, or QNAME. 1586 // - Unexpected amount of questions. 1587 // - CNAME RDATA with the domain name which has null label(s). 1588 // TODO: Add test for resolv_gethostbyname(). 1589 // - Invalid parameters. 1590 // - DNS response message parsing. 1591 // - Unexpected type of resource record (RR). 1592 // - Invalid length CNAME, or QNAME. 1593 // - Unexpected amount of questions. 1594 // - CNAME RDATA with the domain name which has null label(s). 1595 // TODO: Add test for resolv_gethostbyaddr(). 1596 1597 } // end of namespace net 1598 } // end of namespace android 1599