blob: ef912665db45d0d2a2e3254d0b1bb1934bf7bcd3 [file] [log] [blame]
Pierre Imai904ce3a2016-02-18 13:13:12 +09001/*
2 * Copyright (C) 2016 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 requied 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
18#include <arpa/inet.h>
19#include <errno.h>
20#include <netdb.h>
21#include <stdarg.h>
22#include <stdio.h>
23#include <stdlib.h>
Pierre Imai95f5f942016-03-09 18:09:25 +090024#include <unistd.h>
Pierre Imai904ce3a2016-02-18 13:13:12 +090025
26#include <cutils/sockets.h>
Pierre Imai95f5f942016-03-09 18:09:25 +090027#include <android-base/stringprintf.h>
Pierre Imai904ce3a2016-02-18 13:13:12 +090028#include <private/android_filesystem_config.h>
Pierre Imai95f5f942016-03-09 18:09:25 +090029
Pierre Imaibeedec32016-04-13 06:44:51 +090030#include <algorithm>
31#include <chrono>
32#include <iterator>
33#include <numeric>
Pierre Imai95f5f942016-03-09 18:09:25 +090034#include <thread>
35
Pierre Imaibeedec32016-04-13 06:44:51 +090036#define LOG_TAG "netd_test"
37// TODO: make this dynamic and stop depending on implementation details.
38#define TEST_OEM_NETWORK "oem29"
39#define TEST_NETID 30
40
Pierre Imai904ce3a2016-02-18 13:13:12 +090041#include "NetdClient.h"
42
43#include <gtest/gtest.h>
Pierre Imaibeedec32016-04-13 06:44:51 +090044
Pierre Imai904ce3a2016-02-18 13:13:12 +090045#include <utils/Log.h>
Pierre Imaibeedec32016-04-13 06:44:51 +090046
Pierre Imai904ce3a2016-02-18 13:13:12 +090047#include <testUtil.h>
48
49#include "dns_responder.h"
Pierre Imai95f5f942016-03-09 18:09:25 +090050#include "resolv_params.h"
Pierre Imaibeedec32016-04-13 06:44:51 +090051#include "ResolverStats.h"
52
53#include "android/net/INetd.h"
54#include "binder/IServiceManager.h"
Pierre Imai95f5f942016-03-09 18:09:25 +090055
56using android::base::StringPrintf;
57using android::base::StringAppendF;
Pierre Imaibeedec32016-04-13 06:44:51 +090058using android::net::ResolverStats;
Pierre Imai904ce3a2016-02-18 13:13:12 +090059
Pierre Imaibeedec32016-04-13 06:44:51 +090060// Emulates the behavior of UnorderedElementsAreArray, which currently cannot be used.
61// TODO: Use UnorderedElementsAreArray, which depends on being able to compile libgmock_host,
62// if that is not possible, improve this hacky algorithm, which is O(n**2)
63template <class A, class B>
64bool UnorderedCompareArray(const A& a, const B& b) {
65 if (a.size() != b.size()) return false;
66 for (const auto& a_elem : a) {
67 size_t a_count = 0;
68 for (const auto& a_elem2 : a) {
69 if (a_elem == a_elem2) {
70 ++a_count;
71 }
72 }
73 size_t b_count = 0;
74 for (const auto& b_elem : b) {
75 if (a_elem == b_elem) ++b_count;
76 }
77 if (a_count != b_count) return false;
78 }
79 return true;
80}
Pierre Imai904ce3a2016-02-18 13:13:12 +090081
Pierre Imai95f5f942016-03-09 18:09:25 +090082// The only response code used in this test, see
83// frameworks/base/services/java/com/android/server/NetworkManagementService.java
84// for others.
85static constexpr int ResponseCodeOK = 200;
Pierre Imai904ce3a2016-02-18 13:13:12 +090086
87// Returns ResponseCode.
88int netdCommand(const char* sockname, const char* command) {
89 int sock = socket_local_client(sockname,
90 ANDROID_SOCKET_NAMESPACE_RESERVED,
91 SOCK_STREAM);
92 if (sock < 0) {
93 perror("Error connecting");
94 return -1;
95 }
96
97 // FrameworkListener expects the whole command in one read.
98 char buffer[256];
99 int nwritten = snprintf(buffer, sizeof(buffer), "0 %s", command);
100 if (write(sock, buffer, nwritten + 1) < 0) {
101 perror("Error sending netd command");
102 close(sock);
103 return -1;
104 }
105
106 int nread = read(sock, buffer, sizeof(buffer));
107 if (nread < 0) {
108 perror("Error reading response");
109 close(sock);
110 return -1;
111 }
112 close(sock);
113 return atoi(buffer);
114}
115
Pierre Imai95f5f942016-03-09 18:09:25 +0900116bool expectNetdResult(int expected, const char* sockname, const char* format, ...) {
Pierre Imai904ce3a2016-02-18 13:13:12 +0900117 char command[256];
118 va_list args;
119 va_start(args, format);
120 vsnprintf(command, sizeof(command), format, args);
121 va_end(args);
122 int result = netdCommand(sockname, command);
Pierre Imai95f5f942016-03-09 18:09:25 +0900123 EXPECT_EQ(expected, result) << command;
124 return (200 <= expected && expected < 300);
Pierre Imai904ce3a2016-02-18 13:13:12 +0900125}
126
Pierre Imai904ce3a2016-02-18 13:13:12 +0900127class ResolverTest : public ::testing::Test {
128protected:
Pierre Imaibeedec32016-04-13 06:44:51 +0900129 struct Mapping {
130 std::string host;
131 std::string entry;
132 std::string ip4;
133 std::string ip6;
134 };
135
Pierre Imai904ce3a2016-02-18 13:13:12 +0900136 virtual void SetUp() {
137 // Ensure resolutions go via proxy.
138 setenv("ANDROID_DNS_MODE", "", 1);
139 uid = getuid();
140 pid = getpid();
141 SetupOemNetwork();
Pierre Imaibeedec32016-04-13 06:44:51 +0900142
143 // binder setup
144 auto binder = android::defaultServiceManager()->getService(android::String16("netd"));
145 ASSERT_TRUE(binder != nullptr);
146 mNetdSrv = android::interface_cast<android::net::INetd>(binder);
Pierre Imai904ce3a2016-02-18 13:13:12 +0900147 }
148
149 virtual void TearDown() {
150 TearDownOemNetwork();
151 netdCommand("netd", "network destroy " TEST_OEM_NETWORK);
152 }
153
154 void SetupOemNetwork() {
155 netdCommand("netd", "network destroy " TEST_OEM_NETWORK);
Pierre Imai95f5f942016-03-09 18:09:25 +0900156 if (expectNetdResult(ResponseCodeOK, "netd",
Pierre Imai904ce3a2016-02-18 13:13:12 +0900157 "network create %s", TEST_OEM_NETWORK)) {
158 oemNetId = TEST_NETID;
159 }
160 setNetworkForProcess(oemNetId);
161 ASSERT_EQ((unsigned) oemNetId, getNetworkForProcess());
162 }
163
Pierre Imaibeedec32016-04-13 06:44:51 +0900164 void SetupMappings(unsigned num_hosts, const std::vector<std::string>& domains,
165 std::vector<Mapping>* mappings) const {
166 mappings->resize(num_hosts * domains.size());
167 auto mappings_it = mappings->begin();
168 for (unsigned i = 0 ; i < num_hosts ; ++i) {
169 for (const auto& domain : domains) {
170 ASSERT_TRUE(mappings_it != mappings->end());
171 mappings_it->host = StringPrintf("host%u", i);
172 mappings_it->entry = StringPrintf("%s.%s.", mappings_it->host.c_str(),
173 domain.c_str());
174 mappings_it->ip4 = StringPrintf("192.0.2.%u", i%253 + 1);
175 mappings_it->ip6 = StringPrintf("2001:db8::%x", i%65534 + 1);
176 ++mappings_it;
177 }
178 }
179 }
180
181 void SetupDNSServers(unsigned num_servers, const std::vector<Mapping>& mappings,
182 std::vector<std::unique_ptr<test::DNSResponder>>* dns,
183 std::vector<std::string>* servers) const {
184 ASSERT_TRUE(num_servers != 0 && num_servers < 100);
185 const char* listen_srv = "53";
186 dns->resize(num_servers);
187 servers->resize(num_servers);
188 for (unsigned i = 0 ; i < num_servers ; ++i) {
189 auto& server = (*servers)[i];
190 auto& d = (*dns)[i];
191 server = StringPrintf("127.0.0.%u", i + 100);
192 d = std::make_unique<test::DNSResponder>(server, listen_srv, 250,
193 ns_rcode::ns_r_servfail, 1.0);
194 ASSERT_TRUE(d.get() != nullptr);
195 for (const auto& mapping : mappings) {
196 d->addMapping(mapping.entry.c_str(), ns_type::ns_t_a, mapping.ip4.c_str());
197 d->addMapping(mapping.entry.c_str(), ns_type::ns_t_aaaa, mapping.ip6.c_str());
198 }
199 ASSERT_TRUE(d->startServer());
200 }
201 }
202
203 void ShutdownDNSServers(std::vector<std::unique_ptr<test::DNSResponder>>* dns) const {
204 for (const auto& d : *dns) {
205 ASSERT_TRUE(d.get() != nullptr);
206 d->stopServer();
207 }
208 dns->clear();
209 }
210
Pierre Imai904ce3a2016-02-18 13:13:12 +0900211 void TearDownOemNetwork() {
212 if (oemNetId != -1) {
Pierre Imai95f5f942016-03-09 18:09:25 +0900213 expectNetdResult(ResponseCodeOK, "netd",
Pierre Imai904ce3a2016-02-18 13:13:12 +0900214 "network destroy %s", TEST_OEM_NETWORK);
215 }
216 }
217
Pierre Imaibeedec32016-04-13 06:44:51 +0900218 bool SetResolversForNetwork(const std::vector<std::string>& servers,
219 const std::vector<std::string>& domains, const std::vector<int>& params) {
220 auto rv = mNetdSrv->setResolverConfiguration(TEST_NETID, servers, domains, params);
221 return rv.isOk();
222 }
223
Pierre Imai95f5f942016-03-09 18:09:25 +0900224 bool SetResolversForNetwork(const std::vector<std::string>& searchDomains,
225 const std::vector<std::string>& servers, const std::string& params) {
Pierre Imaibeedec32016-04-13 06:44:51 +0900226 std::string cmd = StringPrintf("resolver setnetdns %d \"", oemNetId);
227 if (!searchDomains.empty()) {
228 cmd += searchDomains[0].c_str();
229 for (size_t i = 1 ; i < searchDomains.size() ; ++i) {
230 cmd += " ";
231 cmd += searchDomains[i];
232 }
Pierre Imai95f5f942016-03-09 18:09:25 +0900233 }
Pierre Imaibeedec32016-04-13 06:44:51 +0900234 cmd += "\"";
Pierre Imai95f5f942016-03-09 18:09:25 +0900235
Pierre Imaibeedec32016-04-13 06:44:51 +0900236 for (const auto& str : servers) {
Pierre Imai95f5f942016-03-09 18:09:25 +0900237 cmd += " ";
Pierre Imaibeedec32016-04-13 06:44:51 +0900238 cmd += str;
Pierre Imai95f5f942016-03-09 18:09:25 +0900239 }
240
241 if (!params.empty()) {
242 cmd += " --params \"";
243 cmd += params;
244 cmd += "\"";
245 }
246
247 int rv = netdCommand("netd", cmd.c_str());
Pierre Imai95f5f942016-03-09 18:09:25 +0900248 if (rv != ResponseCodeOK) {
249 return false;
250 }
251 return true;
Pierre Imai904ce3a2016-02-18 13:13:12 +0900252 }
253
Pierre Imaibeedec32016-04-13 06:44:51 +0900254 bool GetResolverInfo(std::vector<std::string>* servers, std::vector<std::string>* domains,
255 __res_params* params, std::vector<ResolverStats>* stats) {
256 using android::net::INetd;
257 std::vector<int32_t> params32;
258 std::vector<int32_t> stats32;
259 auto rv = mNetdSrv->getResolverInfo(TEST_NETID, servers, domains, &params32, &stats32);
260 if (!rv.isOk() || params32.size() != INetd::RESOLVER_PARAMS_COUNT) {
261 return false;
262 }
263 *params = __res_params {
264 .sample_validity = static_cast<uint16_t>(
265 params32[INetd::RESOLVER_PARAMS_SAMPLE_VALIDITY]),
266 .success_threshold = static_cast<uint8_t>(
267 params32[INetd::RESOLVER_PARAMS_SUCCESS_THRESHOLD]),
268 .min_samples = static_cast<uint8_t>(
269 params32[INetd::RESOLVER_PARAMS_MIN_SAMPLES]),
270 .max_samples = static_cast<uint8_t>(
271 params32[INetd::RESOLVER_PARAMS_MAX_SAMPLES])
272 };
273 return ResolverStats::decodeAll(stats32, stats);
274 }
275
Pierre Imai95f5f942016-03-09 18:09:25 +0900276 std::string ToString(const hostent* he) const {
277 if (he == nullptr) return "<null>";
278 char buffer[INET6_ADDRSTRLEN];
279 if (!inet_ntop(he->h_addrtype, he->h_addr_list[0], buffer, sizeof(buffer))) {
280 return "<invalid>";
281 }
282 return buffer;
Pierre Imaiccf7b992016-02-25 16:34:29 +0900283 }
284
Pierre Imai95f5f942016-03-09 18:09:25 +0900285 std::string ToString(const addrinfo* ai) const {
286 if (!ai)
Pierre Imai904ce3a2016-02-18 13:13:12 +0900287 return "<null>";
Pierre Imai95f5f942016-03-09 18:09:25 +0900288 for (const auto* aip = ai ; aip != nullptr ; aip = aip->ai_next) {
289 char host[NI_MAXHOST];
290 int rv = getnameinfo(aip->ai_addr, aip->ai_addrlen, host, sizeof(host), nullptr, 0,
291 NI_NUMERICHOST);
292 if (rv != 0)
293 return gai_strerror(rv);
294 return host;
295 }
296 return "<invalid>";
297 }
298
299 size_t GetNumQueries(const test::DNSResponder& dns, const char* name) const {
300 auto queries = dns.queries();
301 size_t found = 0;
302 for (const auto& p : queries) {
Pierre Imai95f5f942016-03-09 18:09:25 +0900303 if (p.first == name) {
304 ++found;
305 }
306 }
307 return found;
308 }
309
310 size_t GetNumQueriesForType(const test::DNSResponder& dns, ns_type type,
311 const char* name) const {
312 auto queries = dns.queries();
313 size_t found = 0;
314 for (const auto& p : queries) {
Pierre Imai95f5f942016-03-09 18:09:25 +0900315 if (p.second == type && p.first == name) {
316 ++found;
317 }
318 }
319 return found;
Pierre Imai904ce3a2016-02-18 13:13:12 +0900320 }
321
Pierre Imaibeedec32016-04-13 06:44:51 +0900322 void RunGetAddrInfoStressTest_Binder(unsigned num_hosts, unsigned num_threads,
323 unsigned num_queries) {
324 std::vector<std::string> domains = { "example.com" };
325 std::vector<std::unique_ptr<test::DNSResponder>> dns;
326 std::vector<std::string> servers;
327 std::vector<Mapping> mappings;
328 ASSERT_NO_FATAL_FAILURE(SetupMappings(num_hosts, domains, &mappings));
329 ASSERT_NO_FATAL_FAILURE(SetupDNSServers(MAXNS, mappings, &dns, &servers));
330
331 std::vector<int> params = { 300, 25, 8, 8 };
332 ASSERT_TRUE(SetResolversForNetwork(servers, domains, params));
333
334 auto t0 = std::chrono::steady_clock::now();
335 std::vector<std::thread> threads(num_threads);
336 for (std::thread& thread : threads) {
337 thread = std::thread([this, &servers, &dns, &mappings, num_queries]() {
338 for (unsigned i = 0 ; i < num_queries ; ++i) {
339 uint32_t ofs = arc4random_uniform(mappings.size());
340 ASSERT_TRUE(ofs < mappings.size());
341 auto& mapping = mappings[i];
342 addrinfo* result = nullptr;
343 int rv = getaddrinfo(mapping.host.c_str(), nullptr, nullptr, &result);
344 EXPECT_EQ(0, rv) << "error [" << rv << "] " << gai_strerror(rv);
345 if (rv == 0) {
346 std::string result_str = ToString(result);
347 EXPECT_TRUE(result_str == mapping.ip4 || result_str == mapping.ip6)
348 << "result='" << result_str << "', ip4='" << mapping.ip4
349 << "', ip6='" << mapping.ip6;
350 }
351 if (result) {
352 freeaddrinfo(result);
353 result = nullptr;
354 }
355 }
356 });
357 }
358
359 for (std::thread& thread : threads) {
360 thread.join();
361 }
362 auto t1 = std::chrono::steady_clock::now();
363 ALOGI("%u hosts, %u threads, %u queries, %Es", num_hosts, num_threads, num_queries,
364 std::chrono::duration<double>(t1 - t0).count());
365 ASSERT_NO_FATAL_FAILURE(ShutdownDNSServers(&dns));
366 }
367
Pierre Imai904ce3a2016-02-18 13:13:12 +0900368 int pid;
369 int uid;
370 int oemNetId = -1;
Pierre Imaibeedec32016-04-13 06:44:51 +0900371 android::sp<android::net::INetd> mNetdSrv = nullptr;
Pierre Imai95f5f942016-03-09 18:09:25 +0900372 const std::vector<std::string> mDefaultSearchDomains = { "example.com" };
373 // <sample validity in s> <success threshold in percent> <min samples> <max samples>
374 const std::string mDefaultParams = "300 25 8 8";
Pierre Imai904ce3a2016-02-18 13:13:12 +0900375};
376
Pierre Imai904ce3a2016-02-18 13:13:12 +0900377TEST_F(ResolverTest, GetHostByName) {
378 const char* listen_addr = "127.0.0.3";
379 const char* listen_srv = "53";
Pierre Imai95f5f942016-03-09 18:09:25 +0900380 const char* host_name = "hello.example.com.";
381 test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail, 1.0);
382 dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.3");
383 ASSERT_TRUE(dns.startServer());
384 std::vector<std::string> servers = { listen_addr };
385 ASSERT_TRUE(SetResolversForNetwork(mDefaultSearchDomains, servers, mDefaultParams));
Pierre Imai904ce3a2016-02-18 13:13:12 +0900386
Pierre Imai95f5f942016-03-09 18:09:25 +0900387 dns.clearQueries();
Pierre Imai904ce3a2016-02-18 13:13:12 +0900388 const hostent* result = gethostbyname("hello");
Pierre Imai95f5f942016-03-09 18:09:25 +0900389 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
Pierre Imai904ce3a2016-02-18 13:13:12 +0900390 ASSERT_FALSE(result == nullptr);
391 ASSERT_EQ(4, result->h_length);
392 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Pierre Imai95f5f942016-03-09 18:09:25 +0900393 EXPECT_EQ("1.2.3.3", ToString(result));
Pierre Imai904ce3a2016-02-18 13:13:12 +0900394 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Pierre Imai95f5f942016-03-09 18:09:25 +0900395 dns.stopServer();
Pierre Imai904ce3a2016-02-18 13:13:12 +0900396}
397
Pierre Imaibeedec32016-04-13 06:44:51 +0900398TEST_F(ResolverTest, TestBinderSerialization) {
399 using android::net::INetd;
400 std::vector<int> params_offsets = {
401 INetd::RESOLVER_PARAMS_SAMPLE_VALIDITY,
402 INetd::RESOLVER_PARAMS_SUCCESS_THRESHOLD,
403 INetd::RESOLVER_PARAMS_MIN_SAMPLES,
404 INetd::RESOLVER_PARAMS_MAX_SAMPLES
405 };
406 int size = static_cast<int>(params_offsets.size());
407 EXPECT_EQ(size, INetd::RESOLVER_PARAMS_COUNT);
408 std::sort(params_offsets.begin(), params_offsets.end());
409 for (int i = 0 ; i < size ; ++i) {
410 EXPECT_EQ(params_offsets[i], i);
411 }
412}
413
414TEST_F(ResolverTest, GetHostByName_Binder) {
415 using android::net::INetd;
416
417 std::vector<std::string> domains = { "example.com" };
418 std::vector<std::unique_ptr<test::DNSResponder>> dns;
419 std::vector<std::string> servers;
420 std::vector<Mapping> mappings;
421 ASSERT_NO_FATAL_FAILURE(SetupMappings(1, domains, &mappings));
422 ASSERT_NO_FATAL_FAILURE(SetupDNSServers(4, mappings, &dns, &servers));
423 ASSERT_EQ(1U, mappings.size());
424 const Mapping& mapping = mappings[0];
425
426 std::vector<int> params = { 300, 25, 8, 8 };
427 ASSERT_TRUE(SetResolversForNetwork(servers, domains, params));
428
429 const hostent* result = gethostbyname(mapping.host.c_str());
430 size_t total_queries = std::accumulate(dns.begin(), dns.end(), 0,
431 [this, &mapping](size_t total, auto& d) {
432 return total + GetNumQueriesForType(*d, ns_type::ns_t_a, mapping.entry.c_str());
433 });
434
435 EXPECT_LE(1U, total_queries);
436 ASSERT_FALSE(result == nullptr);
437 ASSERT_EQ(4, result->h_length);
438 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
439 EXPECT_EQ(mapping.ip4, ToString(result));
440 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
441
442 std::vector<std::string> res_servers;
443 std::vector<std::string> res_domains;
444 __res_params res_params;
445 std::vector<ResolverStats> res_stats;
446 ASSERT_TRUE(GetResolverInfo(&res_servers, &res_domains, &res_params, &res_stats));
447 EXPECT_EQ(servers.size(), res_servers.size());
448 EXPECT_EQ(domains.size(), res_domains.size());
449 ASSERT_EQ(INetd::RESOLVER_PARAMS_COUNT, params.size());
450 EXPECT_EQ(params[INetd::RESOLVER_PARAMS_SAMPLE_VALIDITY], res_params.sample_validity);
451 EXPECT_EQ(params[INetd::RESOLVER_PARAMS_SUCCESS_THRESHOLD], res_params.success_threshold);
452 EXPECT_EQ(params[INetd::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
453 EXPECT_EQ(params[INetd::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
454 EXPECT_EQ(servers.size(), res_stats.size());
455
456 EXPECT_TRUE(UnorderedCompareArray(res_servers, servers));
457 EXPECT_TRUE(UnorderedCompareArray(res_domains, domains));
458
459 ASSERT_NO_FATAL_FAILURE(ShutdownDNSServers(&dns));
460}
461
Pierre Imai904ce3a2016-02-18 13:13:12 +0900462TEST_F(ResolverTest, GetAddrInfo) {
463 addrinfo* result = nullptr;
464
465 const char* listen_addr = "127.0.0.4";
Pierre Imai6f4f86d2016-04-08 13:15:27 +0900466 const char* listen_addr2 = "127.0.0.5";
Pierre Imai904ce3a2016-02-18 13:13:12 +0900467 const char* listen_srv = "53";
Pierre Imaibeedec32016-04-13 06:44:51 +0900468 const char* host_name = "howdy.example.com.";
Pierre Imai95f5f942016-03-09 18:09:25 +0900469 test::DNSResponder dns(listen_addr, listen_srv, 250,
470 ns_rcode::ns_r_servfail, 1.0);
471 dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.4");
472 dns.addMapping(host_name, ns_type::ns_t_aaaa, "::1.2.3.4");
473 ASSERT_TRUE(dns.startServer());
474 std::vector<std::string> servers = { listen_addr };
475 ASSERT_TRUE(SetResolversForNetwork(mDefaultSearchDomains, servers, mDefaultParams));
Pierre Imai904ce3a2016-02-18 13:13:12 +0900476
Pierre Imai95f5f942016-03-09 18:09:25 +0900477 dns.clearQueries();
Pierre Imaibeedec32016-04-13 06:44:51 +0900478 EXPECT_EQ(0, getaddrinfo("howdy", nullptr, nullptr, &result));
Pierre Imai95f5f942016-03-09 18:09:25 +0900479 size_t found = GetNumQueries(dns, host_name);
Pierre Imaib19fcc72016-03-11 17:54:48 +0900480 EXPECT_LE(1U, found);
Pierre Imai904ce3a2016-02-18 13:13:12 +0900481 // Could be A or AAAA
482 std::string result_str = ToString(result);
Pierre Imai95f5f942016-03-09 18:09:25 +0900483 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
484 << ", result_str='" << result_str << "'";
Pierre Imaibeedec32016-04-13 06:44:51 +0900485 // TODO: Use ScopedAddrinfo or similar once it is available in a common header file.
486 if (result) {
487 freeaddrinfo(result);
488 result = nullptr;
489 }
Pierre Imai904ce3a2016-02-18 13:13:12 +0900490
Pierre Imai6f4f86d2016-04-08 13:15:27 +0900491 // Verify that the name is cached.
Pierre Imaibeedec32016-04-13 06:44:51 +0900492 EXPECT_EQ(0, getaddrinfo("howdy", nullptr, nullptr, &result));
Pierre Imai95f5f942016-03-09 18:09:25 +0900493 found = GetNumQueries(dns, host_name);
Pierre Imaibeedec32016-04-13 06:44:51 +0900494 EXPECT_LE(1U, found);
Pierre Imai904ce3a2016-02-18 13:13:12 +0900495 result_str = ToString(result);
Pierre Imai95f5f942016-03-09 18:09:25 +0900496 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
497 << result_str;
Pierre Imaibeedec32016-04-13 06:44:51 +0900498 if (result) {
499 freeaddrinfo(result);
500 result = nullptr;
501 }
Pierre Imai904ce3a2016-02-18 13:13:12 +0900502
Pierre Imai6f4f86d2016-04-08 13:15:27 +0900503 // Change the DNS resolver, ensure that queries are no longer cached.
Pierre Imai95f5f942016-03-09 18:09:25 +0900504 dns.clearQueries();
Pierre Imai6f4f86d2016-04-08 13:15:27 +0900505 test::DNSResponder dns2(listen_addr2, listen_srv, 250,
506 ns_rcode::ns_r_servfail, 1.0);
507 dns2.addMapping(host_name, ns_type::ns_t_a, "1.2.3.4");
508 dns2.addMapping(host_name, ns_type::ns_t_aaaa, "::1.2.3.4");
509 ASSERT_TRUE(dns2.startServer());
510 servers = { listen_addr2 };
511 ASSERT_TRUE(SetResolversForNetwork(mDefaultSearchDomains, servers, mDefaultParams));
Pierre Imaibeedec32016-04-13 06:44:51 +0900512 EXPECT_EQ(0, getaddrinfo("howdy", nullptr, nullptr, &result));
Pierre Imai6f4f86d2016-04-08 13:15:27 +0900513 found = GetNumQueries(dns, host_name);
514 size_t found2 = GetNumQueries(dns2, host_name);
515 EXPECT_EQ(0U, found);
516 EXPECT_LE(1U, found2);
517
Pierre Imai904ce3a2016-02-18 13:13:12 +0900518 // Could be A or AAAA
519 result_str = ToString(result);
Pierre Imai6f4f86d2016-04-08 13:15:27 +0900520 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
Pierre Imai95f5f942016-03-09 18:09:25 +0900521 << ", result_str='" << result_str << "'";
Pierre Imaibeedec32016-04-13 06:44:51 +0900522 if (result) {
523 freeaddrinfo(result);
524 result = nullptr;
525 }
Pierre Imai6f4f86d2016-04-08 13:15:27 +0900526 dns.stopServer();
527 dns2.stopServer();
Pierre Imai904ce3a2016-02-18 13:13:12 +0900528}
529
530TEST_F(ResolverTest, GetAddrInfoV4) {
531 addrinfo* result = nullptr;
532
533 const char* listen_addr = "127.0.0.5";
534 const char* listen_srv = "53";
Pierre Imai95f5f942016-03-09 18:09:25 +0900535 const char* host_name = "hola.example.com.";
536 test::DNSResponder dns(listen_addr, listen_srv, 250,
537 ns_rcode::ns_r_servfail, 1.0);
538 dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.5");
539 ASSERT_TRUE(dns.startServer());
540 std::vector<std::string> servers = { listen_addr };
541 ASSERT_TRUE(SetResolversForNetwork(mDefaultSearchDomains, servers, mDefaultParams));
Pierre Imai904ce3a2016-02-18 13:13:12 +0900542
543 addrinfo hints;
544 memset(&hints, 0, sizeof(hints));
545 hints.ai_family = AF_INET;
546 EXPECT_EQ(0, getaddrinfo("hola", nullptr, &hints, &result));
Pierre Imai95f5f942016-03-09 18:09:25 +0900547 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
Pierre Imaiccf7b992016-02-25 16:34:29 +0900548 EXPECT_EQ("1.2.3.5", ToString(result));
Pierre Imaibeedec32016-04-13 06:44:51 +0900549 if (result) {
550 freeaddrinfo(result);
551 result = nullptr;
552 }
Pierre Imai904ce3a2016-02-18 13:13:12 +0900553}
Pierre Imai95f5f942016-03-09 18:09:25 +0900554
555TEST_F(ResolverTest, MultidomainResolution) {
556 std::vector<std::string> searchDomains = { "example1.com", "example2.com", "example3.com" };
557 const char* listen_addr = "127.0.0.6";
558 const char* listen_srv = "53";
559 const char* host_name = "nihao.example2.com.";
560 test::DNSResponder dns(listen_addr, listen_srv, 250,
561 ns_rcode::ns_r_servfail, 1.0);
562 dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.3");
563 ASSERT_TRUE(dns.startServer());
564 std::vector<std::string> servers = { listen_addr };
565 ASSERT_TRUE(SetResolversForNetwork(searchDomains, servers, mDefaultParams));
566
567 dns.clearQueries();
568 const hostent* result = gethostbyname("nihao");
569 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
570 ASSERT_FALSE(result == nullptr);
571 ASSERT_EQ(4, result->h_length);
572 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
573 EXPECT_EQ("1.2.3.3", ToString(result));
574 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
575 dns.stopServer();
576}
577
578TEST_F(ResolverTest, GetAddrInfoV6_failing) {
579 addrinfo* result = nullptr;
580
581 const char* listen_addr0 = "127.0.0.7";
582 const char* listen_addr1 = "127.0.0.8";
583 const char* listen_srv = "53";
584 const char* host_name = "ohayou.example.com.";
585 test::DNSResponder dns0(listen_addr0, listen_srv, 250,
586 ns_rcode::ns_r_servfail, 0.0);
587 test::DNSResponder dns1(listen_addr1, listen_srv, 250,
588 ns_rcode::ns_r_servfail, 1.0);
589 dns0.addMapping(host_name, ns_type::ns_t_aaaa, "2001:db8::5");
590 dns1.addMapping(host_name, ns_type::ns_t_aaaa, "2001:db8::6");
591 ASSERT_TRUE(dns0.startServer());
592 ASSERT_TRUE(dns1.startServer());
593 std::vector<std::string> servers = { listen_addr0, listen_addr1 };
594 // <sample validity in s> <success threshold in percent> <min samples> <max samples>
595 unsigned sample_validity = 300;
596 int success_threshold = 25;
597 int sample_count = 8;
598 std::string params = StringPrintf("%u %d %d %d", sample_validity, success_threshold,
599 sample_count, sample_count);
600 ASSERT_TRUE(SetResolversForNetwork(mDefaultSearchDomains, servers, params));
601
602 // Repeatedly perform resolutions for non-existing domains until MAXNSSAMPLES resolutions have
603 // reached the dns0, which is set to fail. No more requests should then arrive at that server
604 // for the next sample_lifetime seconds.
605 // TODO: This approach is implementation-dependent, change once metrics reporting is available.
606 addrinfo hints;
607 memset(&hints, 0, sizeof(hints));
608 hints.ai_family = AF_INET6;
609 for (int i = 0 ; i < sample_count ; ++i) {
610 std::string domain = StringPrintf("nonexistent%d", i);
611 getaddrinfo(domain.c_str(), nullptr, &hints, &result);
Pierre Imaibeedec32016-04-13 06:44:51 +0900612 if (result) {
613 freeaddrinfo(result);
614 result = nullptr;
615 }
Pierre Imai95f5f942016-03-09 18:09:25 +0900616 }
617 // Due to 100% errors for all possible samples, the server should be ignored from now on and
618 // only the second one used for all following queries, until NSSAMPLE_VALIDITY is reached.
619 dns0.clearQueries();
620 dns1.clearQueries();
621 EXPECT_EQ(0, getaddrinfo("ohayou", nullptr, &hints, &result));
622 EXPECT_EQ(0U, GetNumQueries(dns0, host_name));
623 EXPECT_EQ(1U, GetNumQueries(dns1, host_name));
Pierre Imaibeedec32016-04-13 06:44:51 +0900624 if (result) {
625 freeaddrinfo(result);
626 result = nullptr;
627 }
Pierre Imai95f5f942016-03-09 18:09:25 +0900628}
629
630TEST_F(ResolverTest, GetAddrInfoV6_concurrent) {
631 const char* listen_addr0 = "127.0.0.9";
632 const char* listen_addr1 = "127.0.0.10";
633 const char* listen_addr2 = "127.0.0.11";
634 const char* listen_srv = "53";
635 const char* host_name = "konbanha.example.com.";
636 test::DNSResponder dns0(listen_addr0, listen_srv, 250,
637 ns_rcode::ns_r_servfail, 1.0);
638 test::DNSResponder dns1(listen_addr1, listen_srv, 250,
639 ns_rcode::ns_r_servfail, 1.0);
640 test::DNSResponder dns2(listen_addr2, listen_srv, 250,
641 ns_rcode::ns_r_servfail, 1.0);
642 dns0.addMapping(host_name, ns_type::ns_t_aaaa, "2001:db8::5");
643 dns1.addMapping(host_name, ns_type::ns_t_aaaa, "2001:db8::6");
644 dns2.addMapping(host_name, ns_type::ns_t_aaaa, "2001:db8::7");
645 ASSERT_TRUE(dns0.startServer());
646 ASSERT_TRUE(dns1.startServer());
647 ASSERT_TRUE(dns2.startServer());
648 const std::vector<std::string> servers = { listen_addr0, listen_addr1, listen_addr2 };
649 std::vector<std::thread> threads(10);
650 for (std::thread& thread : threads) {
651 thread = std::thread([this, &servers, &dns0, &dns1, &dns2]() {
652 unsigned delay = arc4random_uniform(1*1000*1000); // <= 1s
653 usleep(delay);
654 std::vector<std::string> serverSubset;
655 for (const auto& server : servers) {
656 if (arc4random_uniform(2)) {
657 serverSubset.push_back(server);
658 }
659 }
660 if (serverSubset.empty()) serverSubset = servers;
661 ASSERT_TRUE(SetResolversForNetwork(mDefaultSearchDomains, serverSubset,
662 mDefaultParams));
663 addrinfo hints;
664 memset(&hints, 0, sizeof(hints));
665 hints.ai_family = AF_INET6;
666 addrinfo* result = nullptr;
667 int rv = getaddrinfo("konbanha", nullptr, &hints, &result);
668 EXPECT_EQ(0, rv) << "error [" << rv << "] " << gai_strerror(rv);
Pierre Imaibeedec32016-04-13 06:44:51 +0900669 if (result) {
670 freeaddrinfo(result);
671 result = nullptr;
672 }
Pierre Imai95f5f942016-03-09 18:09:25 +0900673 });
674 }
675 for (std::thread& thread : threads) {
676 thread.join();
677 }
678}
Pierre Imaibeedec32016-04-13 06:44:51 +0900679
680TEST_F(ResolverTest, GetAddrInfoStressTest_Binder_100) {
681 const unsigned num_hosts = 100;
682 const unsigned num_threads = 100;
683 const unsigned num_queries = 100;
684 ASSERT_NO_FATAL_FAILURE(RunGetAddrInfoStressTest_Binder(num_hosts, num_threads, num_queries));
685}
686
687TEST_F(ResolverTest, GetAddrInfoStressTest_Binder_100000) {
688 const unsigned num_hosts = 100000;
689 const unsigned num_threads = 100;
690 const unsigned num_queries = 100;
691 ASSERT_NO_FATAL_FAILURE(RunGetAddrInfoStressTest_Binder(num_hosts, num_threads, num_queries));
692}
693
694TEST_F(ResolverTest, EmptySetup) {
695 using android::net::INetd;
696 std::vector<std::string> servers;
697 std::vector<std::string> domains;
698 std::vector<int> params = { 300, 25, 8, 8 };
699 ASSERT_TRUE(SetResolversForNetwork(servers, domains, params));
700 std::vector<std::string> res_servers;
701 std::vector<std::string> res_domains;
702 __res_params res_params;
703 std::vector<ResolverStats> res_stats;
704 ASSERT_TRUE(GetResolverInfo(&res_servers, &res_domains, &res_params, &res_stats));
705 EXPECT_EQ(0U, res_servers.size());
706 EXPECT_EQ(0U, res_domains.size());
707 ASSERT_EQ(INetd::RESOLVER_PARAMS_COUNT, params.size());
708 EXPECT_EQ(params[INetd::RESOLVER_PARAMS_SAMPLE_VALIDITY], res_params.sample_validity);
709 EXPECT_EQ(params[INetd::RESOLVER_PARAMS_SUCCESS_THRESHOLD], res_params.success_threshold);
710 EXPECT_EQ(params[INetd::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
711 EXPECT_EQ(params[INetd::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
712}