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 "libnetd_resolv_test"
18
19 #include <gtest/gtest.h>
20
21 #include <android-base/stringprintf.h>
22 #include <arpa/inet.h>
23 #include <netdb.h>
24
25 #include "dns_responder.h"
26 #include "getaddrinfo.h"
27 #include "gethnamaddr.h"
28 #include "resolv_cache.h"
29
30 // TODO: make this dynamic and stop depending on implementation details.
31 constexpr unsigned int TEST_NETID = 30;
32
33 // Specifying 0 in ai_socktype or ai_protocol of struct addrinfo indicates that any type or
34 // protocol can be returned by getaddrinfo().
35 constexpr unsigned int ANY = 0;
36
37 using android::base::StringPrintf;
38
39 namespace android {
40 namespace net {
41
42 // Minimize class ResolverTest to be class TestBase because class TestBase doesn't need all member
43 // functions of class ResolverTest and class DnsResponderClient.
44 class TestBase : public ::testing::Test {
45 protected:
SetUp()46 void SetUp() override {
47 // Create cache for test
48 resolv_create_cache_for_net(TEST_NETID);
49 }
TearDown()50 void TearDown() override {
51 // Delete cache for test
52 resolv_delete_cache_for_net(TEST_NETID);
53 }
54
ToString(const hostent * he)55 static std::string ToString(const hostent* he) {
56 if (he == nullptr) return "<null>";
57 char buffer[INET6_ADDRSTRLEN];
58 if (!inet_ntop(he->h_addrtype, he->h_addr_list[0], buffer, sizeof(buffer))) {
59 return "<invalid>";
60 }
61 return buffer;
62 }
63
ToString(const addrinfo * ai)64 static std::string ToString(const addrinfo* ai) {
65 if (!ai) return "<null>";
66 for (const auto* aip = ai; aip != nullptr; aip = aip->ai_next) {
67 char host[NI_MAXHOST];
68 int rv = getnameinfo(aip->ai_addr, aip->ai_addrlen, host, sizeof(host), nullptr, 0,
69 NI_NUMERICHOST);
70 if (rv != 0) return gai_strerror(rv);
71 return host;
72 }
73 return "<invalid>";
74 }
75
GetNumQueries(const test::DNSResponder & dns,const char * name) const76 size_t GetNumQueries(const test::DNSResponder& dns, const char* name) const {
77 auto queries = dns.queries();
78 size_t found = 0;
79 for (const auto& p : queries) {
80 if (p.first == name) {
81 ++found;
82 }
83 }
84 return found;
85 }
86
87 const char* mDefaultSearchDomains = "example.com";
88 const res_params mDefaultParams_Binder = {
89 .sample_validity = 300,
90 .success_threshold = 25,
91 .min_samples = 8,
92 .max_samples = 8,
93 .base_timeout_msec = 1000,
94 .retry_count = 2,
95 };
96 const android_net_context mNetcontext = {
97 .app_netid = TEST_NETID,
98 .app_mark = MARK_UNSET,
99 .dns_netid = TEST_NETID,
100 .dns_mark = MARK_UNSET,
101 .uid = NET_CONTEXT_INVALID_UID,
102 };
103 };
104
105 class GetAddrInfoForNetContextTest : public TestBase {};
106 class GetHostByNameForNetContextTest : public TestBase {};
107
TEST_F(GetAddrInfoForNetContextTest,InvalidParameters)108 TEST_F(GetAddrInfoForNetContextTest, InvalidParameters) {
109 // Both null "netcontext" and null "res" of android_getaddrinfofornetcontext() are not tested
110 // here because they are checked by assert() without returning any error number.
111
112 // Invalid hostname and servname.
113 // Both hostname and servname are null pointers. Expect error number EAI_NONAME.
114 struct addrinfo* result = nullptr;
115 int rv = android_getaddrinfofornetcontext(nullptr /*hostname*/, nullptr /*servname*/,
116 nullptr /*hints*/, &mNetcontext, &result);
117 EXPECT_EQ(EAI_NONAME, rv);
118 if (result) {
119 freeaddrinfo(result);
120 result = nullptr;
121 }
122
123 // Invalid hints.
124 // These place holders are used to test function call with unrequired parameters.
125 // The content is not important because function call returns error directly if
126 // there have any unrequired parameter.
127 char placeholder_cname[] = "invalid_cname";
128 sockaddr placeholder_addr = {};
129 addrinfo placeholder_next = {};
130 static const struct TestConfig {
131 int ai_flags;
132 socklen_t ai_addrlen;
133 char* ai_canonname;
134 struct sockaddr* ai_addr;
135 struct addrinfo* ai_next;
136 int expected_errorno; // expected result
137
138 std::string asParameters() const {
139 return StringPrintf("0x%x/%u/%s/%p/%p", ai_flags, ai_addrlen,
140 ai_canonname ? ai_canonname : "(null)", (void*) ai_addr,
141 (void*) ai_next);
142 }
143 } testConfigs[]{
144 {0, sizeof(struct in_addr) /*bad*/, nullptr, nullptr, nullptr, EAI_BADHINTS},
145 {0, 0, placeholder_cname /*bad*/, nullptr, nullptr, EAI_BADHINTS},
146 {0, 0, nullptr, &placeholder_addr /*bad*/, nullptr, EAI_BADHINTS},
147 {0, 0, nullptr, nullptr, &placeholder_next /*bad*/, EAI_BADHINTS},
148 {AI_ALL /*bad*/, 0, nullptr, nullptr, nullptr, EAI_BADFLAGS},
149 {AI_V4MAPPED_CFG /*bad*/, 0, nullptr, nullptr, nullptr, EAI_BADFLAGS},
150 {AI_V4MAPPED /*bad*/, 0, nullptr, nullptr, nullptr, EAI_BADFLAGS},
151 {AI_DEFAULT /*bad*/, 0, nullptr, nullptr, nullptr, EAI_BADFLAGS},
152 };
153
154 for (const auto& config : testConfigs) {
155 SCOPED_TRACE(config.asParameters());
156
157 // In current test configuration set, ai_family, ai_protocol and ai_socktype are not
158 // checked because other fields cause hints error check failed first.
159 const struct addrinfo hints = {
160 .ai_flags = config.ai_flags,
161 .ai_family = AF_UNSPEC,
162 .ai_socktype = ANY,
163 .ai_protocol = ANY,
164 .ai_addrlen = config.ai_addrlen,
165 .ai_canonname = config.ai_canonname,
166 .ai_addr = config.ai_addr,
167 .ai_next = config.ai_next,
168 };
169
170 rv = android_getaddrinfofornetcontext("localhost", nullptr /*servname*/, &hints,
171 &mNetcontext, &result);
172 EXPECT_EQ(config.expected_errorno, rv);
173
174 if (result) {
175 freeaddrinfo(result);
176 result = nullptr;
177 }
178 }
179 }
180
TEST_F(GetAddrInfoForNetContextTest,InvalidParameters_Family)181 TEST_F(GetAddrInfoForNetContextTest, InvalidParameters_Family) {
182 for (int family = 0; family < AF_MAX; ++family) {
183 if (family == AF_UNSPEC || family == AF_INET || family == AF_INET6) {
184 continue; // skip supported family
185 }
186 SCOPED_TRACE(StringPrintf("family: %d", family));
187
188 struct addrinfo* result = nullptr;
189 const struct addrinfo hints = {
190 .ai_family = family, // unsupported family
191 };
192
193 int rv = android_getaddrinfofornetcontext("localhost", nullptr /*servname*/, &hints,
194 &mNetcontext, &result);
195 EXPECT_EQ(EAI_FAMILY, rv);
196
197 if (result) freeaddrinfo(result);
198 }
199 }
200
TEST_F(GetAddrInfoForNetContextTest,InvalidParameters_MeaningfulSocktypeAndProtocolCombination)201 TEST_F(GetAddrInfoForNetContextTest, InvalidParameters_MeaningfulSocktypeAndProtocolCombination) {
202 static const int families[] = {PF_INET, PF_INET6, PF_UNSPEC};
203 // Skip to test socket type SOCK_RAW in meaningful combination (explore_options[]) of
204 // system\netd\resolv\getaddrinfo.cpp. In explore_options[], the socket type SOCK_RAW always
205 // comes with protocol ANY which causes skipping meaningful socktype/protocol combination
206 // check. So it nerver returns error number EAI_BADHINTS which we want to test in this test
207 // case.
208 static const int socktypes[] = {SOCK_STREAM, SOCK_DGRAM};
209
210 // If both socktype/protocol are specified, check non-meaningful combination returns
211 // expected error number EAI_BADHINTS. See meaningful combination in explore_options[] of
212 // system\netd\resolv\getaddrinfo.cpp.
213 for (const auto& family : families) {
214 for (const auto& socktype : socktypes) {
215 for (int protocol = 0; protocol < IPPROTO_MAX; ++protocol) {
216 SCOPED_TRACE(StringPrintf("family: %d, socktype: %d, protocol: %d", family,
217 socktype, protocol));
218
219 // Both socktype/protocol need to be specified.
220 if (!socktype || !protocol) continue;
221
222 // Skip meaningful combination in explore_options[] of
223 // system\netd\resolv\getaddrinfo.cpp.
224 if ((family == AF_INET6 && socktype == SOCK_DGRAM && protocol == IPPROTO_UDP) ||
225 (family == AF_INET6 && socktype == SOCK_STREAM && protocol == IPPROTO_TCP) ||
226 (family == AF_INET && socktype == SOCK_DGRAM && protocol == IPPROTO_UDP) ||
227 (family == AF_INET && socktype == SOCK_STREAM && protocol == IPPROTO_TCP) ||
228 (family == AF_UNSPEC && socktype == SOCK_DGRAM && protocol == IPPROTO_UDP) ||
229 (family == AF_UNSPEC && socktype == SOCK_STREAM && protocol == IPPROTO_TCP)) {
230 continue;
231 }
232
233 struct addrinfo* result = nullptr;
234 const struct addrinfo hints = {
235 .ai_family = family,
236 .ai_protocol = protocol,
237 .ai_socktype = socktype,
238 };
239
240 int rv = android_getaddrinfofornetcontext("localhost", nullptr /*servname*/, &hints,
241 &mNetcontext, &result);
242 EXPECT_EQ(EAI_BADHINTS, rv);
243
244 if (result) freeaddrinfo(result);
245 }
246 }
247 }
248 }
249
TEST_F(GetAddrInfoForNetContextTest,InvalidParameters_PortNameAndNumber)250 TEST_F(GetAddrInfoForNetContextTest, InvalidParameters_PortNameAndNumber) {
251 constexpr char http_portno[] = "80";
252 constexpr char invalid_portno[] = "65536"; // out of valid port range from 0 to 65535
253 constexpr char http_portname[] = "http";
254 constexpr char invalid_portname[] = "invalid_portname";
255
256 static const struct TestConfig {
257 int ai_flags;
258 int ai_family;
259 int ai_socktype;
260 const char* servname;
261 int expected_errorno; // expected result
262
263 std::string asParameters() const {
264 return StringPrintf("0x%x/%d/%d/%s", ai_flags, ai_family, ai_socktype,
265 servname ? servname : "(null)");
266 }
267 } testConfigs[]{
268 {0, AF_INET, SOCK_RAW /*bad*/, http_portno, EAI_SERVICE},
269 {0, AF_INET6, SOCK_RAW /*bad*/, http_portno, EAI_SERVICE},
270 {0, AF_UNSPEC, SOCK_RAW /*bad*/, http_portno, EAI_SERVICE},
271 {0, AF_INET, SOCK_RDM /*bad*/, http_portno, EAI_SOCKTYPE},
272 {0, AF_INET6, SOCK_RDM /*bad*/, http_portno, EAI_SOCKTYPE},
273 {0, AF_UNSPEC, SOCK_RDM /*bad*/, http_portno, EAI_SOCKTYPE},
274 {0, AF_INET, SOCK_SEQPACKET /*bad*/, http_portno, EAI_SOCKTYPE},
275 {0, AF_INET6, SOCK_SEQPACKET /*bad*/, http_portno, EAI_SOCKTYPE},
276 {0, AF_UNSPEC, SOCK_SEQPACKET /*bad*/, http_portno, EAI_SOCKTYPE},
277 {0, AF_INET, SOCK_DCCP /*bad*/, http_portno, EAI_SOCKTYPE},
278 {0, AF_INET6, SOCK_DCCP /*bad*/, http_portno, EAI_SOCKTYPE},
279 {0, AF_UNSPEC, SOCK_DCCP /*bad*/, http_portno, EAI_SOCKTYPE},
280 {0, AF_INET, SOCK_PACKET /*bad*/, http_portno, EAI_SOCKTYPE},
281 {0, AF_INET6, SOCK_PACKET /*bad*/, http_portno, EAI_SOCKTYPE},
282 {0, AF_UNSPEC, SOCK_PACKET /*bad*/, http_portno, EAI_SOCKTYPE},
283 {0, AF_INET, ANY, invalid_portno /*bad*/, EAI_SERVICE},
284 {0, AF_INET, SOCK_STREAM, invalid_portno /*bad*/, EAI_SERVICE},
285 {0, AF_INET, SOCK_DGRAM, invalid_portno /*bad*/, EAI_SERVICE},
286 {0, AF_INET6, ANY, invalid_portno /*bad*/, EAI_SERVICE},
287 {0, AF_INET6, SOCK_STREAM, invalid_portno /*bad*/, EAI_SERVICE},
288 {0, AF_INET6, SOCK_DGRAM, invalid_portno /*bad*/, EAI_SERVICE},
289 {0, AF_UNSPEC, ANY, invalid_portno /*bad*/, EAI_SERVICE},
290 {0, AF_UNSPEC, SOCK_STREAM, invalid_portno /*bad*/, EAI_SERVICE},
291 {0, AF_UNSPEC, SOCK_DGRAM, invalid_portno /*bad*/, EAI_SERVICE},
292 {AI_NUMERICSERV, AF_INET, ANY, http_portname /*bad*/, EAI_NONAME},
293 {AI_NUMERICSERV, AF_INET, SOCK_STREAM, http_portname /*bad*/, EAI_NONAME},
294 {AI_NUMERICSERV, AF_INET, SOCK_DGRAM, http_portname /*bad*/, EAI_NONAME},
295 {AI_NUMERICSERV, AF_INET6, ANY, http_portname /*bad*/, EAI_NONAME},
296 {AI_NUMERICSERV, AF_INET6, SOCK_STREAM, http_portname /*bad*/, EAI_NONAME},
297 {AI_NUMERICSERV, AF_INET6, SOCK_DGRAM, http_portname /*bad*/, EAI_NONAME},
298 {AI_NUMERICSERV, AF_UNSPEC, ANY, http_portname /*bad*/, EAI_NONAME},
299 {AI_NUMERICSERV, AF_UNSPEC, SOCK_STREAM, http_portname /*bad*/, EAI_NONAME},
300 {AI_NUMERICSERV, AF_UNSPEC, SOCK_DGRAM, http_portname /*bad*/, EAI_NONAME},
301 {0, AF_INET, ANY, invalid_portname /*bad*/, EAI_SERVICE},
302 {0, AF_INET, SOCK_STREAM, invalid_portname /*bad*/, EAI_SERVICE},
303 {0, AF_INET, SOCK_DGRAM, invalid_portname /*bad*/, EAI_SERVICE},
304 {0, AF_INET6, ANY, invalid_portname /*bad*/, EAI_SERVICE},
305 {0, AF_INET6, SOCK_STREAM, invalid_portname /*bad*/, EAI_SERVICE},
306 {0, AF_INET6, SOCK_DGRAM, invalid_portname /*bad*/, EAI_SERVICE},
307 {0, AF_UNSPEC, ANY, invalid_portname /*bad*/, EAI_SERVICE},
308 {0, AF_UNSPEC, SOCK_STREAM, invalid_portname /*bad*/, EAI_SERVICE},
309 {0, AF_UNSPEC, SOCK_DGRAM, invalid_portname /*bad*/, EAI_SERVICE},
310 };
311
312 for (const auto& config : testConfigs) {
313 const std::string testParameters = config.asParameters();
314 SCOPED_TRACE(testParameters);
315
316 const struct addrinfo hints = {
317 .ai_flags = config.ai_flags,
318 .ai_family = config.ai_family,
319 .ai_socktype = config.ai_socktype,
320 };
321
322 struct addrinfo* result = nullptr;
323 int rv = android_getaddrinfofornetcontext("localhost", config.servname, &hints,
324 &mNetcontext, &result);
325 EXPECT_EQ(config.expected_errorno, rv);
326
327 if (result) freeaddrinfo(result);
328 }
329 }
330
TEST_F(GetAddrInfoForNetContextTest,AlphabeticalHostname_NoData)331 TEST_F(GetAddrInfoForNetContextTest, AlphabeticalHostname_NoData) {
332 constexpr char listen_addr[] = "127.0.0.3";
333 constexpr char listen_srv[] = "53";
334 constexpr char v4_host_name[] = "v4only.example.com.";
335 test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail);
336 dns.addMapping(v4_host_name, ns_type::ns_t_a, "1.2.3.3");
337 ASSERT_TRUE(dns.startServer());
338 const char* servers[] = {listen_addr};
339 ASSERT_EQ(0, resolv_set_nameservers_for_net(TEST_NETID, servers,
340 sizeof(servers) / sizeof(servers[0]),
341 mDefaultSearchDomains, &mDefaultParams_Binder));
342 dns.clearQueries();
343
344 // Want AAAA answer but DNS server has A answer only.
345 struct addrinfo* result = nullptr;
346 const addrinfo hints = {.ai_family = AF_INET6};
347 int rv = android_getaddrinfofornetcontext("v4only", nullptr, &hints, &mNetcontext, &result);
348 EXPECT_LE(1U, GetNumQueries(dns, v4_host_name));
349 EXPECT_TRUE(result == nullptr);
350 EXPECT_EQ(EAI_NODATA, rv);
351
352 if (result) freeaddrinfo(result);
353 }
354
TEST_F(GetAddrInfoForNetContextTest,AlphabeticalHostname)355 TEST_F(GetAddrInfoForNetContextTest, AlphabeticalHostname) {
356 constexpr char listen_addr[] = "127.0.0.3";
357 constexpr char listen_srv[] = "53";
358 constexpr char host_name[] = "sawadee.example.com.";
359 constexpr char v4addr[] = "1.2.3.4";
360 constexpr char v6addr[] = "::1.2.3.4";
361
362 test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail);
363 dns.addMapping(host_name, ns_type::ns_t_a, v4addr);
364 dns.addMapping(host_name, ns_type::ns_t_aaaa, v6addr);
365 ASSERT_TRUE(dns.startServer());
366 const char* servers[] = {listen_addr};
367 ASSERT_EQ(0, resolv_set_nameservers_for_net(TEST_NETID, servers,
368 sizeof(servers) / sizeof(servers[0]),
369 mDefaultSearchDomains, &mDefaultParams_Binder));
370
371 static const struct TestConfig {
372 int ai_family;
373 const std::string expected_addr;
374 } testConfigs[]{
375 {AF_INET, v4addr},
376 {AF_INET6, v6addr},
377 };
378
379 for (const auto& config : testConfigs) {
380 SCOPED_TRACE(StringPrintf("family: %d", config.ai_family));
381 dns.clearQueries();
382
383 struct addrinfo* result = nullptr;
384 const struct addrinfo hints = {.ai_family = config.ai_family};
385 int rv =
386 android_getaddrinfofornetcontext("sawadee", nullptr, &hints, &mNetcontext, &result);
387 EXPECT_EQ(0, rv);
388 EXPECT_TRUE(result != nullptr);
389 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
390 EXPECT_EQ(config.expected_addr, ToString(result));
391
392 if (result) freeaddrinfo(result);
393 }
394 }
395
TEST_F(GetAddrInfoForNetContextTest,ServerResponseError)396 TEST_F(GetAddrInfoForNetContextTest, ServerResponseError) {
397 constexpr char listen_addr[] = "127.0.0.3";
398 constexpr char listen_srv[] = "53";
399 constexpr char host_name[] = "hello.example.com.";
400
401 static const struct TestConfig {
402 ns_rcode rcode;
403 int expected_errorno; // expected result
404
405 // Only test failure RCODE [1..5] in RFC 1035 section 4.1.1 and skip successful RCODE 0
406 // which means no error.
407 } testConfigs[]{
408 // clang-format off
409 {ns_rcode::ns_r_formerr, EAI_FAIL},
410 {ns_rcode::ns_r_servfail, EAI_AGAIN},
411 {ns_rcode::ns_r_nxdomain, EAI_NODATA},
412 {ns_rcode::ns_r_notimpl, EAI_FAIL},
413 {ns_rcode::ns_r_refused, EAI_FAIL},
414 // clang-format on
415 };
416
417 for (const auto& config : testConfigs) {
418 SCOPED_TRACE(StringPrintf("rcode: %d", config.rcode));
419
420 test::DNSResponder dns(listen_addr, listen_srv, 250,
421 config.rcode /*response specific rcode*/);
422 dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.4");
423 dns.setResponseProbability(0.0); // always ignore requests and response preset rcode
424 ASSERT_TRUE(dns.startServer());
425 const char* servers[] = {listen_addr};
426 ASSERT_EQ(0, resolv_set_nameservers_for_net(TEST_NETID, servers,
427 sizeof(servers) / sizeof(servers[0]),
428 mDefaultSearchDomains, &mDefaultParams_Binder));
429
430 struct addrinfo* result = nullptr;
431 const struct addrinfo hints = {.ai_family = AF_UNSPEC};
432 int rv =
433 android_getaddrinfofornetcontext(host_name, nullptr, &hints, &mNetcontext, &result);
434 EXPECT_EQ(config.expected_errorno, rv);
435
436 if (result) freeaddrinfo(result);
437 }
438 }
439
440 // TODO: Add private DNS server timeout test.
TEST_F(GetAddrInfoForNetContextTest,ServerTimeout)441 TEST_F(GetAddrInfoForNetContextTest, ServerTimeout) {
442 constexpr char listen_addr[] = "127.0.0.3";
443 constexpr char listen_srv[] = "53";
444 constexpr char host_name[] = "hello.example.com.";
445 test::DNSResponder dns(listen_addr, listen_srv, 250, static_cast<ns_rcode>(-1) /*no response*/);
446 dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.4");
447 dns.setResponseProbability(0.0); // always ignore requests and don't response
448 ASSERT_TRUE(dns.startServer());
449 const char* servers[] = {listen_addr};
450 ASSERT_EQ(0, resolv_set_nameservers_for_net(TEST_NETID, servers,
451 sizeof(servers) / sizeof(servers[0]),
452 mDefaultSearchDomains, &mDefaultParams_Binder));
453
454 struct addrinfo* result = nullptr;
455 const struct addrinfo hints = {.ai_family = AF_UNSPEC};
456 int rv = android_getaddrinfofornetcontext("hello", nullptr, &hints, &mNetcontext, &result);
457 EXPECT_EQ(NETD_RESOLV_TIMEOUT, rv);
458
459 if (result) freeaddrinfo(result);
460 }
461
TEST_F(GetHostByNameForNetContextTest,AlphabeticalHostname)462 TEST_F(GetHostByNameForNetContextTest, AlphabeticalHostname) {
463 constexpr char listen_addr[] = "127.0.0.3";
464 constexpr char listen_srv[] = "53";
465 constexpr char host_name[] = "jiababuei.example.com.";
466 constexpr char v4addr[] = "1.2.3.4";
467 constexpr char v6addr[] = "::1.2.3.4";
468
469 test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail);
470 dns.addMapping(host_name, ns_type::ns_t_a, v4addr);
471 dns.addMapping(host_name, ns_type::ns_t_aaaa, v6addr);
472 ASSERT_TRUE(dns.startServer());
473 const char* servers[] = {listen_addr};
474 ASSERT_EQ(0, resolv_set_nameservers_for_net(TEST_NETID, servers,
475 sizeof(servers) / sizeof(servers[0]),
476 mDefaultSearchDomains, &mDefaultParams_Binder));
477
478 static const struct TestConfig {
479 int ai_family;
480 const std::string expected_addr;
481 } testConfigs[]{
482 {AF_INET, v4addr},
483 {AF_INET6, v6addr},
484 };
485
486 for (const auto& config : testConfigs) {
487 SCOPED_TRACE(StringPrintf("family: %d", config.ai_family));
488 dns.clearQueries();
489
490 struct hostent* hp = nullptr;
491 int rv = android_gethostbynamefornetcontext("jiababuei", config.ai_family, &mNetcontext,
492 &hp);
493 EXPECT_EQ(0, rv);
494 EXPECT_TRUE(hp != nullptr);
495 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
496 EXPECT_EQ(config.expected_addr, ToString(hp));
497 }
498 }
499
TEST_F(GetHostByNameForNetContextTest,NoData)500 TEST_F(GetHostByNameForNetContextTest, NoData) {
501 constexpr char listen_addr[] = "127.0.0.3";
502 constexpr char listen_srv[] = "53";
503 constexpr char v4_host_name[] = "v4only.example.com.";
504 test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail);
505 dns.addMapping(v4_host_name, ns_type::ns_t_a, "1.2.3.3");
506 ASSERT_TRUE(dns.startServer());
507 const char* servers[] = {listen_addr};
508 ASSERT_EQ(0, resolv_set_nameservers_for_net(TEST_NETID, servers,
509 sizeof(servers) / sizeof(servers[0]),
510 mDefaultSearchDomains, &mDefaultParams_Binder));
511 dns.clearQueries();
512
513 // Want AAAA answer but DNS server has A answer only.
514 struct hostent* hp = nullptr;
515 int rv = android_gethostbynamefornetcontext("v4only", AF_INET6, &mNetcontext, &hp);
516 EXPECT_LE(1U, GetNumQueries(dns, v4_host_name));
517 EXPECT_TRUE(hp == nullptr);
518 EXPECT_EQ(EAI_NODATA, rv);
519 }
520
TEST_F(GetHostByNameForNetContextTest,ServerResponseError)521 TEST_F(GetHostByNameForNetContextTest, ServerResponseError) {
522 constexpr char listen_addr[] = "127.0.0.3";
523 constexpr char listen_srv[] = "53";
524 constexpr char host_name[] = "hello.example.com.";
525
526 static const struct TestConfig {
527 ns_rcode rcode;
528 int expected_errorno; // expected result
529
530 // Only test failure RCODE [1..5] in RFC 1035 section 4.1.1 and skip successful RCODE 0
531 // which means no error. Note that the return error codes aren't mapped by rcode in the
532 // test case SERVFAIL, NOTIMP and REFUSED. See the comment of res_nsend()
533 // in system\netd\resolv\res_query.cpp for more detail.
534 } testConfigs[]{
535 // clang-format off
536 {ns_rcode::ns_r_formerr, EAI_FAIL},
537 {ns_rcode::ns_r_servfail, EAI_AGAIN}, // Not mapped by rcode.
538 {ns_rcode::ns_r_nxdomain, EAI_NODATA},
539 {ns_rcode::ns_r_notimpl, EAI_AGAIN}, // Not mapped by rcode.
540 {ns_rcode::ns_r_refused, EAI_AGAIN}, // Not mapped by rcode.
541 // clang-format on
542 };
543
544 for (const auto& config : testConfigs) {
545 SCOPED_TRACE(StringPrintf("rcode: %d", config.rcode));
546
547 test::DNSResponder dns(listen_addr, listen_srv, 250,
548 config.rcode /*response specific rcode*/);
549 dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.4");
550 dns.setResponseProbability(0.0); // always ignore requests and response preset rcode
551 ASSERT_TRUE(dns.startServer());
552 const char* servers[] = {listen_addr};
553 ASSERT_EQ(0, resolv_set_nameservers_for_net(TEST_NETID, servers,
554 sizeof(servers) / sizeof(servers[0]),
555 mDefaultSearchDomains, &mDefaultParams_Binder));
556
557 struct hostent* hp = nullptr;
558 int rv = android_gethostbynamefornetcontext(host_name, AF_INET, &mNetcontext, &hp);
559 EXPECT_TRUE(hp == nullptr);
560 EXPECT_EQ(config.expected_errorno, rv);
561 }
562 }
563
564 // TODO: Add private DNS server timeout test.
TEST_F(GetHostByNameForNetContextTest,ServerTimeout)565 TEST_F(GetHostByNameForNetContextTest, ServerTimeout) {
566 constexpr char listen_addr[] = "127.0.0.3";
567 constexpr char listen_srv[] = "53";
568 constexpr char host_name[] = "hello.example.com.";
569 test::DNSResponder dns(listen_addr, listen_srv, 250, static_cast<ns_rcode>(-1) /*no response*/);
570 dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.4");
571 dns.setResponseProbability(0.0); // always ignore requests and don't response
572 ASSERT_TRUE(dns.startServer());
573 const char* servers[] = {listen_addr};
574 ASSERT_EQ(0, resolv_set_nameservers_for_net(TEST_NETID, servers,
575 sizeof(servers) / sizeof(servers[0]),
576 mDefaultSearchDomains, &mDefaultParams_Binder));
577
578 struct hostent* hp = nullptr;
579 int rv = android_gethostbynamefornetcontext(host_name, AF_INET, &mNetcontext, &hp);
580 EXPECT_EQ(NETD_RESOLV_TIMEOUT, rv);
581 }
582
583 // Note that local host file function, files_getaddrinfo(), of android_getaddrinfofornetcontext()
584 // is not tested because it only returns a boolean (success or failure) without any error number.
585
586 // TODO: Add test NULL hostname, or numeric hostname for android_getaddrinfofornetcontext.
587 // TODO: Add test invalid parameters for android_gethostbynamefornetcontext.
588 // TODO: Add test for android_gethostbyaddrfornetcontext.
589
590 } // end of namespace net
591 } // end of namespace android
592