• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SetUp()60     void SetUp() override {
61         // Create cache for test
62         resolv_create_cache_for_net(TEST_NETID);
63     }
TearDown()64     void TearDown() override {
65         // Delete cache for test
66         resolv_delete_cache_for_net(TEST_NETID);
67     }
68 
MakeAnswerRecord(const std::string & name,unsigned rclass,unsigned rtype,const std::string & rdata,unsigned ttl=kAnswerRecordTtlSec)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 
MakeDnsMessage(const std::string & qname,ns_type qtype,const std::vector<std::string> & rdata)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 
StartDns(test::DNSResponder & dns,const std::vector<DnsMessage> & messages)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 
SetResolvers()126     int SetResolvers() { return SetResolvers(servers); }
127 
SetResolvers(std::vector<std::string> servers)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 
TEST_F(ResolvGetAddrInfoTest,InvalidParameters)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 
TEST_F(ResolvGetAddrInfoTest,InvalidParameters_Family)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 
TEST_F(ResolvGetAddrInfoTest,InvalidParameters_SocketType)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 
TEST_F(ResolvGetAddrInfoTest,InvalidParameters_MeaningfulSocktypeAndProtocolCombination)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.
TEST_F(ResolvGetAddrInfoTest,InvalidParameters_PortNameAndNumber)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 
TEST_F(ResolvGetAddrInfoTest,AlphabeticalHostname_NoData)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 
TEST_F(ResolvGetAddrInfoTest,AlphabeticalHostname)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 
TEST_F(ResolvGetAddrInfoTest,IllegalHostname)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 
TEST_F(ResolvGetAddrInfoTest,ServerResponseError)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.
TEST_F(ResolvGetAddrInfoTest,ServerTimeout)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 
TEST_F(ResolvGetAddrInfoTest,CnamesNoIpAddress)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 
TEST_F(ResolvGetAddrInfoTest,CnamesBrokenChainByIllegalCname)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 
TEST_F(ResolvGetAddrInfoTest,CnamesInfiniteLoop)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 
TEST_F(ResolvGetAddrInfoTest,MultiAnswerSections)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 
TEST_F(ResolvGetAddrInfoTest,TruncatedResponse)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.
TEST_F(ResolvGetAddrInfoTest,OverlengthResp)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 
TEST_F(GetHostByNameForNetContextTest,AlphabeticalHostname)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 
TEST_F(GetHostByNameForNetContextTest,IllegalHostname)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 
TEST_F(GetHostByNameForNetContextTest,NoData)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 
TEST_F(GetHostByNameForNetContextTest,ServerResponseError)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.
TEST_F(GetHostByNameForNetContextTest,ServerTimeout)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 
TEST_F(GetHostByNameForNetContextTest,CnamesNoIpAddress)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 
TEST_F(GetHostByNameForNetContextTest,CnamesBrokenChainByIllegalCname)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 
TEST_F(GetHostByNameForNetContextTest,CnamesInfiniteLoop)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 
TEST_F(ResolvCommonFunctionTest,GetCustTableByName)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 
TEST_F(ResolvCommonFunctionTest,GetNetworkTypesForNet)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 
TEST_F(ResolvCommonFunctionTest,ConvertTransportsToNetworkType)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