blob: c6a68e9949b0bd03b799a23c48ce1456d53932fc [file] [log] [blame]
Bernie Innocenti443489e2018-08-10 14:27:23 +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
Bernie Innocentic165ce82018-10-16 23:35:28 +090018#define LOG_TAG "netd_test"
19
Bernie Innocenti443489e2018-08-10 14:27:23 +090020#include <arpa/inet.h>
Luke Huangc68f1b92018-11-21 20:13:38 +080021#include <arpa/nameser.h>
Bernie Innocenti443489e2018-08-10 14:27:23 +090022#include <netdb.h>
Luke Huangc68f1b92018-11-21 20:13:38 +080023#include <netinet/in.h>
24#include <poll.h> /* poll */
25#include <resolv.h>
Bernie Innocenti443489e2018-08-10 14:27:23 +090026#include <stdarg.h>
27#include <stdio.h>
28#include <stdlib.h>
Luke Huangc68f1b92018-11-21 20:13:38 +080029#include <sys/socket.h>
30#include <sys/un.h>
Bernie Innocenti443489e2018-08-10 14:27:23 +090031#include <unistd.h>
32
33#include <algorithm>
34#include <chrono>
35#include <iterator>
36#include <numeric>
37#include <thread>
38
Bernie Innocenti443489e2018-08-10 14:27:23 +090039#include <android-base/stringprintf.h>
Luke Huang952d0942018-12-26 16:53:03 +080040#include <android/multinetwork.h> // ResNsendFlags
Bernie Innocenti0298c682018-10-02 23:18:11 +090041#include <cutils/sockets.h>
Bernie Innocentic165ce82018-10-16 23:35:28 +090042#include <gtest/gtest.h>
Bernie Innocenti443489e2018-08-10 14:27:23 +090043#include <openssl/base64.h>
Bernie Innocentic165ce82018-10-16 23:35:28 +090044#include <private/android_filesystem_config.h>
45#include <utils/Log.h>
Bernie Innocenti443489e2018-08-10 14:27:23 +090046
Bernie Innocenti443489e2018-08-10 14:27:23 +090047#include "NetdClient.h"
Bernie Innocenti189eb502018-10-01 23:10:18 +090048#include "netid_client.h" // NETID_UNSET
Bernie Innocentic165ce82018-10-16 23:35:28 +090049#include "netd_resolv/params.h" // MAX_NS
Bernie Innocenti443489e2018-08-10 14:27:23 +090050
Ken Chenc68c2de2018-11-13 21:51:13 +080051#include "dns_responder/dns_responder.h"
52#include "dns_responder/dns_responder_client.h"
53#include "dns_responder/dns_tls_frontend.h"
Bernie Innocenti9bf749f2018-08-30 08:37:22 +090054
55#include "NetdConstants.h"
Bernie Innocenti443489e2018-08-10 14:27:23 +090056#include "ResolverStats.h"
57
58#include "android/net/INetd.h"
Bernie Innocenti443489e2018-08-10 14:27:23 +090059#include "binder/IServiceManager.h"
60#include "netdutils/SocketOption.h"
61
Bernie Innocentic165ce82018-10-16 23:35:28 +090062// TODO: make this dynamic and stop depending on implementation details.
Luke Huangc68f1b92018-11-21 20:13:38 +080063constexpr int TEST_NETID = 30;
64constexpr int MAXPACKET = (8 * 1024);
Bernie Innocentic165ce82018-10-16 23:35:28 +090065
66// Semi-public Bionic hook used by the NDK (frameworks/base/native/android/net.c)
67// Tested here for convenience.
68extern "C" int android_getaddrinfofornet(const char* hostname, const char* servname,
69 const addrinfo* hints, unsigned netid, unsigned mark,
70 struct addrinfo** result);
71
Bernie Innocenti443489e2018-08-10 14:27:23 +090072using android::base::StringPrintf;
73using android::net::ResolverStats;
Bernie Innocenti443489e2018-08-10 14:27:23 +090074using android::netdutils::enableSockopt;
75
Bernie Innocenti9bf749f2018-08-30 08:37:22 +090076// TODO: move into libnetdutils?
77namespace {
78ScopedAddrinfo safe_getaddrinfo(const char* node, const char* service,
79 const struct addrinfo* hints) {
80 addrinfo* result = nullptr;
81 if (getaddrinfo(node, service, hints, &result) != 0) {
82 result = nullptr; // Should already be the case, but...
83 }
84 return ScopedAddrinfo(result);
85}
86} // namespace
87
Bernie Innocenti443489e2018-08-10 14:27:23 +090088// Emulates the behavior of UnorderedElementsAreArray, which currently cannot be used.
89// TODO: Use UnorderedElementsAreArray, which depends on being able to compile libgmock_host,
90// if that is not possible, improve this hacky algorithm, which is O(n**2)
91template <class A, class B>
92bool UnorderedCompareArray(const A& a, const B& b) {
93 if (a.size() != b.size()) return false;
94 for (const auto& a_elem : a) {
95 size_t a_count = 0;
96 for (const auto& a_elem2 : a) {
97 if (a_elem == a_elem2) {
98 ++a_count;
99 }
100 }
101 size_t b_count = 0;
102 for (const auto& b_elem : b) {
103 if (a_elem == b_elem) ++b_count;
104 }
105 if (a_count != b_count) return false;
106 }
107 return true;
108}
109
Bernie Innocenti3e411a32019-01-17 21:28:24 +0900110class ResolverTest : public ::testing::Test {
Bernie Innocenti0298c682018-10-02 23:18:11 +0900111 protected:
Xiao Ma7c75f452018-12-11 17:56:32 +0900112 struct DnsRecord {
113 std::string host_name; // host name
114 ns_type type; // record type
115 std::string addr; // ipv4/v6 address
116 };
117
Bernie Innocenti3e411a32019-01-17 21:28:24 +0900118 void SetUp() { mDnsClient.SetUp(); }
119 void TearDown() { mDnsClient.TearDown(); }
Bernie Innocenti443489e2018-08-10 14:27:23 +0900120
121 bool GetResolverInfo(std::vector<std::string>* servers, std::vector<std::string>* domains,
Bernie Innocenti34de3ba2019-02-19 18:08:36 +0900122 std::vector<std::string>* tlsServers, res_params* params,
Ken Chen2a429352018-12-22 21:46:55 +0800123 std::vector<ResolverStats>* stats,
124 int* wait_for_pending_req_timeout_count) {
Bernie Innocenti443489e2018-08-10 14:27:23 +0900125 using android::net::INetd;
126 std::vector<int32_t> params32;
127 std::vector<int32_t> stats32;
Ken Chen2a429352018-12-22 21:46:55 +0800128 std::vector<int32_t> wait_for_pending_req_timeout_count32{0};
Bernie Innocenti3e411a32019-01-17 21:28:24 +0900129 auto rv = mDnsClient.netdService()->getResolverInfo(TEST_NETID, servers, domains,
Ken Chen2a429352018-12-22 21:46:55 +0800130 tlsServers, &params32, &stats32,
131 &wait_for_pending_req_timeout_count32);
132
Bernie Innocenti45238a12018-12-04 14:57:48 +0900133 if (!rv.isOk() || params32.size() != static_cast<size_t>(INetd::RESOLVER_PARAMS_COUNT)) {
Bernie Innocenti443489e2018-08-10 14:27:23 +0900134 return false;
135 }
Bernie Innocenti34de3ba2019-02-19 18:08:36 +0900136 *params = res_params{
waynemad193e4d2019-02-18 17:47:59 +0800137 .sample_validity =
138 static_cast<uint16_t>(params32[INetd::RESOLVER_PARAMS_SAMPLE_VALIDITY]),
139 .success_threshold =
140 static_cast<uint8_t>(params32[INetd::RESOLVER_PARAMS_SUCCESS_THRESHOLD]),
141 .min_samples = static_cast<uint8_t>(params32[INetd::RESOLVER_PARAMS_MIN_SAMPLES]),
142 .max_samples = static_cast<uint8_t>(params32[INetd::RESOLVER_PARAMS_MAX_SAMPLES]),
143 .base_timeout_msec = params32[INetd::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
144 .retry_count = params32[INetd::RESOLVER_PARAMS_RETRY_COUNT],
Bernie Innocenti443489e2018-08-10 14:27:23 +0900145 };
Ken Chen2a429352018-12-22 21:46:55 +0800146 *wait_for_pending_req_timeout_count = wait_for_pending_req_timeout_count32[0];
Bernie Innocenti443489e2018-08-10 14:27:23 +0900147 return ResolverStats::decodeAll(stats32, stats);
148 }
149
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900150 static std::string ToString(const hostent* he) {
Bernie Innocenti443489e2018-08-10 14:27:23 +0900151 if (he == nullptr) return "<null>";
152 char buffer[INET6_ADDRSTRLEN];
153 if (!inet_ntop(he->h_addrtype, he->h_addr_list[0], buffer, sizeof(buffer))) {
154 return "<invalid>";
155 }
156 return buffer;
157 }
158
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900159 static std::string ToString(const addrinfo* ai) {
Bernie Innocenti443489e2018-08-10 14:27:23 +0900160 if (!ai)
161 return "<null>";
162 for (const auto* aip = ai ; aip != nullptr ; aip = aip->ai_next) {
163 char host[NI_MAXHOST];
164 int rv = getnameinfo(aip->ai_addr, aip->ai_addrlen, host, sizeof(host), nullptr, 0,
165 NI_NUMERICHOST);
166 if (rv != 0)
167 return gai_strerror(rv);
168 return host;
169 }
170 return "<invalid>";
171 }
172
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900173 static std::string ToString(const ScopedAddrinfo& ai) { return ToString(ai.get()); }
174
nuccachenf52f7a52018-07-17 18:07:23 +0800175 static std::vector<std::string> ToStrings(const addrinfo* ai) {
176 std::vector<std::string> hosts;
177 if (!ai) {
178 hosts.push_back("<null>");
179 return hosts;
180 }
181 for (const auto* aip = ai; aip != nullptr; aip = aip->ai_next) {
182 char host[NI_MAXHOST];
183 int rv = getnameinfo(aip->ai_addr, aip->ai_addrlen, host, sizeof(host), nullptr, 0,
184 NI_NUMERICHOST);
185 if (rv != 0) {
186 hosts.clear();
187 hosts.push_back(gai_strerror(rv));
188 return hosts;
189 } else {
190 hosts.push_back(host);
191 }
192 }
193 if (hosts.empty()) hosts.push_back("<invalid>");
194 return hosts;
195 }
196
197 static std::vector<std::string> ToStrings(const ScopedAddrinfo& ai) {
198 return ToStrings(ai.get());
199 }
200
Bernie Innocenti443489e2018-08-10 14:27:23 +0900201 size_t GetNumQueries(const test::DNSResponder& dns, const char* name) const {
202 auto queries = dns.queries();
203 size_t found = 0;
204 for (const auto& p : queries) {
205 if (p.first == name) {
206 ++found;
207 }
208 }
209 return found;
210 }
211
212 size_t GetNumQueriesForType(const test::DNSResponder& dns, ns_type type,
Bernie Innocenti0298c682018-10-02 23:18:11 +0900213 const char* name) const {
Bernie Innocenti443489e2018-08-10 14:27:23 +0900214 auto queries = dns.queries();
215 size_t found = 0;
216 for (const auto& p : queries) {
217 if (p.second == type && p.first == name) {
218 ++found;
219 }
220 }
221 return found;
222 }
223
nuccachenf52f7a52018-07-17 18:07:23 +0800224 bool WaitForPrefix64Detected(int netId, int timeoutMs) {
225 constexpr int intervalMs = 2;
226 const int limit = timeoutMs / intervalMs;
227 for (int count = 0; count <= limit; ++count) {
228 std::string prefix;
Bernie Innocenti3e411a32019-01-17 21:28:24 +0900229 auto rv = mDnsClient.netdService()->getPrefix64(netId, &prefix);
nuccachenf52f7a52018-07-17 18:07:23 +0800230 if (rv.isOk()) {
231 return true;
232 }
233 usleep(intervalMs * 1000);
234 }
235 return false;
236 }
237
Bernie Innocenti443489e2018-08-10 14:27:23 +0900238 void RunGetAddrInfoStressTest_Binder(unsigned num_hosts, unsigned num_threads,
239 unsigned num_queries) {
240 std::vector<std::string> domains = { "example.com" };
241 std::vector<std::unique_ptr<test::DNSResponder>> dns;
242 std::vector<std::string> servers;
Bernie Innocenti3e411a32019-01-17 21:28:24 +0900243 std::vector<DnsResponderClient::DnsResponderClient::Mapping> mappings;
244 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupMappings(num_hosts, domains, &mappings));
245 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupDNSServers(MAXNS, mappings, &dns, &servers));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900246
Xiao Ma7c75f452018-12-11 17:56:32 +0900247 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains, kDefaultParams));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900248
249 auto t0 = std::chrono::steady_clock::now();
250 std::vector<std::thread> threads(num_threads);
251 for (std::thread& thread : threads) {
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900252 thread = std::thread([&mappings, num_queries]() {
Bernie Innocenti443489e2018-08-10 14:27:23 +0900253 for (unsigned i = 0 ; i < num_queries ; ++i) {
254 uint32_t ofs = arc4random_uniform(mappings.size());
255 auto& mapping = mappings[ofs];
256 addrinfo* result = nullptr;
257 int rv = getaddrinfo(mapping.host.c_str(), nullptr, nullptr, &result);
258 EXPECT_EQ(0, rv) << "error [" << rv << "] " << gai_strerror(rv);
259 if (rv == 0) {
260 std::string result_str = ToString(result);
261 EXPECT_TRUE(result_str == mapping.ip4 || result_str == mapping.ip6)
262 << "result='" << result_str << "', ip4='" << mapping.ip4
263 << "', ip6='" << mapping.ip6;
264 }
265 if (result) {
266 freeaddrinfo(result);
267 result = nullptr;
268 }
269 }
270 });
271 }
272
273 for (std::thread& thread : threads) {
274 thread.join();
275 }
276 auto t1 = std::chrono::steady_clock::now();
277 ALOGI("%u hosts, %u threads, %u queries, %Es", num_hosts, num_threads, num_queries,
278 std::chrono::duration<double>(t1 - t0).count());
Ken Chen2a429352018-12-22 21:46:55 +0800279
280 std::vector<std::string> res_servers;
281 std::vector<std::string> res_domains;
282 std::vector<std::string> res_tls_servers;
Bernie Innocenti34de3ba2019-02-19 18:08:36 +0900283 res_params res_params;
Ken Chen2a429352018-12-22 21:46:55 +0800284 std::vector<ResolverStats> res_stats;
285 int wait_for_pending_req_timeout_count;
286 ASSERT_TRUE(GetResolverInfo(&res_servers, &res_domains, &res_tls_servers, &res_params,
287 &res_stats, &wait_for_pending_req_timeout_count));
288 EXPECT_EQ(0, wait_for_pending_req_timeout_count);
289
Bernie Innocenti3e411a32019-01-17 21:28:24 +0900290 ASSERT_NO_FATAL_FAILURE(mDnsClient.ShutdownDNSServers(&dns));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900291 }
292
Xiao Ma7c75f452018-12-11 17:56:32 +0900293 void StartDns(test::DNSResponder& dns, const std::vector<DnsRecord>& records) {
294 for (const auto& r : records) {
295 dns.addMapping(r.host_name, r.type, r.addr);
296 }
297
298 ASSERT_TRUE(dns.startServer());
299 dns.clearQueries();
300 }
Bernie Innocenti3e411a32019-01-17 21:28:24 +0900301
302 DnsResponderClient mDnsClient;
Xiao Ma7c75f452018-12-11 17:56:32 +0900303
304 static constexpr char kLocalHost[] = "localhost";
305 static constexpr char kLocalHostAddr[] = "127.0.0.1";
306 static constexpr char kIp6LocalHost[] = "ip6-localhost";
307 static constexpr char kIp6LocalHostAddr[] = "::1";
308 static constexpr char kHelloExampleCom[] = "hello.example.com.";
Bernie Innocenti443489e2018-08-10 14:27:23 +0900309};
310
311TEST_F(ResolverTest, GetHostByName) {
Xiao Ma7c75f452018-12-11 17:56:32 +0900312 constexpr char nonexistent_host_name[] = "nonexistent.example.com.";
313
314 test::DNSResponder dns;
315 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.3"}});
316 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Bernie Innocenti443489e2018-08-10 14:27:23 +0900317
318 const hostent* result;
Bernie Innocenti443489e2018-08-10 14:27:23 +0900319 result = gethostbyname("nonexistent");
320 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, nonexistent_host_name));
321 ASSERT_TRUE(result == nullptr);
322 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
323
324 dns.clearQueries();
325 result = gethostbyname("hello");
Xiao Ma7c75f452018-12-11 17:56:32 +0900326 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900327 ASSERT_FALSE(result == nullptr);
328 ASSERT_EQ(4, result->h_length);
329 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
330 EXPECT_EQ("1.2.3.3", ToString(result));
331 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Bernie Innocenti443489e2018-08-10 14:27:23 +0900332}
333
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900334TEST_F(ResolverTest, GetHostByName_localhost) {
Bernie Innocenti6118bf82018-09-14 15:21:19 +0900335 constexpr char name_camelcase[] = "LocalHost";
Bernie Innocenti0298c682018-10-02 23:18:11 +0900336 constexpr char name_ip6_dot[] = "ip6-localhost.";
337 constexpr char name_ip6_fqdn[] = "ip6-localhost.example.com.";
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900338
Bernie Innocenti974233e2018-09-04 20:35:34 +0900339 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma7c75f452018-12-11 17:56:32 +0900340 test::DNSResponder dns;
341 StartDns(dns, {});
342 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Bernie Innocenti6118bf82018-09-14 15:21:19 +0900343
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900344 // Expect no DNS queries; localhost is resolved via /etc/hosts
Xiao Ma7c75f452018-12-11 17:56:32 +0900345 const hostent* result = gethostbyname(kLocalHost);
Bernie Innocenti0298c682018-10-02 23:18:11 +0900346 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900347 ASSERT_FALSE(result == nullptr);
348 ASSERT_EQ(4, result->h_length);
349 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma7c75f452018-12-11 17:56:32 +0900350 EXPECT_EQ(kLocalHostAddr, ToString(result));
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900351 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
352
Bernie Innocenti6118bf82018-09-14 15:21:19 +0900353 // Ensure the hosts file resolver ignores case of hostnames
354 result = gethostbyname(name_camelcase);
Bernie Innocenti0298c682018-10-02 23:18:11 +0900355 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
Bernie Innocenti6118bf82018-09-14 15:21:19 +0900356 ASSERT_FALSE(result == nullptr);
357 ASSERT_EQ(4, result->h_length);
358 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma7c75f452018-12-11 17:56:32 +0900359 EXPECT_EQ(kLocalHostAddr, ToString(result));
Bernie Innocenti6118bf82018-09-14 15:21:19 +0900360 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
361
362 // The hosts file also contains ip6-localhost, but gethostbyname() won't
Bernie Innocenti0298c682018-10-02 23:18:11 +0900363 // return it unless the RES_USE_INET6 option is set. This would be easy to
364 // change, but there's no point in changing the legacy behavior; new code
365 // should be calling getaddrinfo() anyway.
366 // So we check the legacy behavior, which results in amusing A-record
367 // lookups for ip6-localhost, with and without search domains appended.
368 dns.clearQueries();
Xiao Ma7c75f452018-12-11 17:56:32 +0900369 result = gethostbyname(kIp6LocalHost);
Sehee Park8659b8d2018-11-16 10:53:16 +0900370 EXPECT_EQ(2U, dns.queries().size()) << dns.dumpQueries();
371 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, name_ip6_dot)) << dns.dumpQueries();
372 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, name_ip6_fqdn)) << dns.dumpQueries();
Bernie Innocenti6118bf82018-09-14 15:21:19 +0900373 ASSERT_TRUE(result == nullptr);
374
Bernie Innocenti0298c682018-10-02 23:18:11 +0900375 // Finally, use gethostbyname2() to resolve ip6-localhost to ::1 from
376 // the hosts file.
377 dns.clearQueries();
Xiao Ma7c75f452018-12-11 17:56:32 +0900378 result = gethostbyname2(kIp6LocalHost, AF_INET6);
Bernie Innocenti0298c682018-10-02 23:18:11 +0900379 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
Bernie Innocenti6118bf82018-09-14 15:21:19 +0900380 ASSERT_FALSE(result == nullptr);
381 ASSERT_EQ(16, result->h_length);
382 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma7c75f452018-12-11 17:56:32 +0900383 EXPECT_EQ(kIp6LocalHostAddr, ToString(result));
Bernie Innocenti6118bf82018-09-14 15:21:19 +0900384 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900385}
386
Bernie Innocentic1545232018-10-04 17:12:24 +0900387TEST_F(ResolverTest, GetHostByName_numeric) {
388 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma7c75f452018-12-11 17:56:32 +0900389 test::DNSResponder dns;
390 StartDns(dns, {});
391 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Bernie Innocentic1545232018-10-04 17:12:24 +0900392
393 // Numeric v4 address: expect no DNS queries
394 constexpr char numeric_v4[] = "192.168.0.1";
Bernie Innocentic1545232018-10-04 17:12:24 +0900395 const hostent* result = gethostbyname(numeric_v4);
Sehee Park8659b8d2018-11-16 10:53:16 +0900396 EXPECT_EQ(0U, dns.queries().size());
Bernie Innocentic1545232018-10-04 17:12:24 +0900397 ASSERT_FALSE(result == nullptr);
398 ASSERT_EQ(4, result->h_length); // v4
399 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
400 EXPECT_EQ(numeric_v4, ToString(result));
401 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
402
403 // gethostbyname() recognizes a v6 address, and fails with no DNS queries
404 constexpr char numeric_v6[] = "2001:db8::42";
405 dns.clearQueries();
406 result = gethostbyname(numeric_v6);
Sehee Park8659b8d2018-11-16 10:53:16 +0900407 EXPECT_EQ(0U, dns.queries().size());
Bernie Innocentic1545232018-10-04 17:12:24 +0900408 EXPECT_TRUE(result == nullptr);
409
410 // Numeric v6 address with gethostbyname2(): succeeds with no DNS queries
411 dns.clearQueries();
412 result = gethostbyname2(numeric_v6, AF_INET6);
Sehee Park8659b8d2018-11-16 10:53:16 +0900413 EXPECT_EQ(0U, dns.queries().size());
Bernie Innocentic1545232018-10-04 17:12:24 +0900414 ASSERT_FALSE(result == nullptr);
415 ASSERT_EQ(16, result->h_length); // v6
416 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
417 EXPECT_EQ(numeric_v6, ToString(result));
418 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
419
420 // Numeric v6 address with scope work with getaddrinfo(),
421 // but gethostbyname2() does not understand them; it issues two dns
422 // queries, then fails. This hardly ever happens, there's no point
423 // in fixing this. This test simply verifies the current (bogus)
424 // behavior to avoid further regressions (like crashes, or leaks).
425 constexpr char numeric_v6_scope[] = "fe80::1%lo";
426 dns.clearQueries();
427 result = gethostbyname2(numeric_v6_scope, AF_INET6);
Sehee Park8659b8d2018-11-16 10:53:16 +0900428 EXPECT_EQ(2U, dns.queries().size()); // OUCH!
Bernie Innocentic1545232018-10-04 17:12:24 +0900429 ASSERT_TRUE(result == nullptr);
Bernie Innocentic1545232018-10-04 17:12:24 +0900430}
431
Bernie Innocenti443489e2018-08-10 14:27:23 +0900432TEST_F(ResolverTest, BinderSerialization) {
433 using android::net::INetd;
434 std::vector<int> params_offsets = {
waynemad193e4d2019-02-18 17:47:59 +0800435 INetd::RESOLVER_PARAMS_SAMPLE_VALIDITY, INetd::RESOLVER_PARAMS_SUCCESS_THRESHOLD,
436 INetd::RESOLVER_PARAMS_MIN_SAMPLES, INetd::RESOLVER_PARAMS_MAX_SAMPLES,
437 INetd::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC, INetd::RESOLVER_PARAMS_RETRY_COUNT,
Bernie Innocenti443489e2018-08-10 14:27:23 +0900438 };
Bernie Innocenti45238a12018-12-04 14:57:48 +0900439 const int size = static_cast<int>(params_offsets.size());
Bernie Innocenti443489e2018-08-10 14:27:23 +0900440 EXPECT_EQ(size, INetd::RESOLVER_PARAMS_COUNT);
441 std::sort(params_offsets.begin(), params_offsets.end());
Bernie Innocenti45238a12018-12-04 14:57:48 +0900442 for (int i = 0; i < size; ++i) {
Bernie Innocenti443489e2018-08-10 14:27:23 +0900443 EXPECT_EQ(params_offsets[i], i);
444 }
445}
446
447TEST_F(ResolverTest, GetHostByName_Binder) {
448 using android::net::INetd;
449
450 std::vector<std::string> domains = { "example.com" };
451 std::vector<std::unique_ptr<test::DNSResponder>> dns;
452 std::vector<std::string> servers;
Bernie Innocenti3e411a32019-01-17 21:28:24 +0900453 std::vector<DnsResponderClient::Mapping> mappings;
454 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupMappings(1, domains, &mappings));
455 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupDNSServers(4, mappings, &dns, &servers));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900456 ASSERT_EQ(1U, mappings.size());
Bernie Innocenti3e411a32019-01-17 21:28:24 +0900457 const DnsResponderClient::Mapping& mapping = mappings[0];
Bernie Innocenti443489e2018-08-10 14:27:23 +0900458
Xiao Ma7c75f452018-12-11 17:56:32 +0900459 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains, kDefaultParams));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900460
461 const hostent* result = gethostbyname(mapping.host.c_str());
Bernie Innocenti45238a12018-12-04 14:57:48 +0900462 const size_t total_queries =
463 std::accumulate(dns.begin(), dns.end(), 0, [this, &mapping](size_t total, auto& d) {
Bernie Innocenti443489e2018-08-10 14:27:23 +0900464 return total + GetNumQueriesForType(*d, ns_type::ns_t_a, mapping.entry.c_str());
465 });
466
467 EXPECT_LE(1U, total_queries);
468 ASSERT_FALSE(result == nullptr);
469 ASSERT_EQ(4, result->h_length);
470 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
471 EXPECT_EQ(mapping.ip4, ToString(result));
472 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
473
474 std::vector<std::string> res_servers;
475 std::vector<std::string> res_domains;
Mike Yuda77e8e2018-11-26 13:26:21 +0900476 std::vector<std::string> res_tls_servers;
Bernie Innocenti34de3ba2019-02-19 18:08:36 +0900477 res_params res_params;
Bernie Innocenti443489e2018-08-10 14:27:23 +0900478 std::vector<ResolverStats> res_stats;
Ken Chen2a429352018-12-22 21:46:55 +0800479 int wait_for_pending_req_timeout_count;
480 ASSERT_TRUE(GetResolverInfo(&res_servers, &res_domains, &res_tls_servers, &res_params,
481 &res_stats, &wait_for_pending_req_timeout_count));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900482 EXPECT_EQ(servers.size(), res_servers.size());
483 EXPECT_EQ(domains.size(), res_domains.size());
Mike Yuda77e8e2018-11-26 13:26:21 +0900484 EXPECT_EQ(0U, res_tls_servers.size());
Xiao Ma7c75f452018-12-11 17:56:32 +0900485 ASSERT_EQ(static_cast<size_t>(INetd::RESOLVER_PARAMS_COUNT), kDefaultParams.size());
486 EXPECT_EQ(kDefaultParams[INetd::RESOLVER_PARAMS_SAMPLE_VALIDITY], res_params.sample_validity);
487 EXPECT_EQ(kDefaultParams[INetd::RESOLVER_PARAMS_SUCCESS_THRESHOLD],
Bernie Innocenti3e411a32019-01-17 21:28:24 +0900488 res_params.success_threshold);
Xiao Ma7c75f452018-12-11 17:56:32 +0900489 EXPECT_EQ(kDefaultParams[INetd::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
490 EXPECT_EQ(kDefaultParams[INetd::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
491 EXPECT_EQ(kDefaultParams[INetd::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
Bernie Innocenti443489e2018-08-10 14:27:23 +0900492 res_params.base_timeout_msec);
493 EXPECT_EQ(servers.size(), res_stats.size());
494
495 EXPECT_TRUE(UnorderedCompareArray(res_servers, servers));
496 EXPECT_TRUE(UnorderedCompareArray(res_domains, domains));
497
Bernie Innocenti3e411a32019-01-17 21:28:24 +0900498 ASSERT_NO_FATAL_FAILURE(mDnsClient.ShutdownDNSServers(&dns));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900499}
500
501TEST_F(ResolverTest, GetAddrInfo) {
Xiao Ma7c75f452018-12-11 17:56:32 +0900502 constexpr char listen_addr[] = "127.0.0.4";
503 constexpr char listen_addr2[] = "127.0.0.5";
504 constexpr char host_name[] = "howdy.example.com.";
Bernie Innocenti443489e2018-08-10 14:27:23 +0900505
Xiao Ma7c75f452018-12-11 17:56:32 +0900506 const std::vector<DnsRecord> records = {
507 {host_name, ns_type::ns_t_a, "1.2.3.4"},
508 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
509 };
510 test::DNSResponder dns(listen_addr);
511 test::DNSResponder dns2(listen_addr2);
512 StartDns(dns, records);
513 StartDns(dns2, records);
Bernie Innocenti443489e2018-08-10 14:27:23 +0900514
Xiao Ma7c75f452018-12-11 17:56:32 +0900515 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr}));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900516 dns.clearQueries();
517 dns2.clearQueries();
518
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900519 ScopedAddrinfo result = safe_getaddrinfo("howdy", nullptr, nullptr);
520 EXPECT_TRUE(result != nullptr);
Bernie Innocenti443489e2018-08-10 14:27:23 +0900521 size_t found = GetNumQueries(dns, host_name);
522 EXPECT_LE(1U, found);
523 // Could be A or AAAA
524 std::string result_str = ToString(result);
525 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
526 << ", result_str='" << result_str << "'";
Bernie Innocenti443489e2018-08-10 14:27:23 +0900527
528 // Verify that the name is cached.
529 size_t old_found = found;
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900530 result = safe_getaddrinfo("howdy", nullptr, nullptr);
531 EXPECT_TRUE(result != nullptr);
Bernie Innocenti443489e2018-08-10 14:27:23 +0900532 found = GetNumQueries(dns, host_name);
533 EXPECT_LE(1U, found);
534 EXPECT_EQ(old_found, found);
535 result_str = ToString(result);
536 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
537 << result_str;
Bernie Innocenti443489e2018-08-10 14:27:23 +0900538
539 // Change the DNS resolver, ensure that queries are still cached.
Xiao Ma7c75f452018-12-11 17:56:32 +0900540 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr2}));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900541 dns.clearQueries();
542 dns2.clearQueries();
543
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900544 result = safe_getaddrinfo("howdy", nullptr, nullptr);
545 EXPECT_TRUE(result != nullptr);
Bernie Innocenti443489e2018-08-10 14:27:23 +0900546 found = GetNumQueries(dns, host_name);
547 size_t found2 = GetNumQueries(dns2, host_name);
548 EXPECT_EQ(0U, found);
549 EXPECT_LE(0U, found2);
550
551 // Could be A or AAAA
552 result_str = ToString(result);
553 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
554 << ", result_str='" << result_str << "'";
Bernie Innocenti443489e2018-08-10 14:27:23 +0900555}
556
557TEST_F(ResolverTest, GetAddrInfoV4) {
Xiao Ma7c75f452018-12-11 17:56:32 +0900558 test::DNSResponder dns;
559 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.5"}});
560 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Bernie Innocenti443489e2018-08-10 14:27:23 +0900561
Xiao Ma7c75f452018-12-11 17:56:32 +0900562 const addrinfo hints = {.ai_family = AF_INET};
563 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900564 EXPECT_TRUE(result != nullptr);
Xiao Ma7c75f452018-12-11 17:56:32 +0900565 EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900566 EXPECT_EQ("1.2.3.5", ToString(result));
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900567}
568
569TEST_F(ResolverTest, GetAddrInfo_localhost) {
Bernie Innocenti974233e2018-09-04 20:35:34 +0900570 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma7c75f452018-12-11 17:56:32 +0900571 test::DNSResponder dns;
572 StartDns(dns, {});
573 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900574
Xiao Ma7c75f452018-12-11 17:56:32 +0900575 ScopedAddrinfo result = safe_getaddrinfo(kLocalHost, nullptr, nullptr);
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900576 EXPECT_TRUE(result != nullptr);
577 // Expect no DNS queries; localhost is resolved via /etc/hosts
Bernie Innocenti0298c682018-10-02 23:18:11 +0900578 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
Xiao Ma7c75f452018-12-11 17:56:32 +0900579 EXPECT_EQ(kLocalHostAddr, ToString(result));
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900580
Xiao Ma7c75f452018-12-11 17:56:32 +0900581 result = safe_getaddrinfo(kIp6LocalHost, nullptr, nullptr);
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900582 EXPECT_TRUE(result != nullptr);
Bernie Innocenti0298c682018-10-02 23:18:11 +0900583 // Expect no DNS queries; ip6-localhost is resolved via /etc/hosts
584 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
Xiao Ma7c75f452018-12-11 17:56:32 +0900585 EXPECT_EQ(kIp6LocalHostAddr, ToString(result));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900586}
587
Ken Chen2a429352018-12-22 21:46:55 +0800588// Verify if the resolver correctly handle multiple queries simultaneously
589// step 1: set dns server#1 into deferred responding mode.
590// step 2: thread#1 query "hello.example.com." --> resolver send query to server#1.
591// step 3: thread#2 query "hello.example.com." --> resolver hold the request and wait for
592// response of previous pending query sent by thread#1.
593// step 4: thread#3 query "konbanha.example.com." --> resolver send query to server#3. Server
594// respond to resolver immediately.
595// step 5: check if server#1 get 1 query by thread#1, server#2 get 0 query, server#3 get 1 query.
596// step 6: resume dns server#1 to respond dns query in step#2.
597// step 7: thread#1 and #2 should get returned from DNS query after step#6. Also, check the
598// number of queries in server#2 is 0 to ensure thread#2 does not wake up unexpectedly
599// before signaled by thread#1.
600TEST_F(ResolverTest, GetAddrInfoV4_deferred_resp) {
601 const char* listen_addr1 = "127.0.0.9";
602 const char* listen_addr2 = "127.0.0.10";
603 const char* listen_addr3 = "127.0.0.11";
604 const char* listen_srv = "53";
605 const char* host_name_deferred = "hello.example.com.";
606 const char* host_name_normal = "konbanha.example.com.";
607 test::DNSResponder dns1(listen_addr1, listen_srv, 250, ns_rcode::ns_r_servfail);
608 test::DNSResponder dns2(listen_addr2, listen_srv, 250, ns_rcode::ns_r_servfail);
609 test::DNSResponder dns3(listen_addr3, listen_srv, 250, ns_rcode::ns_r_servfail);
610 dns1.addMapping(host_name_deferred, ns_type::ns_t_a, "1.2.3.4");
611 dns2.addMapping(host_name_deferred, ns_type::ns_t_a, "1.2.3.4");
612 dns3.addMapping(host_name_normal, ns_type::ns_t_a, "1.2.3.5");
613 ASSERT_TRUE(dns1.startServer());
614 ASSERT_TRUE(dns2.startServer());
615 ASSERT_TRUE(dns3.startServer());
616 const std::vector<std::string> servers_for_t1 = {listen_addr1};
617 const std::vector<std::string> servers_for_t2 = {listen_addr2};
618 const std::vector<std::string> servers_for_t3 = {listen_addr3};
619 addrinfo hints = {.ai_family = AF_INET};
620 const std::vector<int> params = {300, 25, 8, 8, 5000};
621 bool t3_task_done = false;
622
623 dns1.setDeferredResp(true);
624 std::thread t1([&, this]() {
625 ASSERT_TRUE(
626 mDnsClient.SetResolversForNetwork(servers_for_t1, kDefaultSearchDomains, params));
627 ScopedAddrinfo result = safe_getaddrinfo(host_name_deferred, nullptr, &hints);
628 // t3's dns query should got returned first
629 EXPECT_TRUE(t3_task_done);
630 EXPECT_EQ(1U, GetNumQueries(dns1, host_name_deferred));
631 EXPECT_TRUE(result != nullptr);
632 EXPECT_EQ("1.2.3.4", ToString(result));
633 });
634
635 // ensuring t1 and t2 handler functions are processed in order
636 usleep(100 * 1000);
637 std::thread t2([&, this]() {
638 ASSERT_TRUE(
639 mDnsClient.SetResolversForNetwork(servers_for_t2, kDefaultSearchDomains, params));
640 ScopedAddrinfo result = safe_getaddrinfo(host_name_deferred, nullptr, &hints);
641 EXPECT_TRUE(t3_task_done);
642 EXPECT_EQ(0U, GetNumQueries(dns2, host_name_deferred));
643 EXPECT_TRUE(result != nullptr);
644 EXPECT_EQ("1.2.3.4", ToString(result));
645
646 std::vector<std::string> res_servers;
647 std::vector<std::string> res_domains;
648 std::vector<std::string> res_tls_servers;
Bernie Innocenti34de3ba2019-02-19 18:08:36 +0900649 res_params res_params;
Ken Chen2a429352018-12-22 21:46:55 +0800650 std::vector<ResolverStats> res_stats;
651 int wait_for_pending_req_timeout_count;
652 ASSERT_TRUE(GetResolverInfo(&res_servers, &res_domains, &res_tls_servers, &res_params,
653 &res_stats, &wait_for_pending_req_timeout_count));
654 EXPECT_EQ(0, wait_for_pending_req_timeout_count);
655 });
656
657 // ensuring t2 and t3 handler functions are processed in order
658 usleep(100 * 1000);
659 std::thread t3([&, this]() {
660 ASSERT_TRUE(
661 mDnsClient.SetResolversForNetwork(servers_for_t3, kDefaultSearchDomains, params));
662 ScopedAddrinfo result = safe_getaddrinfo(host_name_normal, nullptr, &hints);
663 EXPECT_EQ(1U, GetNumQueries(dns1, host_name_deferred));
664 EXPECT_EQ(0U, GetNumQueries(dns2, host_name_deferred));
665 EXPECT_EQ(1U, GetNumQueries(dns3, host_name_normal));
666 EXPECT_TRUE(result != nullptr);
667 EXPECT_EQ("1.2.3.5", ToString(result));
668
669 t3_task_done = true;
670 dns1.setDeferredResp(false);
671 });
672 t3.join();
673 t1.join();
674 t2.join();
675}
676
Bernie Innocenti443489e2018-08-10 14:27:23 +0900677TEST_F(ResolverTest, MultidomainResolution) {
Xiao Ma7c75f452018-12-11 17:56:32 +0900678 constexpr char host_name[] = "nihao.example2.com.";
Bernie Innocenti443489e2018-08-10 14:27:23 +0900679 std::vector<std::string> searchDomains = { "example1.com", "example2.com", "example3.com" };
Bernie Innocenti443489e2018-08-10 14:27:23 +0900680
Xiao Ma7c75f452018-12-11 17:56:32 +0900681 test::DNSResponder dns("127.0.0.6");
682 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.3"}});
683 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({"127.0.0.6"}, searchDomains));
684
Bernie Innocenti443489e2018-08-10 14:27:23 +0900685 const hostent* result = gethostbyname("nihao");
Xiao Ma7c75f452018-12-11 17:56:32 +0900686
Bernie Innocenti443489e2018-08-10 14:27:23 +0900687 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
688 ASSERT_FALSE(result == nullptr);
689 ASSERT_EQ(4, result->h_length);
690 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
691 EXPECT_EQ("1.2.3.3", ToString(result));
692 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
693 dns.stopServer();
694}
695
Bernie Innocenti974233e2018-09-04 20:35:34 +0900696TEST_F(ResolverTest, GetAddrInfoV6_numeric) {
Bernie Innocenti974233e2018-09-04 20:35:34 +0900697 constexpr char host_name[] = "ohayou.example.com.";
698 constexpr char numeric_addr[] = "fe80::1%lo";
699
Xiao Ma7c75f452018-12-11 17:56:32 +0900700 test::DNSResponder dns;
Bernie Innocenti974233e2018-09-04 20:35:34 +0900701 dns.setResponseProbability(0.0);
Xiao Ma7c75f452018-12-11 17:56:32 +0900702 StartDns(dns, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
703 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Bernie Innocenti974233e2018-09-04 20:35:34 +0900704
705 addrinfo hints = {.ai_family = AF_INET6};
706 ScopedAddrinfo result = safe_getaddrinfo(numeric_addr, nullptr, &hints);
707 EXPECT_TRUE(result != nullptr);
708 EXPECT_EQ(numeric_addr, ToString(result));
709 EXPECT_TRUE(dns.queries().empty()); // Ensure no DNS queries were sent out
710
711 // Now try a non-numeric hostname query with the AI_NUMERICHOST flag set.
712 // We should fail without sending out a DNS query.
713 hints.ai_flags |= AI_NUMERICHOST;
714 result = safe_getaddrinfo(host_name, nullptr, &hints);
715 EXPECT_TRUE(result == nullptr);
716 EXPECT_TRUE(dns.queries().empty()); // Ensure no DNS queries were sent out
717}
718
Bernie Innocenti443489e2018-08-10 14:27:23 +0900719TEST_F(ResolverTest, GetAddrInfoV6_failing) {
Xiao Ma7c75f452018-12-11 17:56:32 +0900720 constexpr char listen_addr0[] = "127.0.0.7";
721 constexpr char listen_addr1[] = "127.0.0.8";
Bernie Innocenti443489e2018-08-10 14:27:23 +0900722 const char* host_name = "ohayou.example.com.";
Xiao Ma7c75f452018-12-11 17:56:32 +0900723
724 test::DNSResponder dns0(listen_addr0);
725 test::DNSResponder dns1(listen_addr1);
Bernie Innocenti443489e2018-08-10 14:27:23 +0900726 dns0.setResponseProbability(0.0);
Xiao Ma7c75f452018-12-11 17:56:32 +0900727 StartDns(dns0, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
728 StartDns(dns1, {{host_name, ns_type::ns_t_aaaa, "2001:db8::6"}});
729
Bernie Innocenti443489e2018-08-10 14:27:23 +0900730 std::vector<std::string> servers = { listen_addr0, listen_addr1 };
731 // <sample validity in s> <success threshold in percent> <min samples> <max samples>
732 int sample_count = 8;
733 const std::vector<int> params = { 300, 25, sample_count, sample_count };
Xiao Ma7c75f452018-12-11 17:56:32 +0900734 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, kDefaultSearchDomains, params));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900735
736 // Repeatedly perform resolutions for non-existing domains until MAXNSSAMPLES resolutions have
737 // reached the dns0, which is set to fail. No more requests should then arrive at that server
738 // for the next sample_lifetime seconds.
739 // TODO: This approach is implementation-dependent, change once metrics reporting is available.
Xiao Ma7c75f452018-12-11 17:56:32 +0900740 const addrinfo hints = {.ai_family = AF_INET6};
Bernie Innocenti45238a12018-12-04 14:57:48 +0900741 for (int i = 0; i < sample_count; ++i) {
Bernie Innocenti443489e2018-08-10 14:27:23 +0900742 std::string domain = StringPrintf("nonexistent%d", i);
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900743 ScopedAddrinfo result = safe_getaddrinfo(domain.c_str(), nullptr, &hints);
Bernie Innocenti443489e2018-08-10 14:27:23 +0900744 }
745 // Due to 100% errors for all possible samples, the server should be ignored from now on and
746 // only the second one used for all following queries, until NSSAMPLE_VALIDITY is reached.
747 dns0.clearQueries();
748 dns1.clearQueries();
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900749 ScopedAddrinfo result = safe_getaddrinfo("ohayou", nullptr, &hints);
750 EXPECT_TRUE(result != nullptr);
Bernie Innocenti443489e2018-08-10 14:27:23 +0900751 EXPECT_EQ(0U, GetNumQueries(dns0, host_name));
752 EXPECT_EQ(1U, GetNumQueries(dns1, host_name));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900753}
754
755TEST_F(ResolverTest, GetAddrInfoV6_nonresponsive) {
Xiao Ma7c75f452018-12-11 17:56:32 +0900756 constexpr char listen_addr0[] = "127.0.0.7";
757 constexpr char listen_addr1[] = "127.0.0.8";
758 constexpr char listen_srv[] = "53";
759 constexpr char host_name1[] = "ohayou.example.com.";
760 constexpr char host_name2[] = "ciao.example.com.";
761 const std::vector<DnsRecord> records0 = {
762 {host_name1, ns_type::ns_t_aaaa, "2001:db8::5"},
763 {host_name2, ns_type::ns_t_aaaa, "2001:db8::5"},
764 };
765 const std::vector<DnsRecord> records1 = {
766 {host_name1, ns_type::ns_t_aaaa, "2001:db8::6"},
767 {host_name2, ns_type::ns_t_aaaa, "2001:db8::6"},
768 };
Bernie Innocenti443489e2018-08-10 14:27:23 +0900769
770 // dns0 does not respond with 100% probability, while
771 // dns1 responds normally, at least initially.
772 test::DNSResponder dns0(listen_addr0, listen_srv, 250, static_cast<ns_rcode>(-1));
773 test::DNSResponder dns1(listen_addr1, listen_srv, 250, static_cast<ns_rcode>(-1));
774 dns0.setResponseProbability(0.0);
Xiao Ma7c75f452018-12-11 17:56:32 +0900775 StartDns(dns0, records0);
776 StartDns(dns1, records1);
777 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr0, listen_addr1}));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900778
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900779 const addrinfo hints = {.ai_family = AF_INET6};
Bernie Innocenti443489e2018-08-10 14:27:23 +0900780
781 // dns0 will ignore the request, and we'll fallback to dns1 after the first
782 // retry.
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900783 ScopedAddrinfo result = safe_getaddrinfo(host_name1, nullptr, &hints);
784 EXPECT_TRUE(result != nullptr);
Bernie Innocenti443489e2018-08-10 14:27:23 +0900785 EXPECT_EQ(1U, GetNumQueries(dns0, host_name1));
786 EXPECT_EQ(1U, GetNumQueries(dns1, host_name1));
787
788 // Now make dns1 also ignore 100% requests... The resolve should alternate
789 // retries between the nameservers and fail after 4 attempts.
790 dns1.setResponseProbability(0.0);
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900791 addrinfo* result2 = nullptr;
792 EXPECT_EQ(EAI_NODATA, getaddrinfo(host_name2, nullptr, &hints, &result2));
793 EXPECT_EQ(nullptr, result2);
Bernie Innocenti443489e2018-08-10 14:27:23 +0900794 EXPECT_EQ(4U, GetNumQueries(dns0, host_name2));
795 EXPECT_EQ(4U, GetNumQueries(dns1, host_name2));
796}
797
798TEST_F(ResolverTest, GetAddrInfoV6_concurrent) {
Xiao Ma7c75f452018-12-11 17:56:32 +0900799 constexpr char listen_addr0[] = "127.0.0.9";
800 constexpr char listen_addr1[] = "127.0.0.10";
801 constexpr char listen_addr2[] = "127.0.0.11";
802 constexpr char host_name[] = "konbanha.example.com.";
803
804 test::DNSResponder dns0(listen_addr0);
805 test::DNSResponder dns1(listen_addr1);
806 test::DNSResponder dns2(listen_addr2);
807 StartDns(dns0, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
808 StartDns(dns1, {{host_name, ns_type::ns_t_aaaa, "2001:db8::6"}});
809 StartDns(dns2, {{host_name, ns_type::ns_t_aaaa, "2001:db8::7"}});
810
Bernie Innocenti443489e2018-08-10 14:27:23 +0900811 const std::vector<std::string> servers = { listen_addr0, listen_addr1, listen_addr2 };
812 std::vector<std::thread> threads(10);
813 for (std::thread& thread : threads) {
814 thread = std::thread([this, &servers]() {
815 unsigned delay = arc4random_uniform(1*1000*1000); // <= 1s
816 usleep(delay);
817 std::vector<std::string> serverSubset;
818 for (const auto& server : servers) {
819 if (arc4random_uniform(2)) {
820 serverSubset.push_back(server);
821 }
822 }
823 if (serverSubset.empty()) serverSubset = servers;
Xiao Ma7c75f452018-12-11 17:56:32 +0900824 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(serverSubset));
825 const addrinfo hints = {.ai_family = AF_INET6};
Bernie Innocenti443489e2018-08-10 14:27:23 +0900826 addrinfo* result = nullptr;
827 int rv = getaddrinfo("konbanha", nullptr, &hints, &result);
828 EXPECT_EQ(0, rv) << "error [" << rv << "] " << gai_strerror(rv);
829 if (result) {
830 freeaddrinfo(result);
831 result = nullptr;
832 }
833 });
834 }
835 for (std::thread& thread : threads) {
836 thread.join();
837 }
Ken Chen2a429352018-12-22 21:46:55 +0800838
839 std::vector<std::string> res_servers;
840 std::vector<std::string> res_domains;
841 std::vector<std::string> res_tls_servers;
Bernie Innocenti34de3ba2019-02-19 18:08:36 +0900842 res_params res_params;
Ken Chen2a429352018-12-22 21:46:55 +0800843 std::vector<ResolverStats> res_stats;
844 int wait_for_pending_req_timeout_count;
845 ASSERT_TRUE(GetResolverInfo(&res_servers, &res_domains, &res_tls_servers, &res_params,
846 &res_stats, &wait_for_pending_req_timeout_count));
847 EXPECT_EQ(0, wait_for_pending_req_timeout_count);
Bernie Innocenti443489e2018-08-10 14:27:23 +0900848}
849
850TEST_F(ResolverTest, GetAddrInfoStressTest_Binder_100) {
851 const unsigned num_hosts = 100;
852 const unsigned num_threads = 100;
853 const unsigned num_queries = 100;
854 ASSERT_NO_FATAL_FAILURE(RunGetAddrInfoStressTest_Binder(num_hosts, num_threads, num_queries));
855}
856
857TEST_F(ResolverTest, GetAddrInfoStressTest_Binder_100000) {
858 const unsigned num_hosts = 100000;
859 const unsigned num_threads = 100;
860 const unsigned num_queries = 100;
861 ASSERT_NO_FATAL_FAILURE(RunGetAddrInfoStressTest_Binder(num_hosts, num_threads, num_queries));
862}
863
864TEST_F(ResolverTest, EmptySetup) {
865 using android::net::INetd;
866 std::vector<std::string> servers;
867 std::vector<std::string> domains;
Xiao Ma7c75f452018-12-11 17:56:32 +0900868 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900869 std::vector<std::string> res_servers;
870 std::vector<std::string> res_domains;
Mike Yuda77e8e2018-11-26 13:26:21 +0900871 std::vector<std::string> res_tls_servers;
Bernie Innocenti34de3ba2019-02-19 18:08:36 +0900872 res_params res_params;
Bernie Innocenti443489e2018-08-10 14:27:23 +0900873 std::vector<ResolverStats> res_stats;
Ken Chen2a429352018-12-22 21:46:55 +0800874 int wait_for_pending_req_timeout_count;
875 ASSERT_TRUE(GetResolverInfo(&res_servers, &res_domains, &res_tls_servers, &res_params,
876 &res_stats, &wait_for_pending_req_timeout_count));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900877 EXPECT_EQ(0U, res_servers.size());
878 EXPECT_EQ(0U, res_domains.size());
Mike Yuda77e8e2018-11-26 13:26:21 +0900879 EXPECT_EQ(0U, res_tls_servers.size());
Xiao Ma7c75f452018-12-11 17:56:32 +0900880 ASSERT_EQ(static_cast<size_t>(INetd::RESOLVER_PARAMS_COUNT), kDefaultParams.size());
881 EXPECT_EQ(kDefaultParams[INetd::RESOLVER_PARAMS_SAMPLE_VALIDITY], res_params.sample_validity);
882 EXPECT_EQ(kDefaultParams[INetd::RESOLVER_PARAMS_SUCCESS_THRESHOLD],
Bernie Innocenti3e411a32019-01-17 21:28:24 +0900883 res_params.success_threshold);
Xiao Ma7c75f452018-12-11 17:56:32 +0900884 EXPECT_EQ(kDefaultParams[INetd::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
885 EXPECT_EQ(kDefaultParams[INetd::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
886 EXPECT_EQ(kDefaultParams[INetd::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
Bernie Innocenti443489e2018-08-10 14:27:23 +0900887 res_params.base_timeout_msec);
waynemad193e4d2019-02-18 17:47:59 +0800888 EXPECT_EQ(kDefaultParams[INetd::RESOLVER_PARAMS_RETRY_COUNT], res_params.retry_count);
Bernie Innocenti443489e2018-08-10 14:27:23 +0900889}
890
891TEST_F(ResolverTest, SearchPathChange) {
Xiao Ma7c75f452018-12-11 17:56:32 +0900892 constexpr char listen_addr[] = "127.0.0.13";
893 constexpr char host_name1[] = "test13.domain1.org.";
894 constexpr char host_name2[] = "test13.domain2.org.";
Bernie Innocenti443489e2018-08-10 14:27:23 +0900895 std::vector<std::string> servers = { listen_addr };
896 std::vector<std::string> domains = { "domain1.org" };
Xiao Ma7c75f452018-12-11 17:56:32 +0900897
898 const std::vector<DnsRecord> records = {
899 {host_name1, ns_type::ns_t_aaaa, "2001:db8::13"},
900 {host_name2, ns_type::ns_t_aaaa, "2001:db8::1:13"},
901 };
902 test::DNSResponder dns(listen_addr);
903 StartDns(dns, records);
904 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900905
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900906 const addrinfo hints = {.ai_family = AF_INET6};
907 ScopedAddrinfo result = safe_getaddrinfo("test13", nullptr, &hints);
908 EXPECT_TRUE(result != nullptr);
Bernie Innocenti443489e2018-08-10 14:27:23 +0900909 EXPECT_EQ(1U, dns.queries().size());
910 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
911 EXPECT_EQ("2001:db8::13", ToString(result));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900912
913 // Test that changing the domain search path on its own works.
914 domains = { "domain2.org" };
Xiao Ma7c75f452018-12-11 17:56:32 +0900915 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900916 dns.clearQueries();
917
Bernie Innocenti9bf749f2018-08-30 08:37:22 +0900918 result = safe_getaddrinfo("test13", nullptr, &hints);
919 EXPECT_TRUE(result != nullptr);
Bernie Innocenti443489e2018-08-10 14:27:23 +0900920 EXPECT_EQ(1U, dns.queries().size());
921 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
922 EXPECT_EQ("2001:db8::1:13", ToString(result));
Bernie Innocenti443489e2018-08-10 14:27:23 +0900923}
924
Bernie Innocenti443489e2018-08-10 14:27:23 +0900925static std::string base64Encode(const std::vector<uint8_t>& input) {
926 size_t out_len;
927 EXPECT_EQ(1, EVP_EncodedLength(&out_len, input.size()));
928 // out_len includes the trailing NULL.
929 uint8_t output_bytes[out_len];
930 EXPECT_EQ(out_len - 1, EVP_EncodeBlock(output_bytes, input.data(), input.size()));
931 return std::string(reinterpret_cast<char*>(output_bytes));
932}
933
Mike Yuda77e8e2018-11-26 13:26:21 +0900934// If we move this function to dns_responder_client, it will complicate the dependency need of
935// dns_tls_frontend.h.
936static void setupTlsServers(const std::vector<std::string>& servers,
937 std::vector<std::unique_ptr<test::DnsTlsFrontend>>* tls,
938 std::vector<std::string>* fingerprints) {
Xiao Ma7c75f452018-12-11 17:56:32 +0900939 constexpr char listen_udp[] = "53";
940 constexpr char listen_tls[] = "853";
Mike Yuda77e8e2018-11-26 13:26:21 +0900941
942 for (const auto& server : servers) {
943 auto t = std::make_unique<test::DnsTlsFrontend>(server, listen_tls, server, listen_udp);
944 t = std::make_unique<test::DnsTlsFrontend>(server, listen_tls, server, listen_udp);
945 t->startServer();
946 fingerprints->push_back(base64Encode(t->fingerprint()));
947 tls->push_back(std::move(t));
948 }
949}
950
951static void shutdownTlsServers(std::vector<std::unique_ptr<test::DnsTlsFrontend>>* tls) {
952 for (const auto& t : *tls) {
953 t->stopServer();
954 }
955 tls->clear();
956}
957
958TEST_F(ResolverTest, MaxServerPrune_Binder) {
959 using android::net::INetd;
960
961 std::vector<std::string> domains;
962 std::vector<std::unique_ptr<test::DNSResponder>> dns;
963 std::vector<std::unique_ptr<test::DnsTlsFrontend>> tls;
964 std::vector<std::string> servers;
965 std::vector<std::string> fingerprints;
Bernie Innocenti3e411a32019-01-17 21:28:24 +0900966 std::vector<DnsResponderClient::Mapping> mappings;
Mike Yuda77e8e2018-11-26 13:26:21 +0900967
968 for (unsigned i = 0; i < MAXDNSRCH + 1; i++) {
969 domains.push_back(StringPrintf("example%u.com", i));
970 }
Bernie Innocenti3e411a32019-01-17 21:28:24 +0900971 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupMappings(1, domains, &mappings));
972 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupDNSServers(MAXNS + 1, mappings, &dns, &servers));
Mike Yuda77e8e2018-11-26 13:26:21 +0900973 ASSERT_NO_FATAL_FAILURE(setupTlsServers(servers, &tls, &fingerprints));
974
Xiao Ma7c75f452018-12-11 17:56:32 +0900975 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, domains, kDefaultParams, "", fingerprints));
Mike Yuda77e8e2018-11-26 13:26:21 +0900976
977 std::vector<std::string> res_servers;
978 std::vector<std::string> res_domains;
979 std::vector<std::string> res_tls_servers;
Bernie Innocenti34de3ba2019-02-19 18:08:36 +0900980 res_params res_params;
Mike Yuda77e8e2018-11-26 13:26:21 +0900981 std::vector<ResolverStats> res_stats;
Ken Chen2a429352018-12-22 21:46:55 +0800982 int wait_for_pending_req_timeout_count;
983 ASSERT_TRUE(GetResolverInfo(&res_servers, &res_domains, &res_tls_servers, &res_params,
984 &res_stats, &wait_for_pending_req_timeout_count));
Mike Yuda77e8e2018-11-26 13:26:21 +0900985
986 // Check the size of the stats and its contents.
987 EXPECT_EQ(static_cast<size_t>(MAXNS), res_servers.size());
988 EXPECT_EQ(static_cast<size_t>(MAXNS), res_tls_servers.size());
989 EXPECT_EQ(static_cast<size_t>(MAXDNSRCH), res_domains.size());
990 EXPECT_TRUE(std::equal(servers.begin(), servers.begin() + MAXNS, res_servers.begin()));
991 EXPECT_TRUE(std::equal(servers.begin(), servers.begin() + MAXNS, res_tls_servers.begin()));
992 EXPECT_TRUE(std::equal(domains.begin(), domains.begin() + MAXDNSRCH, res_domains.begin()));
993
Bernie Innocenti3e411a32019-01-17 21:28:24 +0900994 ASSERT_NO_FATAL_FAILURE(mDnsClient.ShutdownDNSServers(&dns));
Mike Yuda77e8e2018-11-26 13:26:21 +0900995 ASSERT_NO_FATAL_FAILURE(shutdownTlsServers(&tls));
996}
997
998TEST_F(ResolverTest, ResolverStats) {
Xiao Ma7c75f452018-12-11 17:56:32 +0900999 constexpr char listen_addr1[] = "127.0.0.4";
1000 constexpr char listen_addr2[] = "127.0.0.5";
1001 constexpr char listen_addr3[] = "127.0.0.6";
Mike Yuda77e8e2018-11-26 13:26:21 +09001002
1003 // Set server 1 timeout.
Xiao Ma7c75f452018-12-11 17:56:32 +09001004 test::DNSResponder dns1(listen_addr1, "53", 250, static_cast<ns_rcode>(-1));
Mike Yuda77e8e2018-11-26 13:26:21 +09001005 dns1.setResponseProbability(0.0);
1006 ASSERT_TRUE(dns1.startServer());
1007
1008 // Set server 2 responding server failure.
Xiao Ma7c75f452018-12-11 17:56:32 +09001009 test::DNSResponder dns2(listen_addr2);
Mike Yuda77e8e2018-11-26 13:26:21 +09001010 dns2.setResponseProbability(0.0);
1011 ASSERT_TRUE(dns2.startServer());
1012
1013 // Set server 3 workable.
Xiao Ma7c75f452018-12-11 17:56:32 +09001014 test::DNSResponder dns3(listen_addr3);
1015 dns3.addMapping(kHelloExampleCom, ns_type::ns_t_a, "1.2.3.4");
Mike Yuda77e8e2018-11-26 13:26:21 +09001016 ASSERT_TRUE(dns3.startServer());
1017
1018 std::vector<std::string> servers = {listen_addr1, listen_addr2, listen_addr3};
Xiao Ma7c75f452018-12-11 17:56:32 +09001019 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Mike Yuda77e8e2018-11-26 13:26:21 +09001020
1021 dns3.clearQueries();
Xiao Ma7c75f452018-12-11 17:56:32 +09001022 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
Mike Yuda77e8e2018-11-26 13:26:21 +09001023 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
Xiao Ma7c75f452018-12-11 17:56:32 +09001024 size_t found = GetNumQueries(dns3, kHelloExampleCom);
Mike Yuda77e8e2018-11-26 13:26:21 +09001025 EXPECT_LE(1U, found);
1026 std::string result_str = ToString(result);
1027 EXPECT_TRUE(result_str == "1.2.3.4") << ", result_str='" << result_str << "'";
1028
1029 std::vector<std::string> res_servers;
1030 std::vector<std::string> res_domains;
1031 std::vector<std::string> res_tls_servers;
Bernie Innocenti34de3ba2019-02-19 18:08:36 +09001032 res_params res_params;
Mike Yuda77e8e2018-11-26 13:26:21 +09001033 std::vector<ResolverStats> res_stats;
Ken Chen2a429352018-12-22 21:46:55 +08001034 int wait_for_pending_req_timeout_count;
1035 ASSERT_TRUE(GetResolverInfo(&res_servers, &res_domains, &res_tls_servers, &res_params,
1036 &res_stats, &wait_for_pending_req_timeout_count));
Mike Yuda77e8e2018-11-26 13:26:21 +09001037
1038 EXPECT_EQ(1, res_stats[0].timeouts);
1039 EXPECT_EQ(1, res_stats[1].errors);
1040 EXPECT_EQ(1, res_stats[2].successes);
Mike Yuda77e8e2018-11-26 13:26:21 +09001041}
1042
Bernie Innocenti443489e2018-08-10 14:27:23 +09001043// Test what happens if the specified TLS server is nonexistent.
1044TEST_F(ResolverTest, GetHostByName_TlsMissing) {
Xiao Ma7c75f452018-12-11 17:56:32 +09001045 constexpr char listen_addr[] = "127.0.0.3";
1046 constexpr char host_name[] = "tlsmissing.example.com.";
1047
1048 test::DNSResponder dns;
1049 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.3"}});
Bernie Innocenti443489e2018-08-10 14:27:23 +09001050 std::vector<std::string> servers = { listen_addr };
1051
1052 // There's nothing listening on this address, so validation will either fail or
1053 /// hang. Either way, queries will continue to flow to the DNSResponder.
Bernie Innocenti3e411a32019-01-17 21:28:24 +09001054 ASSERT_TRUE(
Xiao Ma7c75f452018-12-11 17:56:32 +09001055 mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, "", {}));
Bernie Innocenti443489e2018-08-10 14:27:23 +09001056
1057 const hostent* result;
1058
1059 result = gethostbyname("tlsmissing");
1060 ASSERT_FALSE(result == nullptr);
1061 EXPECT_EQ("1.2.3.3", ToString(result));
1062
1063 // Clear TLS bit.
Xiao Ma7c75f452018-12-11 17:56:32 +09001064 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Bernie Innocenti443489e2018-08-10 14:27:23 +09001065}
1066
1067// Test what happens if the specified TLS server replies with garbage.
1068TEST_F(ResolverTest, GetHostByName_TlsBroken) {
Xiao Ma7c75f452018-12-11 17:56:32 +09001069 constexpr char listen_addr[] = "127.0.0.3";
1070 constexpr char host_name1[] = "tlsbroken1.example.com.";
1071 constexpr char host_name2[] = "tlsbroken2.example.com.";
1072 const std::vector<DnsRecord> records = {
1073 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1074 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1075 };
1076
1077 test::DNSResponder dns;
1078 StartDns(dns, records);
Bernie Innocenti443489e2018-08-10 14:27:23 +09001079 std::vector<std::string> servers = { listen_addr };
1080
1081 // Bind the specified private DNS socket but don't respond to any client sockets yet.
1082 int s = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
1083 ASSERT_TRUE(s >= 0);
1084 struct sockaddr_in tlsServer = {
1085 .sin_family = AF_INET,
1086 .sin_port = htons(853),
1087 };
1088 ASSERT_TRUE(inet_pton(AF_INET, listen_addr, &tlsServer.sin_addr));
Bernie Innocenti6f9fd902018-10-11 20:50:23 +09001089 ASSERT_TRUE(enableSockopt(s, SOL_SOCKET, SO_REUSEPORT).ok());
1090 ASSERT_TRUE(enableSockopt(s, SOL_SOCKET, SO_REUSEADDR).ok());
Bernie Innocenti443489e2018-08-10 14:27:23 +09001091 ASSERT_FALSE(bind(s, reinterpret_cast<struct sockaddr*>(&tlsServer), sizeof(tlsServer)));
1092 ASSERT_FALSE(listen(s, 1));
1093
1094 // Trigger TLS validation.
Bernie Innocenti3e411a32019-01-17 21:28:24 +09001095 ASSERT_TRUE(
Xiao Ma7c75f452018-12-11 17:56:32 +09001096 mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, "", {}));
Bernie Innocenti443489e2018-08-10 14:27:23 +09001097
1098 struct sockaddr_storage cliaddr;
1099 socklen_t sin_size = sizeof(cliaddr);
1100 int new_fd = accept4(s, reinterpret_cast<struct sockaddr *>(&cliaddr), &sin_size, SOCK_CLOEXEC);
1101 ASSERT_TRUE(new_fd > 0);
1102
1103 // We've received the new file descriptor but not written to it or closed, so the
1104 // validation is still pending. Queries should still flow correctly because the
1105 // server is not used until validation succeeds.
1106 const hostent* result;
1107 result = gethostbyname("tlsbroken1");
1108 ASSERT_FALSE(result == nullptr);
1109 EXPECT_EQ("1.2.3.1", ToString(result));
1110
1111 // Now we cause the validation to fail.
1112 std::string garbage = "definitely not a valid TLS ServerHello";
1113 write(new_fd, garbage.data(), garbage.size());
1114 close(new_fd);
1115
1116 // Validation failure shouldn't interfere with lookups, because lookups won't be sent
1117 // to the TLS server unless validation succeeds.
1118 result = gethostbyname("tlsbroken2");
1119 ASSERT_FALSE(result == nullptr);
1120 EXPECT_EQ("1.2.3.2", ToString(result));
1121
1122 // Clear TLS bit.
Xiao Ma7c75f452018-12-11 17:56:32 +09001123 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Bernie Innocenti443489e2018-08-10 14:27:23 +09001124 close(s);
1125}
1126
1127TEST_F(ResolverTest, GetHostByName_Tls) {
Xiao Ma7c75f452018-12-11 17:56:32 +09001128 constexpr char listen_addr[] = "127.0.0.3";
1129 constexpr char listen_udp[] = "53";
1130 constexpr char listen_tls[] = "853";
1131 constexpr char host_name1[] = "tls1.example.com.";
1132 constexpr char host_name2[] = "tls2.example.com.";
1133 constexpr char host_name3[] = "tls3.example.com.";
1134 const std::vector<DnsRecord> records = {
1135 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1136 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1137 {host_name3, ns_type::ns_t_a, "1.2.3.3"},
1138 };
1139
1140 test::DNSResponder dns;
1141 StartDns(dns, records);
Bernie Innocenti443489e2018-08-10 14:27:23 +09001142 std::vector<std::string> servers = { listen_addr };
1143
1144 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1145 ASSERT_TRUE(tls.startServer());
Bernie Innocenti3e411a32019-01-17 21:28:24 +09001146 ASSERT_TRUE(
Xiao Ma7c75f452018-12-11 17:56:32 +09001147 mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, "", {}));
Bernie Innocenti443489e2018-08-10 14:27:23 +09001148
1149 const hostent* result;
1150
1151 // Wait for validation to complete.
1152 EXPECT_TRUE(tls.waitForQueries(1, 5000));
1153
1154 result = gethostbyname("tls1");
1155 ASSERT_FALSE(result == nullptr);
1156 EXPECT_EQ("1.2.3.1", ToString(result));
1157
1158 // Wait for query to get counted.
1159 EXPECT_TRUE(tls.waitForQueries(2, 5000));
1160
1161 // Stop the TLS server. Since we're in opportunistic mode, queries will
1162 // fall back to the locally-assigned (clear text) nameservers.
1163 tls.stopServer();
1164
1165 dns.clearQueries();
1166 result = gethostbyname("tls2");
1167 EXPECT_FALSE(result == nullptr);
1168 EXPECT_EQ("1.2.3.2", ToString(result));
1169 const auto queries = dns.queries();
1170 EXPECT_EQ(1U, queries.size());
1171 EXPECT_EQ("tls2.example.com.", queries[0].first);
1172 EXPECT_EQ(ns_t_a, queries[0].second);
1173
1174 // Reset the resolvers without enabling TLS. Queries should still be routed
1175 // to the UDP endpoint.
Xiao Ma7c75f452018-12-11 17:56:32 +09001176 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Bernie Innocenti443489e2018-08-10 14:27:23 +09001177
1178 result = gethostbyname("tls3");
1179 ASSERT_FALSE(result == nullptr);
1180 EXPECT_EQ("1.2.3.3", ToString(result));
Bernie Innocenti443489e2018-08-10 14:27:23 +09001181}
1182
1183TEST_F(ResolverTest, GetHostByName_TlsFingerprint) {
Xiao Ma7c75f452018-12-11 17:56:32 +09001184 constexpr char listen_addr[] = "127.0.0.3";
1185 constexpr char listen_udp[] = "53";
1186 constexpr char listen_tls[] = "853";
1187 test::DNSResponder dns;
Bernie Innocenti443489e2018-08-10 14:27:23 +09001188 ASSERT_TRUE(dns.startServer());
1189 for (int chain_length = 1; chain_length <= 3; ++chain_length) {
Bernie Innocentif2572392018-10-02 19:04:56 +09001190 std::string host_name = StringPrintf("tlsfingerprint%d.example.com.", chain_length);
Bernie Innocenti443489e2018-08-10 14:27:23 +09001191 dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.1");
1192 std::vector<std::string> servers = { listen_addr };
1193
1194 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1195 tls.set_chain_length(chain_length);
1196 ASSERT_TRUE(tls.startServer());
Xiao Ma7c75f452018-12-11 17:56:32 +09001197 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
Bernie Innocenti3e411a32019-01-17 21:28:24 +09001198 "", {base64Encode(tls.fingerprint())}));
Bernie Innocenti443489e2018-08-10 14:27:23 +09001199
1200 const hostent* result;
1201
1202 // Wait for validation to complete.
1203 EXPECT_TRUE(tls.waitForQueries(1, 5000));
1204
1205 result = gethostbyname(StringPrintf("tlsfingerprint%d", chain_length).c_str());
1206 EXPECT_FALSE(result == nullptr);
1207 if (result) {
1208 EXPECT_EQ("1.2.3.1", ToString(result));
1209
1210 // Wait for query to get counted.
1211 EXPECT_TRUE(tls.waitForQueries(2, 5000));
1212 }
1213
1214 // Clear TLS bit to ensure revalidation.
Xiao Ma7c75f452018-12-11 17:56:32 +09001215 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Bernie Innocenti443489e2018-08-10 14:27:23 +09001216 tls.stopServer();
1217 }
Bernie Innocenti443489e2018-08-10 14:27:23 +09001218}
1219
1220TEST_F(ResolverTest, GetHostByName_BadTlsFingerprint) {
Xiao Ma7c75f452018-12-11 17:56:32 +09001221 constexpr char listen_addr[] = "127.0.0.3";
1222 constexpr char listen_udp[] = "53";
1223 constexpr char listen_tls[] = "853";
1224 constexpr char host_name[] = "badtlsfingerprint.example.com.";
1225
1226 test::DNSResponder dns;
1227 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.1"}});
Bernie Innocenti443489e2018-08-10 14:27:23 +09001228 std::vector<std::string> servers = { listen_addr };
1229
1230 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1231 ASSERT_TRUE(tls.startServer());
1232 std::vector<uint8_t> bad_fingerprint = tls.fingerprint();
1233 bad_fingerprint[5] += 1; // Corrupt the fingerprint.
Xiao Ma7c75f452018-12-11 17:56:32 +09001234 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, "",
Bernie Innocenti3e411a32019-01-17 21:28:24 +09001235 {base64Encode(bad_fingerprint)}));
Bernie Innocenti443489e2018-08-10 14:27:23 +09001236
1237 // The initial validation should fail at the fingerprint check before
1238 // issuing a query.
1239 EXPECT_FALSE(tls.waitForQueries(1, 500));
1240
1241 // A fingerprint was provided and failed to match, so the query should fail.
1242 EXPECT_EQ(nullptr, gethostbyname("badtlsfingerprint"));
1243
1244 // Clear TLS bit.
Xiao Ma7c75f452018-12-11 17:56:32 +09001245 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Bernie Innocenti443489e2018-08-10 14:27:23 +09001246}
1247
1248// Test that we can pass two different fingerprints, and connection succeeds as long as
1249// at least one of them matches the server.
1250TEST_F(ResolverTest, GetHostByName_TwoTlsFingerprints) {
Xiao Ma7c75f452018-12-11 17:56:32 +09001251 constexpr char listen_addr[] = "127.0.0.3";
1252 constexpr char listen_udp[] = "53";
1253 constexpr char listen_tls[] = "853";
1254 constexpr char host_name[] = "twotlsfingerprints.example.com.";
1255
1256 test::DNSResponder dns;
1257 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.1"}});
Bernie Innocenti443489e2018-08-10 14:27:23 +09001258 std::vector<std::string> servers = { listen_addr };
1259
1260 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1261 ASSERT_TRUE(tls.startServer());
1262 std::vector<uint8_t> bad_fingerprint = tls.fingerprint();
1263 bad_fingerprint[5] += 1; // Corrupt the fingerprint.
Bernie Innocenti3e411a32019-01-17 21:28:24 +09001264 ASSERT_TRUE(mDnsClient.SetResolversWithTls(
Xiao Ma7c75f452018-12-11 17:56:32 +09001265 servers, kDefaultSearchDomains, kDefaultParams, "",
Bernie Innocenti3e411a32019-01-17 21:28:24 +09001266 {base64Encode(bad_fingerprint), base64Encode(tls.fingerprint())}));
Bernie Innocenti443489e2018-08-10 14:27:23 +09001267
1268 const hostent* result;
1269
1270 // Wait for validation to complete.
1271 EXPECT_TRUE(tls.waitForQueries(1, 5000));
1272
1273 result = gethostbyname("twotlsfingerprints");
1274 ASSERT_FALSE(result == nullptr);
1275 EXPECT_EQ("1.2.3.1", ToString(result));
1276
1277 // Wait for query to get counted.
1278 EXPECT_TRUE(tls.waitForQueries(2, 5000));
1279
1280 // Clear TLS bit.
Xiao Ma7c75f452018-12-11 17:56:32 +09001281 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Bernie Innocenti443489e2018-08-10 14:27:23 +09001282}
1283
1284TEST_F(ResolverTest, GetHostByName_TlsFingerprintGoesBad) {
Xiao Ma7c75f452018-12-11 17:56:32 +09001285 constexpr char listen_addr[] = "127.0.0.3";
1286 constexpr char listen_udp[] = "53";
1287 constexpr char listen_tls[] = "853";
1288 constexpr char host_name1[] = "tlsfingerprintgoesbad1.example.com.";
1289 constexpr char host_name2[] = "tlsfingerprintgoesbad2.example.com.";
1290 const std::vector<DnsRecord> records = {
1291 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1292 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1293 };
1294
1295 test::DNSResponder dns;
1296 StartDns(dns, records);
Bernie Innocenti443489e2018-08-10 14:27:23 +09001297 std::vector<std::string> servers = { listen_addr };
1298
1299 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1300 ASSERT_TRUE(tls.startServer());
Xiao Ma7c75f452018-12-11 17:56:32 +09001301 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, "",
Bernie Innocenti3e411a32019-01-17 21:28:24 +09001302 {base64Encode(tls.fingerprint())}));
Bernie Innocenti443489e2018-08-10 14:27:23 +09001303
1304 const hostent* result;
1305
1306 // Wait for validation to complete.
1307 EXPECT_TRUE(tls.waitForQueries(1, 5000));
1308
1309 result = gethostbyname("tlsfingerprintgoesbad1");
1310 ASSERT_FALSE(result == nullptr);
1311 EXPECT_EQ("1.2.3.1", ToString(result));
1312
1313 // Wait for query to get counted.
1314 EXPECT_TRUE(tls.waitForQueries(2, 5000));
1315
1316 // Restart the TLS server. This will generate a new certificate whose fingerprint
1317 // no longer matches the stored fingerprint.
1318 tls.stopServer();
1319 tls.startServer();
1320
1321 result = gethostbyname("tlsfingerprintgoesbad2");
1322 ASSERT_TRUE(result == nullptr);
1323 EXPECT_EQ(HOST_NOT_FOUND, h_errno);
1324
1325 // Clear TLS bit.
Xiao Ma7c75f452018-12-11 17:56:32 +09001326 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Bernie Innocenti443489e2018-08-10 14:27:23 +09001327}
1328
1329TEST_F(ResolverTest, GetHostByName_TlsFailover) {
Xiao Ma7c75f452018-12-11 17:56:32 +09001330 constexpr char listen_addr1[] = "127.0.0.3";
1331 constexpr char listen_addr2[] = "127.0.0.4";
1332 constexpr char listen_udp[] = "53";
1333 constexpr char listen_tls[] = "853";
1334 constexpr char host_name1[] = "tlsfailover1.example.com.";
1335 constexpr char host_name2[] = "tlsfailover2.example.com.";
1336 const std::vector<DnsRecord> records1 = {
1337 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1338 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1339 };
1340 const std::vector<DnsRecord> records2 = {
1341 {host_name1, ns_type::ns_t_a, "1.2.3.3"},
1342 {host_name2, ns_type::ns_t_a, "1.2.3.4"},
1343 };
1344
1345 test::DNSResponder dns1(listen_addr1);
1346 test::DNSResponder dns2(listen_addr2);
1347 StartDns(dns1, records1);
1348 StartDns(dns2, records2);
1349
Bernie Innocenti443489e2018-08-10 14:27:23 +09001350 std::vector<std::string> servers = { listen_addr1, listen_addr2 };
1351
1352 test::DnsTlsFrontend tls1(listen_addr1, listen_tls, listen_addr1, listen_udp);
1353 test::DnsTlsFrontend tls2(listen_addr2, listen_tls, listen_addr2, listen_udp);
1354 ASSERT_TRUE(tls1.startServer());
1355 ASSERT_TRUE(tls2.startServer());
Bernie Innocenti3e411a32019-01-17 21:28:24 +09001356 ASSERT_TRUE(mDnsClient.SetResolversWithTls(
Xiao Ma7c75f452018-12-11 17:56:32 +09001357 servers, kDefaultSearchDomains, kDefaultParams, "",
Bernie Innocenti3e411a32019-01-17 21:28:24 +09001358 {base64Encode(tls1.fingerprint()), base64Encode(tls2.fingerprint())}));
Bernie Innocenti443489e2018-08-10 14:27:23 +09001359
1360 const hostent* result;
1361
1362 // Wait for validation to complete.
1363 EXPECT_TRUE(tls1.waitForQueries(1, 5000));
1364 EXPECT_TRUE(tls2.waitForQueries(1, 5000));
1365
1366 result = gethostbyname("tlsfailover1");
1367 ASSERT_FALSE(result == nullptr);
1368 EXPECT_EQ("1.2.3.1", ToString(result));
1369
1370 // Wait for query to get counted.
1371 EXPECT_TRUE(tls1.waitForQueries(2, 5000));
1372 // No new queries should have reached tls2.
1373 EXPECT_EQ(1, tls2.queries());
1374
1375 // Stop tls1. Subsequent queries should attempt to reach tls1, fail, and retry to tls2.
1376 tls1.stopServer();
1377
1378 result = gethostbyname("tlsfailover2");
1379 EXPECT_EQ("1.2.3.4", ToString(result));
1380
1381 // Wait for query to get counted.
1382 EXPECT_TRUE(tls2.waitForQueries(2, 5000));
1383
1384 // No additional queries should have reached the insecure servers.
1385 EXPECT_EQ(2U, dns1.queries().size());
1386 EXPECT_EQ(2U, dns2.queries().size());
1387
1388 // Clear TLS bit.
Xiao Ma7c75f452018-12-11 17:56:32 +09001389 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Bernie Innocenti443489e2018-08-10 14:27:23 +09001390}
1391
1392TEST_F(ResolverTest, GetHostByName_BadTlsName) {
Xiao Ma7c75f452018-12-11 17:56:32 +09001393 constexpr char listen_addr[] = "127.0.0.3";
1394 constexpr char listen_udp[] = "53";
1395 constexpr char listen_tls[] = "853";
1396 constexpr char host_name[] = "badtlsname.example.com.";
1397
1398 test::DNSResponder dns;
1399 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.1"}});
Bernie Innocenti443489e2018-08-10 14:27:23 +09001400 std::vector<std::string> servers = { listen_addr };
1401
1402 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1403 ASSERT_TRUE(tls.startServer());
Xiao Ma7c75f452018-12-11 17:56:32 +09001404 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
Bernie Innocenti3e411a32019-01-17 21:28:24 +09001405 "www.example.com", {}));
Bernie Innocenti443489e2018-08-10 14:27:23 +09001406
1407 // The TLS server's certificate doesn't chain to a known CA, and a nonempty name was specified,
1408 // so the client should fail the TLS handshake before ever issuing a query.
1409 EXPECT_FALSE(tls.waitForQueries(1, 500));
1410
1411 // The query should fail hard, because a name was specified.
1412 EXPECT_EQ(nullptr, gethostbyname("badtlsname"));
1413
1414 // Clear TLS bit.
Xiao Ma7c75f452018-12-11 17:56:32 +09001415 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Bernie Innocenti443489e2018-08-10 14:27:23 +09001416}
1417
1418TEST_F(ResolverTest, GetAddrInfo_Tls) {
Xiao Ma7c75f452018-12-11 17:56:32 +09001419 constexpr char listen_addr[] = "127.0.0.3";
1420 constexpr char listen_udp[] = "53";
1421 constexpr char listen_tls[] = "853";
1422 constexpr char host_name[] = "addrinfotls.example.com.";
1423 const std::vector<DnsRecord> records = {
1424 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1425 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1426 };
1427
1428 test::DNSResponder dns;
1429 StartDns(dns, records);
Bernie Innocenti443489e2018-08-10 14:27:23 +09001430 std::vector<std::string> servers = { listen_addr };
1431
1432 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1433 ASSERT_TRUE(tls.startServer());
Xiao Ma7c75f452018-12-11 17:56:32 +09001434 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, "",
Bernie Innocenti3e411a32019-01-17 21:28:24 +09001435 {base64Encode(tls.fingerprint())}));
Bernie Innocenti443489e2018-08-10 14:27:23 +09001436
1437 // Wait for validation to complete.
1438 EXPECT_TRUE(tls.waitForQueries(1, 5000));
1439
1440 dns.clearQueries();
Bernie Innocenti9bf749f2018-08-30 08:37:22 +09001441 ScopedAddrinfo result = safe_getaddrinfo("addrinfotls", nullptr, nullptr);
1442 EXPECT_TRUE(result != nullptr);
Bernie Innocenti443489e2018-08-10 14:27:23 +09001443 size_t found = GetNumQueries(dns, host_name);
1444 EXPECT_LE(1U, found);
1445 // Could be A or AAAA
1446 std::string result_str = ToString(result);
1447 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
1448 << ", result_str='" << result_str << "'";
Bernie Innocenti443489e2018-08-10 14:27:23 +09001449 // Wait for both A and AAAA queries to get counted.
1450 EXPECT_TRUE(tls.waitForQueries(3, 5000));
1451
1452 // Clear TLS bit.
Xiao Ma7c75f452018-12-11 17:56:32 +09001453 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Bernie Innocenti443489e2018-08-10 14:27:23 +09001454}
1455
1456TEST_F(ResolverTest, TlsBypass) {
1457 const char OFF[] = "off";
1458 const char OPPORTUNISTIC[] = "opportunistic";
1459 const char STRICT[] = "strict";
1460
1461 const char GETHOSTBYNAME[] = "gethostbyname";
1462 const char GETADDRINFO[] = "getaddrinfo";
1463 const char GETADDRINFOFORNET[] = "getaddrinfofornet";
1464
1465 const unsigned BYPASS_NETID = NETID_USE_LOCAL_NAMESERVERS | TEST_NETID;
1466
Mike Yu5ae61542018-10-19 22:11:43 +08001467 const std::vector<uint8_t> NOOP_FINGERPRINT(SHA256_SIZE, 0U);
Bernie Innocenti443489e2018-08-10 14:27:23 +09001468
1469 const char ADDR4[] = "192.0.2.1";
1470 const char ADDR6[] = "2001:db8::1";
1471
1472 const char cleartext_addr[] = "127.0.0.53";
1473 const char cleartext_port[] = "53";
1474 const char tls_port[] = "853";
1475 const std::vector<std::string> servers = { cleartext_addr };
1476
Xiao Ma7c75f452018-12-11 17:56:32 +09001477 test::DNSResponder dns(cleartext_addr);
Bernie Innocenti443489e2018-08-10 14:27:23 +09001478 ASSERT_TRUE(dns.startServer());
1479
1480 test::DnsTlsFrontend tls(cleartext_addr, tls_port, cleartext_addr, cleartext_port);
1481
1482 struct TestConfig {
1483 const std::string mode;
1484 const bool withWorkingTLS;
1485 const std::string method;
1486
1487 std::string asHostName() const {
1488 return StringPrintf("%s.%s.%s.",
1489 mode.c_str(),
1490 withWorkingTLS ? "tlsOn" : "tlsOff",
1491 method.c_str());
1492 }
1493 } testConfigs[]{
1494 {OFF, false, GETHOSTBYNAME},
1495 {OPPORTUNISTIC, false, GETHOSTBYNAME},
1496 {STRICT, false, GETHOSTBYNAME},
1497 {OFF, true, GETHOSTBYNAME},
1498 {OPPORTUNISTIC, true, GETHOSTBYNAME},
1499 {STRICT, true, GETHOSTBYNAME},
1500 {OFF, false, GETADDRINFO},
1501 {OPPORTUNISTIC, false, GETADDRINFO},
1502 {STRICT, false, GETADDRINFO},
1503 {OFF, true, GETADDRINFO},
1504 {OPPORTUNISTIC, true, GETADDRINFO},
1505 {STRICT, true, GETADDRINFO},
1506 {OFF, false, GETADDRINFOFORNET},
1507 {OPPORTUNISTIC, false, GETADDRINFOFORNET},
1508 {STRICT, false, GETADDRINFOFORNET},
1509 {OFF, true, GETADDRINFOFORNET},
1510 {OPPORTUNISTIC, true, GETADDRINFOFORNET},
1511 {STRICT, true, GETADDRINFOFORNET},
1512 };
1513
1514 for (const auto& config : testConfigs) {
1515 const std::string testHostName = config.asHostName();
1516 SCOPED_TRACE(testHostName);
1517
1518 // Don't tempt test bugs due to caching.
1519 const char* host_name = testHostName.c_str();
1520 dns.addMapping(host_name, ns_type::ns_t_a, ADDR4);
1521 dns.addMapping(host_name, ns_type::ns_t_aaaa, ADDR6);
1522
1523 if (config.withWorkingTLS) ASSERT_TRUE(tls.startServer());
1524
1525 if (config.mode == OFF) {
Xiao Ma7c75f452018-12-11 17:56:32 +09001526 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, kDefaultSearchDomains,
1527 kDefaultParams));
Bernie Innocenti443489e2018-08-10 14:27:23 +09001528 } else if (config.mode == OPPORTUNISTIC) {
Xiao Ma7c75f452018-12-11 17:56:32 +09001529 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
1530 kDefaultParams, "", {}));
Bernie Innocenti443489e2018-08-10 14:27:23 +09001531 // Wait for validation to complete.
1532 if (config.withWorkingTLS) EXPECT_TRUE(tls.waitForQueries(1, 5000));
1533 } else if (config.mode == STRICT) {
1534 // We use the existence of fingerprints to trigger strict mode,
1535 // rather than hostname validation.
1536 const auto& fingerprint =
1537 (config.withWorkingTLS) ? tls.fingerprint() : NOOP_FINGERPRINT;
Xiao Ma7c75f452018-12-11 17:56:32 +09001538 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
1539 kDefaultParams, "",
Bernie Innocenti3e411a32019-01-17 21:28:24 +09001540 {base64Encode(fingerprint)}));
Bernie Innocenti443489e2018-08-10 14:27:23 +09001541 // Wait for validation to complete.
1542 if (config.withWorkingTLS) EXPECT_TRUE(tls.waitForQueries(1, 5000));
1543 } else {
1544 FAIL() << "Unsupported Private DNS mode: " << config.mode;
1545 }
1546
1547 const int tlsQueriesBefore = tls.queries();
1548
1549 const hostent* h_result = nullptr;
Bernie Innocenti9bf749f2018-08-30 08:37:22 +09001550 ScopedAddrinfo ai_result;
Bernie Innocenti443489e2018-08-10 14:27:23 +09001551
1552 if (config.method == GETHOSTBYNAME) {
1553 ASSERT_EQ(0, setNetworkForResolv(BYPASS_NETID));
1554 h_result = gethostbyname(host_name);
1555
1556 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
1557 ASSERT_FALSE(h_result == nullptr);
1558 ASSERT_EQ(4, h_result->h_length);
1559 ASSERT_FALSE(h_result->h_addr_list[0] == nullptr);
1560 EXPECT_EQ(ADDR4, ToString(h_result));
1561 EXPECT_TRUE(h_result->h_addr_list[1] == nullptr);
1562 } else if (config.method == GETADDRINFO) {
1563 ASSERT_EQ(0, setNetworkForResolv(BYPASS_NETID));
Bernie Innocenti9bf749f2018-08-30 08:37:22 +09001564 ai_result = safe_getaddrinfo(host_name, nullptr, nullptr);
1565 EXPECT_TRUE(ai_result != nullptr);
Bernie Innocenti443489e2018-08-10 14:27:23 +09001566
1567 EXPECT_LE(1U, GetNumQueries(dns, host_name));
1568 // Could be A or AAAA
1569 const std::string result_str = ToString(ai_result);
1570 EXPECT_TRUE(result_str == ADDR4 || result_str == ADDR6)
1571 << ", result_str='" << result_str << "'";
1572 } else if (config.method == GETADDRINFOFORNET) {
Bernie Innocenti9bf749f2018-08-30 08:37:22 +09001573 addrinfo* raw_ai_result = nullptr;
Bernie Innocentic165ce82018-10-16 23:35:28 +09001574 EXPECT_EQ(0, android_getaddrinfofornet(host_name, /*servname=*/nullptr,
1575 /*hints=*/nullptr, BYPASS_NETID, MARK_UNSET,
1576 &raw_ai_result));
Bernie Innocenti9bf749f2018-08-30 08:37:22 +09001577 ai_result.reset(raw_ai_result);
Bernie Innocenti443489e2018-08-10 14:27:23 +09001578
1579 EXPECT_LE(1U, GetNumQueries(dns, host_name));
1580 // Could be A or AAAA
1581 const std::string result_str = ToString(ai_result);
1582 EXPECT_TRUE(result_str == ADDR4 || result_str == ADDR6)
1583 << ", result_str='" << result_str << "'";
1584 } else {
1585 FAIL() << "Unsupported query method: " << config.method;
1586 }
1587
1588 const int tlsQueriesAfter = tls.queries();
1589 EXPECT_EQ(0, tlsQueriesAfter - tlsQueriesBefore);
1590
Bernie Innocenti443489e2018-08-10 14:27:23 +09001591 // Clear per-process resolv netid.
1592 ASSERT_EQ(0, setNetworkForResolv(NETID_UNSET));
1593 tls.stopServer();
1594 dns.clearQueries();
1595 }
Bernie Innocenti443489e2018-08-10 14:27:23 +09001596}
1597
1598TEST_F(ResolverTest, StrictMode_NoTlsServers) {
Mike Yu5ae61542018-10-19 22:11:43 +08001599 const std::vector<uint8_t> NOOP_FINGERPRINT(SHA256_SIZE, 0U);
Xiao Ma7c75f452018-12-11 17:56:32 +09001600 constexpr char cleartext_addr[] = "127.0.0.53";
Bernie Innocenti443489e2018-08-10 14:27:23 +09001601 const std::vector<std::string> servers = { cleartext_addr };
Xiao Ma7c75f452018-12-11 17:56:32 +09001602 constexpr char host_name[] = "strictmode.notlsips.example.com.";
1603 const std::vector<DnsRecord> records = {
1604 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1605 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1606 };
Bernie Innocenti443489e2018-08-10 14:27:23 +09001607
Xiao Ma7c75f452018-12-11 17:56:32 +09001608 test::DNSResponder dns(cleartext_addr);
1609 StartDns(dns, records);
Bernie Innocenti443489e2018-08-10 14:27:23 +09001610
Xiao Ma7c75f452018-12-11 17:56:32 +09001611 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, {},
Bernie Innocenti3e411a32019-01-17 21:28:24 +09001612 "", {base64Encode(NOOP_FINGERPRINT)}));
Bernie Innocenti443489e2018-08-10 14:27:23 +09001613
1614 addrinfo* ai_result = nullptr;
1615 EXPECT_NE(0, getaddrinfo(host_name, nullptr, nullptr, &ai_result));
1616 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
1617}
Luke Huangc68f1b92018-11-21 20:13:38 +08001618
1619namespace {
1620
1621int getAsyncResponse(int fd, int* rcode, u_char* buf, int bufLen) {
1622 struct pollfd wait_fd[1];
1623 wait_fd[0].fd = fd;
1624 wait_fd[0].events = POLLIN;
1625 short revents;
1626 int ret;
1627
1628 ret = poll(wait_fd, 1, -1);
1629 revents = wait_fd[0].revents;
1630 if (revents & POLLIN) {
1631 int n = resNetworkResult(fd, rcode, buf, bufLen);
Luke Huang952d0942018-12-26 16:53:03 +08001632 // Verify that resNetworkResult() closed the fd
1633 char dummy;
1634 EXPECT_EQ(-1, read(fd, &dummy, sizeof dummy));
1635 EXPECT_EQ(EBADF, errno);
Luke Huangc68f1b92018-11-21 20:13:38 +08001636 return n;
1637 }
1638 return -1;
1639}
1640
1641std::string toString(u_char* buf, int bufLen, int ipType) {
1642 ns_msg handle;
1643 int ancount, n = 0;
1644 ns_rr rr;
1645
1646 if (ns_initparse((const uint8_t*) buf, bufLen, &handle) >= 0) {
1647 ancount = ns_msg_count(handle, ns_s_an);
1648 if (ns_parserr(&handle, ns_s_an, n, &rr) == 0) {
1649 const u_char* rdata = ns_rr_rdata(rr);
1650 char buffer[INET6_ADDRSTRLEN];
1651 if (inet_ntop(ipType, (const char*) rdata, buffer, sizeof(buffer))) {
1652 return buffer;
1653 }
1654 }
1655 }
1656 return "";
1657}
1658
1659int dns_open_proxy() {
1660 int s = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
1661 if (s == -1) {
1662 return -1;
1663 }
1664 const int one = 1;
1665 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1666
1667 static const struct sockaddr_un proxy_addr = {
1668 .sun_family = AF_UNIX,
1669 .sun_path = "/dev/socket/dnsproxyd",
1670 };
1671
1672 if (TEMP_FAILURE_RETRY(connect(s, (const struct sockaddr*) &proxy_addr, sizeof(proxy_addr))) !=
1673 0) {
1674 close(s);
1675 return -1;
1676 }
1677
1678 return s;
1679}
1680
Luke Huang952d0942018-12-26 16:53:03 +08001681void expectAnswersValid(int fd, int ipType, const std::string& expectedAnswer) {
1682 int rcode = -1;
1683 uint8_t buf[MAXPACKET] = {};
1684
1685 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
1686 EXPECT_GT(res, 0);
1687 EXPECT_EQ(expectedAnswer, toString(buf, res, ipType));
1688}
1689
1690void expectAnswersNotValid(int fd, int expectedErrno) {
1691 int rcode = -1;
1692 uint8_t buf[MAXPACKET] = {};
1693
1694 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
1695 EXPECT_EQ(expectedErrno, res);
1696}
1697
Luke Huangc68f1b92018-11-21 20:13:38 +08001698} // namespace
1699
1700TEST_F(ResolverTest, Async_NormalQueryV4V6) {
Xiao Ma7c75f452018-12-11 17:56:32 +09001701 constexpr char listen_addr[] = "127.0.0.4";
1702 constexpr char host_name[] = "howdy.example.com.";
1703 const std::vector<DnsRecord> records = {
1704 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1705 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1706 };
1707
1708 test::DNSResponder dns(listen_addr);
1709 StartDns(dns, records);
Luke Huangc68f1b92018-11-21 20:13:38 +08001710 std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09001711 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huangc68f1b92018-11-21 20:13:38 +08001712
Luke Huang952d0942018-12-26 16:53:03 +08001713 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
1714 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huangc68f1b92018-11-21 20:13:38 +08001715 EXPECT_TRUE(fd1 != -1);
1716 EXPECT_TRUE(fd2 != -1);
1717
1718 u_char buf[MAXPACKET] = {};
1719 int rcode;
1720 int res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
1721 EXPECT_GT(res, 0);
1722 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
1723
1724 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
1725 EXPECT_GT(res, 0);
1726 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
1727
1728 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
1729
1730 // Re-query verify cache works
Luke Huang952d0942018-12-26 16:53:03 +08001731 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
1732 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huangc68f1b92018-11-21 20:13:38 +08001733
1734 EXPECT_TRUE(fd1 != -1);
1735 EXPECT_TRUE(fd2 != -1);
1736
1737 res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
1738 EXPECT_GT(res, 0);
1739 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
1740
1741 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
1742 EXPECT_GT(res, 0);
1743 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
1744
1745 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
1746}
1747
1748TEST_F(ResolverTest, Async_BadQuery) {
Xiao Ma7c75f452018-12-11 17:56:32 +09001749 constexpr char listen_addr[] = "127.0.0.4";
1750 constexpr char host_name[] = "howdy.example.com.";
1751 const std::vector<DnsRecord> records = {
1752 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1753 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1754 };
1755
1756 test::DNSResponder dns(listen_addr);
1757 StartDns(dns, records);
Luke Huangc68f1b92018-11-21 20:13:38 +08001758 std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09001759 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huangc68f1b92018-11-21 20:13:38 +08001760
1761 static struct {
1762 int fd;
1763 const char* dname;
1764 const int queryType;
1765 const int expectRcode;
1766 } kTestData[] = {
Luke Huang952d0942018-12-26 16:53:03 +08001767 {-1, "", ns_t_aaaa, 0},
1768 {-1, "as65ass46", ns_t_aaaa, 0},
1769 {-1, "454564564564", ns_t_aaaa, 0},
1770 {-1, "h645235", ns_t_a, 0},
1771 {-1, "www.google.com", ns_t_a, 0},
Luke Huangc68f1b92018-11-21 20:13:38 +08001772 };
1773
1774 for (auto& td : kTestData) {
1775 SCOPED_TRACE(td.dname);
Luke Huang952d0942018-12-26 16:53:03 +08001776 td.fd = resNetworkQuery(TEST_NETID, td.dname, ns_c_in, td.queryType, 0);
Luke Huangc68f1b92018-11-21 20:13:38 +08001777 EXPECT_TRUE(td.fd != -1);
1778 }
1779
1780 // dns_responder return empty resp(packet only contains query part) with no error currently
1781 for (const auto& td : kTestData) {
1782 u_char buf[MAXPACKET] = {};
1783 int rcode;
1784 SCOPED_TRACE(td.dname);
1785 int res = getAsyncResponse(td.fd, &rcode, buf, MAXPACKET);
1786 EXPECT_GT(res, 0);
1787 EXPECT_EQ(rcode, td.expectRcode);
1788 }
1789}
1790
1791TEST_F(ResolverTest, Async_EmptyAnswer) {
Xiao Ma7c75f452018-12-11 17:56:32 +09001792 constexpr char listen_addr[] = "127.0.0.4";
1793 constexpr char host_name[] = "howdy.example.com.";
1794 const std::vector<DnsRecord> records = {
1795 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1796 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1797 };
1798
1799 test::DNSResponder dns(listen_addr);
1800 StartDns(dns, records);
Luke Huangc68f1b92018-11-21 20:13:38 +08001801 std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09001802 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huangc68f1b92018-11-21 20:13:38 +08001803
Luke Huang26a0e2a2018-12-18 16:44:41 +08001804 // TODO: Disable retry to make this test explicit.
1805 auto& cv = dns.getCv();
1806 auto& cvMutex = dns.getCvMutex();
1807 int fd1;
1808 // Wait on the condition variable to ensure that the DNS server has handled our first query.
1809 {
1810 std::unique_lock lk(cvMutex);
Luke Huang952d0942018-12-26 16:53:03 +08001811 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huang26a0e2a2018-12-18 16:44:41 +08001812 EXPECT_TRUE(fd1 != -1);
1813 EXPECT_EQ(std::cv_status::no_timeout, cv.wait_for(lk, std::chrono::seconds(1)));
1814 }
Luke Huangc68f1b92018-11-21 20:13:38 +08001815
Luke Huangc68f1b92018-11-21 20:13:38 +08001816 dns.setResponseProbability(0.0);
Luke Huangc68f1b92018-11-21 20:13:38 +08001817
Luke Huang952d0942018-12-26 16:53:03 +08001818 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huangc68f1b92018-11-21 20:13:38 +08001819 EXPECT_TRUE(fd2 != -1);
1820
Luke Huang952d0942018-12-26 16:53:03 +08001821 int fd3 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huangc68f1b92018-11-21 20:13:38 +08001822 EXPECT_TRUE(fd3 != -1);
1823
Luke Huang26a0e2a2018-12-18 16:44:41 +08001824 uint8_t buf[MAXPACKET] = {};
Luke Huangc68f1b92018-11-21 20:13:38 +08001825 int rcode;
1826
Luke Huang26a0e2a2018-12-18 16:44:41 +08001827 // expect no response
1828 int res = getAsyncResponse(fd3, &rcode, buf, MAXPACKET);
1829 EXPECT_EQ(-ETIMEDOUT, res);
Luke Huangc68f1b92018-11-21 20:13:38 +08001830
Luke Huang26a0e2a2018-12-18 16:44:41 +08001831 // expect no response
Luke Huangc68f1b92018-11-21 20:13:38 +08001832 memset(buf, 0, MAXPACKET);
Luke Huang26a0e2a2018-12-18 16:44:41 +08001833 res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
1834 EXPECT_EQ(-ETIMEDOUT, res);
Luke Huangc68f1b92018-11-21 20:13:38 +08001835
Luke Huangc68f1b92018-11-21 20:13:38 +08001836 dns.setResponseProbability(1.0);
Luke Huangc68f1b92018-11-21 20:13:38 +08001837
Luke Huang952d0942018-12-26 16:53:03 +08001838 int fd4 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huangc68f1b92018-11-21 20:13:38 +08001839 EXPECT_TRUE(fd4 != -1);
1840
1841 memset(buf, 0, MAXPACKET);
1842 res = getAsyncResponse(fd4, &rcode, buf, MAXPACKET);
1843 EXPECT_GT(res, 0);
1844 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
1845
1846 memset(buf, 0, MAXPACKET);
1847 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
1848 EXPECT_GT(res, 0);
1849 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
1850}
1851
1852TEST_F(ResolverTest, Async_MalformedQuery) {
Xiao Ma7c75f452018-12-11 17:56:32 +09001853 constexpr char listen_addr[] = "127.0.0.4";
1854 constexpr char host_name[] = "howdy.example.com.";
1855 const std::vector<DnsRecord> records = {
1856 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1857 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1858 };
1859
1860 test::DNSResponder dns(listen_addr);
1861 StartDns(dns, records);
Luke Huangc68f1b92018-11-21 20:13:38 +08001862 std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09001863 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huangc68f1b92018-11-21 20:13:38 +08001864
1865 int fd = dns_open_proxy();
1866 EXPECT_TRUE(fd > 0);
1867
1868 const std::string badMsg = "16-52512#";
Xiao Ma7c75f452018-12-11 17:56:32 +09001869 static const struct {
Luke Huangc68f1b92018-11-21 20:13:38 +08001870 const std::string cmd;
1871 const int expectErr;
1872 } kTestData[] = {
Luke Huang952d0942018-12-26 16:53:03 +08001873 // Too few arguments
Luke Huangc68f1b92018-11-21 20:13:38 +08001874 {"resnsend " + badMsg + '\0', -EINVAL},
1875 // Bad netId
Luke Huang952d0942018-12-26 16:53:03 +08001876 {"resnsend badnetId 0 " + badMsg + '\0', -EINVAL},
Luke Huangc68f1b92018-11-21 20:13:38 +08001877 // Bad raw data
Luke Huang952d0942018-12-26 16:53:03 +08001878 {"resnsend " + std::to_string(TEST_NETID) + " 0 " + badMsg + '\0', -EILSEQ},
Luke Huangc68f1b92018-11-21 20:13:38 +08001879 };
1880
1881 for (unsigned int i = 0; i < std::size(kTestData); i++) {
1882 auto& td = kTestData[i];
1883 SCOPED_TRACE(td.cmd);
1884 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, td.cmd.c_str(), td.cmd.size()));
1885 EXPECT_EQ(rc, static_cast<ssize_t>(td.cmd.size()));
1886
1887 int32_t tmp;
1888 rc = TEMP_FAILURE_RETRY(read(fd, &tmp, sizeof(tmp)));
1889 EXPECT_TRUE(rc > 0);
1890 EXPECT_EQ(static_cast<int>(ntohl(tmp)), td.expectErr);
1891 }
1892 // Normal query with answer buffer
1893 // This is raw data of query "howdy.example.com" type 1 class 1
1894 std::string query = "81sBAAABAAAAAAAABWhvd2R5B2V4YW1wbGUDY29tAAABAAE=";
Luke Huang952d0942018-12-26 16:53:03 +08001895 std::string cmd = "resnsend " + std::to_string(TEST_NETID) + " 0 " + query + '\0';
Luke Huangc68f1b92018-11-21 20:13:38 +08001896 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size()));
1897 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size()));
1898
1899 u_char smallBuf[1] = {};
1900 int rcode;
1901 rc = getAsyncResponse(fd, &rcode, smallBuf, 1);
Luke Huang952d0942018-12-26 16:53:03 +08001902 EXPECT_EQ(-EMSGSIZE, rc);
Luke Huangc68f1b92018-11-21 20:13:38 +08001903
1904 // Do the normal test with large buffer again
1905 fd = dns_open_proxy();
1906 EXPECT_TRUE(fd > 0);
1907 rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size()));
1908 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size()));
1909 u_char buf[MAXPACKET] = {};
1910 rc = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
1911 EXPECT_EQ("1.2.3.4", toString(buf, rc, AF_INET));
Mike Yu5b9ffb22018-12-02 17:54:29 +09001912}
1913
Luke Huang952d0942018-12-26 16:53:03 +08001914TEST_F(ResolverTest, Async_CacheFlags) {
Xiao Ma7c75f452018-12-11 17:56:32 +09001915 constexpr char listen_addr[] = "127.0.0.4";
1916 constexpr char host_name[] = "howdy.example.com.";
1917 const std::vector<DnsRecord> records = {
1918 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1919 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1920 };
1921
1922 test::DNSResponder dns(listen_addr);
1923 StartDns(dns, records);
Luke Huang952d0942018-12-26 16:53:03 +08001924 std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09001925 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang952d0942018-12-26 16:53:03 +08001926
1927 // ANDROID_RESOLV_NO_CACHE_STORE
1928 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1929 ANDROID_RESOLV_NO_CACHE_STORE);
1930 EXPECT_TRUE(fd1 != -1);
1931 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1932 ANDROID_RESOLV_NO_CACHE_STORE);
1933 EXPECT_TRUE(fd2 != -1);
1934 int fd3 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1935 ANDROID_RESOLV_NO_CACHE_STORE);
1936 EXPECT_TRUE(fd3 != -1);
1937
1938 expectAnswersValid(fd3, AF_INET, "1.2.3.4");
1939 expectAnswersValid(fd2, AF_INET, "1.2.3.4");
1940 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
1941
1942 // No cache exists, expect 3 queries
1943 EXPECT_EQ(3U, GetNumQueries(dns, host_name));
1944
1945 // Re-query and cache
1946 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
1947
1948 EXPECT_TRUE(fd1 != -1);
1949
1950 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
1951
1952 // Now we have cache, expect 4 queries
1953 EXPECT_EQ(4U, GetNumQueries(dns, host_name));
1954
1955 // ANDROID_RESOLV_NO_CACHE_LOOKUP
1956 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1957 ANDROID_RESOLV_NO_CACHE_LOOKUP);
1958 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1959 ANDROID_RESOLV_NO_CACHE_LOOKUP);
1960
1961 EXPECT_TRUE(fd1 != -1);
1962 EXPECT_TRUE(fd2 != -1);
1963
1964 expectAnswersValid(fd2, AF_INET, "1.2.3.4");
1965 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
1966
1967 // Skip cache, expect 6 queries
1968 EXPECT_EQ(6U, GetNumQueries(dns, host_name));
1969
1970 // Re-query verify cache works
1971 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1972 ANDROID_RESOLV_NO_CACHE_STORE);
1973 EXPECT_TRUE(fd1 != -1);
1974 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
1975
1976 // Cache hits, expect still 6 queries
1977 EXPECT_EQ(6U, GetNumQueries(dns, host_name));
1978}
1979
1980TEST_F(ResolverTest, Async_NoRetryFlag) {
Xiao Ma7c75f452018-12-11 17:56:32 +09001981 constexpr char listen_addr[] = "127.0.0.4";
1982 constexpr char host_name[] = "howdy.example.com.";
1983 const std::vector<DnsRecord> records = {
1984 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1985 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1986 };
1987
1988 test::DNSResponder dns(listen_addr);
1989 StartDns(dns, records);
Luke Huang952d0942018-12-26 16:53:03 +08001990 std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09001991 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang952d0942018-12-26 16:53:03 +08001992
1993 dns.setResponseProbability(0.0);
1994
1995 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1996 ANDROID_RESOLV_NO_RETRY);
1997 EXPECT_TRUE(fd1 != -1);
1998
1999 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
2000 ANDROID_RESOLV_NO_RETRY);
2001 EXPECT_TRUE(fd2 != -1);
2002
2003 // expect no response
2004 expectAnswersNotValid(fd1, -ETIMEDOUT);
2005 expectAnswersNotValid(fd2, -ETIMEDOUT);
2006
2007 // No retry case, expect 2 queries
2008 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
2009
2010 dns.clearQueries();
2011
2012 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
2013 EXPECT_TRUE(fd1 != -1);
2014
2015 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
2016 EXPECT_TRUE(fd2 != -1);
2017
2018 // expect no response
2019 expectAnswersNotValid(fd1, -ETIMEDOUT);
2020 expectAnswersNotValid(fd2, -ETIMEDOUT);
2021
2022 // Retry case, expect 4 queries
2023 EXPECT_EQ(4U, GetNumQueries(dns, host_name));
2024}
2025
Mike Yu5b9ffb22018-12-02 17:54:29 +09002026// This test checks that the resolver should not generate the request containing OPT RR when using
Ken Chenbfd32022019-01-02 14:59:38 +08002027// cleartext DNS. If we query the DNS server not supporting EDNS0 and it reponds with
2028// FORMERR_ON_EDNS, we will fallback to no EDNS0 and try again. If the server does no response, we
2029// won't retry so that we get no answer.
Mike Yu5b9ffb22018-12-02 17:54:29 +09002030TEST_F(ResolverTest, BrokenEdns) {
2031 typedef test::DNSResponder::Edns Edns;
2032 enum ExpectResult { EXPECT_FAILURE, EXPECT_SUCCESS };
2033
2034 const char OFF[] = "off";
2035 const char OPPORTUNISTIC_UDP[] = "opportunistic_udp";
2036 const char OPPORTUNISTIC_TLS[] = "opportunistic_tls";
2037 const char STRICT[] = "strict";
2038 const char GETHOSTBYNAME[] = "gethostbyname";
2039 const char GETADDRINFO[] = "getaddrinfo";
2040 const std::vector<uint8_t> NOOP_FINGERPRINT(SHA256_SIZE, 0U);
2041 const char ADDR4[] = "192.0.2.1";
2042 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2043 const char CLEARTEXT_PORT[] = "53";
2044 const char TLS_PORT[] = "853";
2045 const std::vector<std::string> servers = { CLEARTEXT_ADDR };
2046
2047 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, 250, ns_rcode::ns_r_servfail);
2048 ASSERT_TRUE(dns.startServer());
2049
2050 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2051
2052 static const struct TestConfig {
2053 std::string mode;
2054 std::string method;
2055 Edns edns;
2056 ExpectResult expectResult;
2057
2058 std::string asHostName() const {
2059 const char* ednsString;
2060 switch (edns) {
2061 case Edns::ON:
2062 ednsString = "ednsOn";
2063 break;
Ken Chenbfd32022019-01-02 14:59:38 +08002064 case Edns::FORMERR_ON_EDNS:
Mike Yu5b9ffb22018-12-02 17:54:29 +09002065 ednsString = "ednsFormerr";
2066 break;
2067 case Edns::DROP:
2068 ednsString = "ednsDrop";
2069 break;
2070 default:
2071 ednsString = "";
2072 break;
2073 }
2074 return StringPrintf("%s.%s.%s.", mode.c_str(), method.c_str(), ednsString);
2075 }
2076 } testConfigs[] = {
2077 // In OPPORTUNISTIC_TLS, we get no answer if the DNS server supports TLS but not EDNS0.
2078 // Could such server exist? if so, we might need to fallback to query cleartext DNS.
2079 // Another thing is that {OPPORTUNISTIC_TLS, Edns::DROP} and {STRICT, Edns::DROP} are
2080 // commented out since TLS timeout is not configurable.
2081 // TODO: Uncomment them after TLS timeout is configurable.
2082 {OFF, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2083 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2084 {OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2085 {STRICT, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
Ken Chenbfd32022019-01-02 14:59:38 +08002086 {OFF, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2087 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2088 {OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
2089 {STRICT, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
Mike Yu5b9ffb22018-12-02 17:54:29 +09002090 {OFF, GETHOSTBYNAME, Edns::DROP, EXPECT_SUCCESS},
2091 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::DROP, EXPECT_SUCCESS},
2092 //{OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::DROP, EXPECT_FAILURE},
2093 //{STRICT, GETHOSTBYNAME, Edns::DROP, EXPECT_FAILURE},
2094 {OFF, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2095 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2096 {OPPORTUNISTIC_TLS, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2097 {STRICT, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
Ken Chenbfd32022019-01-02 14:59:38 +08002098 {OFF, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2099 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2100 {OPPORTUNISTIC_TLS, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
2101 {STRICT, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
Mike Yu5b9ffb22018-12-02 17:54:29 +09002102 {OFF, GETADDRINFO, Edns::DROP, EXPECT_SUCCESS},
2103 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::DROP, EXPECT_SUCCESS},
2104 //{OPPORTUNISTIC_TLS, GETADDRINFO, Edns::DROP, EXPECT_FAILURE},
2105 //{STRICT, GETADDRINFO, Edns::DROP, EXPECT_FAILURE},
2106 };
2107
2108 for (const auto& config : testConfigs) {
2109 const std::string testHostName = config.asHostName();
2110 SCOPED_TRACE(testHostName);
2111
2112 const char* host_name = testHostName.c_str();
2113 dns.addMapping(host_name, ns_type::ns_t_a, ADDR4);
2114 dns.setEdns(config.edns);
2115
2116 if (config.mode == OFF) {
Xiao Ma7c75f452018-12-11 17:56:32 +09002117 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Mike Yu5b9ffb22018-12-02 17:54:29 +09002118 } else if (config.mode == OPPORTUNISTIC_UDP) {
Xiao Ma7c75f452018-12-11 17:56:32 +09002119 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
2120 kDefaultParams, "", {}));
Mike Yu5b9ffb22018-12-02 17:54:29 +09002121 } else if (config.mode == OPPORTUNISTIC_TLS) {
2122 ASSERT_TRUE(tls.startServer());
Xiao Ma7c75f452018-12-11 17:56:32 +09002123 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
2124 kDefaultParams, "", {}));
Mike Yu5b9ffb22018-12-02 17:54:29 +09002125 // Wait for validation to complete.
2126 EXPECT_TRUE(tls.waitForQueries(1, 5000));
2127 } else if (config.mode == STRICT) {
2128 ASSERT_TRUE(tls.startServer());
Xiao Ma7c75f452018-12-11 17:56:32 +09002129 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
2130 kDefaultParams, "",
Bernie Innocenti3e411a32019-01-17 21:28:24 +09002131 {base64Encode(tls.fingerprint())}));
Mike Yu5b9ffb22018-12-02 17:54:29 +09002132 // Wait for validation to complete.
2133 EXPECT_TRUE(tls.waitForQueries(1, 5000));
2134 }
2135
2136 if (config.method == GETHOSTBYNAME) {
2137 const hostent* h_result = gethostbyname(host_name);
2138 if (config.expectResult == EXPECT_SUCCESS) {
2139 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2140 ASSERT_TRUE(h_result != nullptr);
2141 ASSERT_EQ(4, h_result->h_length);
2142 ASSERT_FALSE(h_result->h_addr_list[0] == nullptr);
2143 EXPECT_EQ(ADDR4, ToString(h_result));
2144 EXPECT_TRUE(h_result->h_addr_list[1] == nullptr);
2145 } else {
2146 EXPECT_EQ(0U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
2147 ASSERT_TRUE(h_result == nullptr);
2148 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2149 }
2150 } else if (config.method == GETADDRINFO) {
2151 ScopedAddrinfo ai_result;
2152 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2153 ai_result = safe_getaddrinfo(host_name, nullptr, &hints);
2154 if (config.expectResult == EXPECT_SUCCESS) {
2155 EXPECT_TRUE(ai_result != nullptr);
2156 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
2157 const std::string result_str = ToString(ai_result);
2158 EXPECT_EQ(ADDR4, result_str);
2159 } else {
2160 EXPECT_TRUE(ai_result == nullptr);
2161 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
2162 }
2163 } else {
2164 FAIL() << "Unsupported query method: " << config.method;
2165 }
2166
2167 tls.stopServer();
2168 dns.clearQueries();
2169 }
2170
2171 dns.stopServer();
2172}
nuccachenf52f7a52018-07-17 18:07:23 +08002173
Ken Chenbfd32022019-01-02 14:59:38 +08002174// DNS-over-TLS validation success, but server does not respond to TLS query after a while.
2175// Resolver should have a reasonable number of retries instead of spinning forever. We don't have
2176// an efficient way to know if resolver is stuck in an infinite loop. However, test case will be
2177// failed due to timeout.
2178TEST_F(ResolverTest, UnstableTls) {
2179 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2180 const char CLEARTEXT_PORT[] = "53";
2181 const char TLS_PORT[] = "853";
2182 const char* host_name1 = "nonexistent1.example.com.";
2183 const char* host_name2 = "nonexistent2.example.com.";
2184 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
2185
2186 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, 250, ns_rcode::ns_r_servfail);
2187 ASSERT_TRUE(dns.startServer());
2188 dns.setEdns(test::DNSResponder::Edns::FORMERR_ON_EDNS);
2189 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2190 ASSERT_TRUE(tls.startServer());
Bernie Innocenti3e411a32019-01-17 21:28:24 +09002191 ASSERT_TRUE(
Xiao Ma7c75f452018-12-11 17:56:32 +09002192 mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, "", {}));
Ken Chenbfd32022019-01-02 14:59:38 +08002193 // Wait for validation complete.
2194 EXPECT_TRUE(tls.waitForQueries(1, 5000));
2195 // Shutdown TLS server to get an error. It's similar to no response case but without waiting.
2196 tls.stopServer();
2197
2198 const hostent* h_result = gethostbyname(host_name1);
2199 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
2200 ASSERT_TRUE(h_result == nullptr);
2201 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2202
2203 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2204 ScopedAddrinfo ai_result = safe_getaddrinfo(host_name2, nullptr, &hints);
2205 EXPECT_TRUE(ai_result == nullptr);
2206 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
2207}
2208
2209// DNS-over-TLS validation success, but server does not respond to TLS query after a while.
2210// Moreover, server responds RCODE=FORMERR even on non-EDNS query.
2211TEST_F(ResolverTest, BogusDnsServer) {
2212 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2213 const char CLEARTEXT_PORT[] = "53";
2214 const char TLS_PORT[] = "853";
2215 const char* host_name1 = "nonexistent1.example.com.";
2216 const char* host_name2 = "nonexistent2.example.com.";
2217 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
2218
2219 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, 250, ns_rcode::ns_r_servfail);
2220 ASSERT_TRUE(dns.startServer());
2221 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2222 ASSERT_TRUE(tls.startServer());
Bernie Innocenti3e411a32019-01-17 21:28:24 +09002223 ASSERT_TRUE(
Xiao Ma7c75f452018-12-11 17:56:32 +09002224 mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, "", {}));
Ken Chenbfd32022019-01-02 14:59:38 +08002225 // Wait for validation complete.
2226 EXPECT_TRUE(tls.waitForQueries(1, 5000));
2227 // Shutdown TLS server to get an error. It's similar to no response case but without waiting.
2228 tls.stopServer();
2229 dns.setEdns(test::DNSResponder::Edns::FORMERR_UNCOND);
2230
2231 const hostent* h_result = gethostbyname(host_name1);
2232 EXPECT_EQ(0U, GetNumQueries(dns, host_name1));
2233 ASSERT_TRUE(h_result == nullptr);
2234 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2235
2236 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2237 ScopedAddrinfo ai_result = safe_getaddrinfo(host_name2, nullptr, &hints);
2238 EXPECT_TRUE(ai_result == nullptr);
2239 EXPECT_EQ(0U, GetNumQueries(dns, host_name2));
2240}
2241
nuccachenf52f7a52018-07-17 18:07:23 +08002242TEST_F(ResolverTest, GetAddrInfo_Dns64Synthesize) {
2243 constexpr char listen_addr[] = "::1";
2244 constexpr char listen_addr2[] = "127.0.0.5";
nuccachenf52f7a52018-07-17 18:07:23 +08002245 constexpr char dns64_name[] = "ipv4only.arpa.";
2246 constexpr char host_name[] = "v4only.example.com.";
Xiao Ma7c75f452018-12-11 17:56:32 +09002247 const std::vector<DnsRecord> records = {
2248 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2249 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2250 };
nuccachenf52f7a52018-07-17 18:07:23 +08002251
Xiao Ma7c75f452018-12-11 17:56:32 +09002252 test::DNSResponder dns(listen_addr);
2253 test::DNSResponder dns2(listen_addr2);
2254 StartDns(dns, records);
2255 StartDns(dns2, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
nuccachenf52f7a52018-07-17 18:07:23 +08002256
2257 std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09002258 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachenf52f7a52018-07-17 18:07:23 +08002259
2260 // Wait for detecting prefix to complete.
2261 EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
2262
2263 // hints are necessary in order to let netd know which type of addresses the caller is
2264 // interested in.
Xiao Ma7c75f452018-12-11 17:56:32 +09002265 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachenf52f7a52018-07-17 18:07:23 +08002266 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, &hints);
2267 EXPECT_TRUE(result != nullptr);
2268 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2269
2270 std::string result_str = ToString(result);
2271 EXPECT_EQ(result_str, "64:ff9b::102:304");
2272
2273 // Let's test the case when there's an IPv4 resolver.
2274 servers = {listen_addr, listen_addr2};
Xiao Ma7c75f452018-12-11 17:56:32 +09002275 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachenf52f7a52018-07-17 18:07:23 +08002276 dns.clearQueries();
2277 dns2.clearQueries();
2278
2279 // Netd doesn't detect prefix because there has an IPv4 resolver but all IPv6 resolvers.
2280 EXPECT_FALSE(WaitForPrefix64Detected(TEST_NETID, 1000));
2281
2282 result = safe_getaddrinfo("v4only", nullptr, &hints);
2283 EXPECT_TRUE(result != nullptr);
2284 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2285
2286 result_str = ToString(result);
2287 EXPECT_EQ(result_str, "1.2.3.4");
2288}
2289
nuccachenf52f7a52018-07-17 18:07:23 +08002290TEST_F(ResolverTest, GetAddrInfo_Dns64QuerySpecified) {
2291 constexpr char listen_addr[] = "::1";
nuccachenf52f7a52018-07-17 18:07:23 +08002292 constexpr char dns64_name[] = "ipv4only.arpa.";
2293 constexpr char host_name[] = "v4only.example.com.";
Xiao Ma7c75f452018-12-11 17:56:32 +09002294 const std::vector<DnsRecord> records = {
2295 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2296 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2297 };
nuccachenf52f7a52018-07-17 18:07:23 +08002298
Xiao Ma7c75f452018-12-11 17:56:32 +09002299 test::DNSResponder dns(listen_addr);
2300 StartDns(dns, records);
nuccachenf52f7a52018-07-17 18:07:23 +08002301 const std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09002302 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachenf52f7a52018-07-17 18:07:23 +08002303
2304 // Wait for detecting prefix to complete.
2305 EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
2306
2307 // Ensure to synthesize AAAA if AF_INET6 is specified, and not to synthesize AAAA
2308 // in AF_INET case.
2309 addrinfo hints;
2310 memset(&hints, 0, sizeof(hints));
2311 hints.ai_family = AF_INET6;
2312 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, &hints);
2313 EXPECT_TRUE(result != nullptr);
2314 std::string result_str = ToString(result);
2315 EXPECT_EQ(result_str, "64:ff9b::102:304");
2316
2317 hints.ai_family = AF_INET;
2318 result = safe_getaddrinfo("v4only", nullptr, &hints);
2319 EXPECT_TRUE(result != nullptr);
2320 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2321 result_str = ToString(result);
2322 EXPECT_EQ(result_str, "1.2.3.4");
2323}
nuccachenf52f7a52018-07-17 18:07:23 +08002324
2325TEST_F(ResolverTest, GetAddrInfo_Dns64QueryUnspecifiedV6) {
2326 constexpr char listen_addr[] = "::1";
nuccachenf52f7a52018-07-17 18:07:23 +08002327 constexpr char dns64_name[] = "ipv4only.arpa.";
2328 constexpr char host_name[] = "v4v6.example.com.";
Xiao Ma7c75f452018-12-11 17:56:32 +09002329 const std::vector<DnsRecord> records = {
2330 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2331 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2332 {host_name, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
2333 };
nuccachenf52f7a52018-07-17 18:07:23 +08002334
Xiao Ma7c75f452018-12-11 17:56:32 +09002335 test::DNSResponder dns(listen_addr);
2336 StartDns(dns, records);
nuccachenf52f7a52018-07-17 18:07:23 +08002337 const std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09002338 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachenf52f7a52018-07-17 18:07:23 +08002339
2340 // Wait for detecting prefix to complete.
2341 EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
2342
Xiao Ma7c75f452018-12-11 17:56:32 +09002343 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachenf52f7a52018-07-17 18:07:23 +08002344 ScopedAddrinfo result = safe_getaddrinfo("v4v6", nullptr, &hints);
2345 EXPECT_TRUE(result != nullptr);
2346 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2347
2348 // In AF_UNSPEC case, do not synthesize AAAA if there's at least one AAAA answer.
Xiao Ma7c75f452018-12-11 17:56:32 +09002349 const std::vector<std::string> result_strs = ToStrings(result);
nuccachenf52f7a52018-07-17 18:07:23 +08002350 for (const auto& str : result_strs) {
2351 EXPECT_TRUE(str == "1.2.3.4" || str == "2001:db8::102:304")
2352 << ", result_str='" << str << "'";
2353 }
2354}
2355
2356TEST_F(ResolverTest, GetAddrInfo_Dns64QueryUnspecifiedNoV6) {
2357 constexpr char listen_addr[] = "::1";
nuccachenf52f7a52018-07-17 18:07:23 +08002358 constexpr char dns64_name[] = "ipv4only.arpa.";
2359 constexpr char host_name[] = "v4v6.example.com.";
Xiao Ma7c75f452018-12-11 17:56:32 +09002360 const std::vector<DnsRecord> records = {
2361 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2362 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2363 };
nuccachenf52f7a52018-07-17 18:07:23 +08002364
Xiao Ma7c75f452018-12-11 17:56:32 +09002365 test::DNSResponder dns(listen_addr);
2366 StartDns(dns, records);
nuccachenf52f7a52018-07-17 18:07:23 +08002367 const std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09002368 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachenf52f7a52018-07-17 18:07:23 +08002369
2370 // Wait for detecting prefix to complete.
2371 EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
2372
Xiao Ma7c75f452018-12-11 17:56:32 +09002373 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachenf52f7a52018-07-17 18:07:23 +08002374 ScopedAddrinfo result = safe_getaddrinfo("v4v6", nullptr, &hints);
2375 EXPECT_TRUE(result != nullptr);
2376 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2377
2378 // In AF_UNSPEC case, synthesize AAAA if there's no AAAA answer.
2379 std::string result_str = ToString(result);
2380 EXPECT_EQ(result_str, "64:ff9b::102:304");
2381}
2382
2383TEST_F(ResolverTest, GetAddrInfo_Dns64QuerySpecialUseIPv4Addresses) {
2384 constexpr char THIS_NETWORK[] = "this_network";
2385 constexpr char LOOPBACK[] = "loopback";
2386 constexpr char LINK_LOCAL[] = "link_local";
2387 constexpr char MULTICAST[] = "multicast";
2388 constexpr char LIMITED_BROADCAST[] = "limited_broadcast";
2389
2390 constexpr char ADDR_THIS_NETWORK[] = "0.0.0.1";
2391 constexpr char ADDR_LOOPBACK[] = "127.0.0.1";
2392 constexpr char ADDR_LINK_LOCAL[] = "169.254.0.1";
2393 constexpr char ADDR_MULTICAST[] = "224.0.0.1";
2394 constexpr char ADDR_LIMITED_BROADCAST[] = "255.255.255.255";
2395
2396 constexpr char listen_addr[] = "::1";
nuccachenf52f7a52018-07-17 18:07:23 +08002397 constexpr char dns64_name[] = "ipv4only.arpa.";
2398
Xiao Ma7c75f452018-12-11 17:56:32 +09002399 test::DNSResponder dns(listen_addr);
2400 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachenf52f7a52018-07-17 18:07:23 +08002401 const std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09002402 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachenf52f7a52018-07-17 18:07:23 +08002403
2404 // Wait for detecting prefix to complete.
2405 EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
2406
2407 static const struct TestConfig {
2408 std::string name;
2409 std::string addr;
2410
2411 std::string asHostName() const { return StringPrintf("%s.example.com.", name.c_str()); }
2412 } testConfigs[]{
2413 {THIS_NETWORK, ADDR_THIS_NETWORK},
2414 {LOOPBACK, ADDR_LOOPBACK},
2415 {LINK_LOCAL, ADDR_LINK_LOCAL},
2416 {MULTICAST, ADDR_MULTICAST},
2417 {LIMITED_BROADCAST, ADDR_LIMITED_BROADCAST}
2418 };
2419
2420 for (const auto& config : testConfigs) {
2421 const std::string testHostName = config.asHostName();
2422 SCOPED_TRACE(testHostName);
2423
2424 const char* host_name = testHostName.c_str();
2425 dns.addMapping(host_name, ns_type::ns_t_a, config.addr.c_str());
2426
2427 addrinfo hints;
2428 memset(&hints, 0, sizeof(hints));
2429 hints.ai_family = AF_INET6;
2430 ScopedAddrinfo result = safe_getaddrinfo(config.name.c_str(), nullptr, &hints);
2431 // In AF_INET6 case, don't return IPv4 answers
2432 EXPECT_TRUE(result == nullptr);
2433 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2434 dns.clearQueries();
2435
2436 memset(&hints, 0, sizeof(hints));
2437 hints.ai_family = AF_UNSPEC;
2438 result = safe_getaddrinfo(config.name.c_str(), nullptr, &hints);
2439 EXPECT_TRUE(result != nullptr);
2440 // Expect IPv6 query only. IPv4 answer has been cached in previous query.
2441 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2442 // In AF_UNSPEC case, don't synthesize special use IPv4 address.
2443 std::string result_str = ToString(result);
2444 EXPECT_EQ(result_str, config.addr.c_str());
2445 dns.clearQueries();
2446 }
2447}
2448
2449TEST_F(ResolverTest, GetAddrInfo_Dns64QueryWithNullArgumentHints) {
2450 constexpr char listen_addr[] = "::1";
nuccachenf52f7a52018-07-17 18:07:23 +08002451 constexpr char dns64_name[] = "ipv4only.arpa.";
2452 constexpr char host_name[] = "v4only.example.com.";
2453 constexpr char host_name2[] = "v4v6.example.com.";
Xiao Ma7c75f452018-12-11 17:56:32 +09002454 const std::vector<DnsRecord> records = {
2455 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2456 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2457 {host_name2, ns_type::ns_t_a, "1.2.3.4"},
2458 {host_name2, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
2459 };
nuccachenf52f7a52018-07-17 18:07:23 +08002460
Xiao Ma7c75f452018-12-11 17:56:32 +09002461 test::DNSResponder dns(listen_addr);
2462 StartDns(dns, records);
nuccachenf52f7a52018-07-17 18:07:23 +08002463 const std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09002464 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachenf52f7a52018-07-17 18:07:23 +08002465
2466 // Wait for detecting prefix to complete.
2467 EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
2468
2469 // Assign argument hints of getaddrinfo() as null is equivalent to set ai_family AF_UNSPEC.
2470 // In AF_UNSPEC case, synthesize AAAA if there has A answer only.
2471 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, nullptr);
2472 EXPECT_TRUE(result != nullptr);
2473 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2474 std::string result_str = ToString(result);
2475 EXPECT_EQ(result_str, "64:ff9b::102:304");
2476 dns.clearQueries();
2477
2478 // In AF_UNSPEC case, do not synthesize AAAA if there's at least one AAAA answer.
2479 result = safe_getaddrinfo("v4v6", nullptr, nullptr);
2480 EXPECT_TRUE(result != nullptr);
2481 EXPECT_LE(2U, GetNumQueries(dns, host_name2));
2482 std::vector<std::string> result_strs = ToStrings(result);
2483 for (const auto& str : result_strs) {
2484 EXPECT_TRUE(str == "1.2.3.4" || str == "2001:db8::102:304")
2485 << ", result_str='" << str << "'";
2486 }
2487}
2488
2489TEST_F(ResolverTest, GetAddrInfo_Dns64QueryNullArgumentNode) {
2490 constexpr char ADDR_ANYADDR_V4[] = "0.0.0.0";
2491 constexpr char ADDR_ANYADDR_V6[] = "::";
2492 constexpr char ADDR_LOCALHOST_V4[] = "127.0.0.1";
2493 constexpr char ADDR_LOCALHOST_V6[] = "::1";
2494
2495 constexpr char PORT_NAME_HTTP[] = "http";
2496 constexpr char PORT_NUMBER_HTTP[] = "80";
2497
2498 constexpr char listen_addr[] = "::1";
nuccachenf52f7a52018-07-17 18:07:23 +08002499 constexpr char dns64_name[] = "ipv4only.arpa.";
2500
Xiao Ma7c75f452018-12-11 17:56:32 +09002501 test::DNSResponder dns(listen_addr);
2502 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachenf52f7a52018-07-17 18:07:23 +08002503 const std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09002504 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachenf52f7a52018-07-17 18:07:23 +08002505
2506 // Wait for detecting prefix to complete.
2507 EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
2508
2509 // If node is null, return address is listed by libc/getaddrinfo.c as follows.
2510 // - passive socket -> anyaddr (0.0.0.0 or ::)
2511 // - non-passive socket -> localhost (127.0.0.1 or ::1)
2512 static const struct TestConfig {
2513 int flag;
2514 std::string addr_v4;
2515 std::string addr_v6;
2516
2517 std::string asParameters() const {
2518 return StringPrintf("flag=%d, addr_v4=%s, addr_v6=%s", flag, addr_v4.c_str(),
2519 addr_v6.c_str());
2520 }
2521 } testConfigs[]{
2522 {0 /* non-passive */, ADDR_LOCALHOST_V4, ADDR_LOCALHOST_V6},
2523 {AI_PASSIVE, ADDR_ANYADDR_V4, ADDR_ANYADDR_V6}
2524 };
2525
2526 for (const auto& config : testConfigs) {
2527 SCOPED_TRACE(config.asParameters());
2528
Xiao Ma7c75f452018-12-11 17:56:32 +09002529 addrinfo hints = {
2530 .ai_family = AF_UNSPEC, // any address family
2531 .ai_socktype = 0, // any type
2532 .ai_protocol = 0, // any protocol
2533 .ai_flags = config.flag,
2534 };
nuccachenf52f7a52018-07-17 18:07:23 +08002535
2536 // Assign hostname as null and service as port name.
2537 ScopedAddrinfo result = safe_getaddrinfo(nullptr, PORT_NAME_HTTP, &hints);
2538 ASSERT_TRUE(result != nullptr);
2539
2540 // Can't be synthesized because it should not get into Netd.
2541 std::vector<std::string> result_strs = ToStrings(result);
2542 for (const auto& str : result_strs) {
2543 EXPECT_TRUE(str == config.addr_v4 || str == config.addr_v6)
2544 << ", result_str='" << str << "'";
2545 }
2546
2547 // Assign hostname as null and service as numeric port number.
2548 hints.ai_flags = config.flag | AI_NUMERICSERV;
2549 result = safe_getaddrinfo(nullptr, PORT_NUMBER_HTTP, &hints);
2550 ASSERT_TRUE(result != nullptr);
2551
2552 // Can't be synthesized because it should not get into Netd.
2553 result_strs = ToStrings(result);
2554 for (const auto& str : result_strs) {
2555 EXPECT_TRUE(str == config.addr_v4 || str == config.addr_v6)
2556 << ", result_str='" << str << "'";
2557 }
2558 }
2559}
2560
2561TEST_F(ResolverTest, GetHostByAddr_ReverseDnsQueryWithHavingNat64Prefix) {
2562 struct hostent* result = nullptr;
2563 struct in_addr v4addr;
2564 struct in6_addr v6addr;
2565
2566 constexpr char listen_addr[] = "::1";
nuccachenf52f7a52018-07-17 18:07:23 +08002567 constexpr char dns64_name[] = "ipv4only.arpa.";
2568 constexpr char ptr_name[] = "v4v6.example.com.";
2569 // PTR record for IPv4 address 1.2.3.4
2570 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2571 // PTR record for IPv6 address 2001:db8::102:304
2572 constexpr char ptr_addr_v6[] =
2573 "4.0.3.0.2.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.";
Xiao Ma7c75f452018-12-11 17:56:32 +09002574 const std::vector<DnsRecord> records = {
2575 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2576 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2577 {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name},
2578 };
nuccachenf52f7a52018-07-17 18:07:23 +08002579
Xiao Ma7c75f452018-12-11 17:56:32 +09002580 test::DNSResponder dns(listen_addr);
2581 StartDns(dns, records);
nuccachenf52f7a52018-07-17 18:07:23 +08002582 const std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09002583 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachenf52f7a52018-07-17 18:07:23 +08002584
2585 // Wait for detecting prefix to complete.
2586 EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
2587
2588 // Reverse IPv4 DNS query. Prefix should have no effect on it.
2589 inet_pton(AF_INET, "1.2.3.4", &v4addr);
2590 result = gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET);
2591 ASSERT_TRUE(result != nullptr);
2592 std::string result_str = result->h_name ? result->h_name : "null";
2593 EXPECT_EQ(result_str, "v4v6.example.com");
2594
2595 // Reverse IPv6 DNS query. Prefix should have no effect on it.
2596 inet_pton(AF_INET6, "2001:db8::102:304", &v6addr);
2597 result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2598 ASSERT_TRUE(result != nullptr);
2599 result_str = result->h_name ? result->h_name : "null";
2600 EXPECT_EQ(result_str, "v4v6.example.com");
2601}
2602
2603TEST_F(ResolverTest, GetHostByAddr_ReverseDns64Query) {
2604 constexpr char listen_addr[] = "::1";
nuccachenf52f7a52018-07-17 18:07:23 +08002605 constexpr char dns64_name[] = "ipv4only.arpa.";
2606 constexpr char ptr_name[] = "v4only.example.com.";
2607 // PTR record for IPv4 address 1.2.3.4
2608 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2609 // PTR record for IPv6 address 64:ff9b::1.2.3.4
2610 constexpr char ptr_addr_v6_nomapping[] =
2611 "4.0.3.0.2.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.b.9.f.f.4.6.0.0.ip6.arpa.";
2612 constexpr char ptr_name_v6_synthesis[] = "v6synthesis.example.com.";
2613 // PTR record for IPv6 address 64:ff9b::5.6.7.8
2614 constexpr char ptr_addr_v6_synthesis[] =
2615 "8.0.7.0.6.0.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.b.9.f.f.4.6.0.0.ip6.arpa.";
Xiao Ma7c75f452018-12-11 17:56:32 +09002616 const std::vector<DnsRecord> records = {
2617 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2618 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2619 {ptr_addr_v6_synthesis, ns_type::ns_t_ptr, ptr_name_v6_synthesis},
2620 };
nuccachenf52f7a52018-07-17 18:07:23 +08002621
Xiao Ma7c75f452018-12-11 17:56:32 +09002622 test::DNSResponder dns(listen_addr);
2623 StartDns(dns, records);
nuccachenf52f7a52018-07-17 18:07:23 +08002624 // "ptr_addr_v6_nomapping" is not mapped in DNS server
nuccachenf52f7a52018-07-17 18:07:23 +08002625 const std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09002626 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachenf52f7a52018-07-17 18:07:23 +08002627
2628 // Wait for detecting prefix to complete.
2629 EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
2630
2631 // Synthesized PTR record doesn't exist on DNS server
2632 // Reverse IPv6 DNS64 query while DNS server doesn't have an answer for synthesized address.
2633 // After querying synthesized address failed, expect that prefix is removed from IPv6
2634 // synthesized address and do reverse IPv4 query instead.
2635 struct in6_addr v6addr;
2636 inet_pton(AF_INET6, "64:ff9b::1.2.3.4", &v6addr);
2637 struct hostent* result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2638 ASSERT_TRUE(result != nullptr);
2639 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_nomapping)); // PTR record not exist
2640 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4)); // PTR record exist
2641 std::string result_str = result->h_name ? result->h_name : "null";
2642 EXPECT_EQ(result_str, "v4only.example.com");
2643 // Check that return address has been mapped from IPv4 to IPv6 address because Netd
2644 // removes NAT64 prefix and does IPv4 DNS reverse lookup in this case. Then, Netd
2645 // fakes the return IPv4 address as original queried IPv6 address.
2646 result_str = ToString(result);
2647 EXPECT_EQ(result_str, "64:ff9b::102:304");
2648 dns.clearQueries();
2649
2650 // Synthesized PTR record exists on DNS server
2651 // Reverse IPv6 DNS64 query while DNS server has an answer for synthesized address.
2652 // Expect to Netd pass through synthesized address for DNS queries.
2653 inet_pton(AF_INET6, "64:ff9b::5.6.7.8", &v6addr);
2654 result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2655 ASSERT_TRUE(result != nullptr);
2656 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_synthesis));
2657 result_str = result->h_name ? result->h_name : "null";
2658 EXPECT_EQ(result_str, "v6synthesis.example.com");
2659}
2660
2661TEST_F(ResolverTest, GetHostByAddr_ReverseDns64QueryFromHostFile) {
2662 constexpr char dns64_name[] = "ipv4only.arpa.";
2663 constexpr char host_name[] = "localhost";
2664 // The address is synthesized by prefix64:localhost.
2665 constexpr char host_addr[] = "64:ff9b::7f00:1";
nuccachenf52f7a52018-07-17 18:07:23 +08002666 constexpr char listen_addr[] = "::1";
Xiao Ma7c75f452018-12-11 17:56:32 +09002667
2668 test::DNSResponder dns(listen_addr);
2669 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
nuccachenf52f7a52018-07-17 18:07:23 +08002670 const std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09002671 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachenf52f7a52018-07-17 18:07:23 +08002672
2673 // Wait for detecting prefix to complete.
2674 EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
2675
2676 // Using synthesized "localhost" address to be a trick for resolving host name
2677 // from host file /etc/hosts and "localhost" is the only name in /etc/hosts. Note that this is
2678 // not realistic: the code never synthesizes AAAA records for addresses in 127.0.0.0/8.
2679 struct in6_addr v6addr;
2680 inet_pton(AF_INET6, host_addr, &v6addr);
2681 struct hostent* result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2682 ASSERT_TRUE(result != nullptr);
2683 // Expect no DNS queries; localhost is resolved via /etc/hosts.
2684 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
2685
2686 ASSERT_EQ(sizeof(in6_addr), (unsigned) result->h_length);
2687 ASSERT_EQ(AF_INET6, result->h_addrtype);
2688 std::string result_str = ToString(result);
2689 EXPECT_EQ(result_str, host_addr);
2690 result_str = result->h_name ? result->h_name : "null";
2691 EXPECT_EQ(result_str, host_name);
2692}
2693
2694TEST_F(ResolverTest, GetNameInfo_ReverseDnsQueryWithHavingNat64Prefix) {
2695 constexpr char listen_addr[] = "::1";
nuccachenf52f7a52018-07-17 18:07:23 +08002696 constexpr char dns64_name[] = "ipv4only.arpa.";
2697 constexpr char ptr_name[] = "v4v6.example.com.";
2698 // PTR record for IPv4 address 1.2.3.4
2699 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2700 // PTR record for IPv6 address 2001:db8::102:304
2701 constexpr char ptr_addr_v6[] =
2702 "4.0.3.0.2.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.";
Xiao Ma7c75f452018-12-11 17:56:32 +09002703 const std::vector<DnsRecord> records = {
2704 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2705 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2706 {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name},
2707 };
nuccachenf52f7a52018-07-17 18:07:23 +08002708
Xiao Ma7c75f452018-12-11 17:56:32 +09002709 test::DNSResponder dns(listen_addr);
2710 StartDns(dns, records);
nuccachenf52f7a52018-07-17 18:07:23 +08002711 const std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09002712 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachenf52f7a52018-07-17 18:07:23 +08002713
2714 // Wait for detecting prefix to complete.
2715 EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
2716
2717 static const struct TestConfig {
2718 int flag;
2719 int family;
2720 std::string addr;
2721 std::string host;
2722
2723 std::string asParameters() const {
2724 return StringPrintf("flag=%d, family=%d, addr=%s, host=%s", flag, family, addr.c_str(),
2725 host.c_str());
2726 }
2727 } testConfigs[]{
2728 {NI_NAMEREQD, AF_INET, "1.2.3.4", "v4v6.example.com"},
2729 {NI_NUMERICHOST, AF_INET, "1.2.3.4", "1.2.3.4"},
2730 {0, AF_INET, "1.2.3.4", "v4v6.example.com"},
2731 {0, AF_INET, "5.6.7.8", "5.6.7.8"}, // unmapped
2732 {NI_NAMEREQD, AF_INET6, "2001:db8::102:304", "v4v6.example.com"},
2733 {NI_NUMERICHOST, AF_INET6, "2001:db8::102:304", "2001:db8::102:304"},
2734 {0, AF_INET6, "2001:db8::102:304", "v4v6.example.com"},
2735 {0, AF_INET6, "2001:db8::506:708", "2001:db8::506:708"}, // unmapped
2736 };
2737
2738 // Reverse IPv4/IPv6 DNS query. Prefix should have no effect on it.
2739 for (const auto& config : testConfigs) {
2740 SCOPED_TRACE(config.asParameters());
2741
2742 int rv;
2743 char host[NI_MAXHOST];
2744 struct sockaddr_in sin;
2745 struct sockaddr_in6 sin6;
2746 if (config.family == AF_INET) {
2747 memset(&sin, 0, sizeof(sin));
2748 sin.sin_family = AF_INET;
2749 inet_pton(AF_INET, config.addr.c_str(), &sin.sin_addr);
2750 rv = getnameinfo((const struct sockaddr*) &sin, sizeof(sin), host, sizeof(host),
2751 nullptr, 0, config.flag);
2752 if (config.flag == NI_NAMEREQD) EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4));
2753 } else if (config.family == AF_INET6) {
2754 memset(&sin6, 0, sizeof(sin6));
2755 sin6.sin6_family = AF_INET6;
2756 inet_pton(AF_INET6, config.addr.c_str(), &sin6.sin6_addr);
2757 rv = getnameinfo((const struct sockaddr*) &sin6, sizeof(sin6), host, sizeof(host),
2758 nullptr, 0, config.flag);
2759 if (config.flag == NI_NAMEREQD) EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6));
2760 }
2761 ASSERT_EQ(0, rv);
2762 std::string result_str = host;
2763 EXPECT_EQ(result_str, config.host);
2764 dns.clearQueries();
2765 }
2766}
2767
2768TEST_F(ResolverTest, GetNameInfo_ReverseDns64Query) {
2769 constexpr char listen_addr[] = "::1";
nuccachenf52f7a52018-07-17 18:07:23 +08002770 constexpr char dns64_name[] = "ipv4only.arpa.";
2771 constexpr char ptr_name[] = "v4only.example.com.";
2772 // PTR record for IPv4 address 1.2.3.4
2773 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2774 // PTR record for IPv6 address 64:ff9b::1.2.3.4
2775 constexpr char ptr_addr_v6_nomapping[] =
2776 "4.0.3.0.2.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.b.9.f.f.4.6.0.0.ip6.arpa.";
2777 constexpr char ptr_name_v6_synthesis[] = "v6synthesis.example.com.";
2778 // PTR record for IPv6 address 64:ff9b::5.6.7.8
2779 constexpr char ptr_addr_v6_synthesis[] =
2780 "8.0.7.0.6.0.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.b.9.f.f.4.6.0.0.ip6.arpa.";
Xiao Ma7c75f452018-12-11 17:56:32 +09002781 const std::vector<DnsRecord> records = {
2782 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2783 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2784 {ptr_addr_v6_synthesis, ns_type::ns_t_ptr, ptr_name_v6_synthesis},
2785 };
nuccachenf52f7a52018-07-17 18:07:23 +08002786
Xiao Ma7c75f452018-12-11 17:56:32 +09002787 test::DNSResponder dns(listen_addr);
2788 StartDns(dns, records);
nuccachenf52f7a52018-07-17 18:07:23 +08002789 const std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09002790 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachenf52f7a52018-07-17 18:07:23 +08002791
2792 // Wait for detecting prefix to complete.
2793 EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
2794
2795 static const struct TestConfig {
2796 bool hasSynthesizedPtrRecord;
2797 int flag;
2798 std::string addr;
2799 std::string host;
2800
2801 std::string asParameters() const {
2802 return StringPrintf("hasSynthesizedPtrRecord=%d, flag=%d, addr=%s, host=%s",
2803 hasSynthesizedPtrRecord, flag, addr.c_str(), host.c_str());
2804 }
2805 } testConfigs[]{
2806 {false, NI_NAMEREQD, "64:ff9b::102:304", "v4only.example.com"},
2807 {false, NI_NUMERICHOST, "64:ff9b::102:304", "64:ff9b::102:304"},
2808 {false, 0, "64:ff9b::102:304", "v4only.example.com"},
2809 {true, NI_NAMEREQD, "64:ff9b::506:708", "v6synthesis.example.com"},
2810 {true, NI_NUMERICHOST, "64:ff9b::506:708", "64:ff9b::506:708"},
2811 {true, 0, "64:ff9b::506:708", "v6synthesis.example.com"}
2812 };
2813
2814 // hasSynthesizedPtrRecord = false
2815 // Synthesized PTR record doesn't exist on DNS server
2816 // Reverse IPv6 DNS64 query while DNS server doesn't have an answer for synthesized address.
2817 // After querying synthesized address failed, expect that prefix is removed from IPv6
2818 // synthesized address and do reverse IPv4 query instead.
2819 //
2820 // hasSynthesizedPtrRecord = true
2821 // Synthesized PTR record exists on DNS server
2822 // Reverse IPv6 DNS64 query while DNS server has an answer for synthesized address.
2823 // Expect to just pass through synthesized address for DNS queries.
2824 for (const auto& config : testConfigs) {
2825 SCOPED_TRACE(config.asParameters());
2826
2827 char host[NI_MAXHOST];
2828 struct sockaddr_in6 sin6;
2829 memset(&sin6, 0, sizeof(sin6));
2830 sin6.sin6_family = AF_INET6;
2831 inet_pton(AF_INET6, config.addr.c_str(), &sin6.sin6_addr);
2832 int rv = getnameinfo((const struct sockaddr*) &sin6, sizeof(sin6), host, sizeof(host),
2833 nullptr, 0, config.flag);
2834 ASSERT_EQ(0, rv);
2835 if (config.flag == NI_NAMEREQD) {
2836 if (config.hasSynthesizedPtrRecord) {
2837 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_synthesis));
2838 } else {
2839 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_nomapping)); // PTR record not exist.
2840 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4)); // PTR record exist.
2841 }
2842 }
2843 std::string result_str = host;
2844 EXPECT_EQ(result_str, config.host);
2845 dns.clearQueries();
2846 }
2847}
2848
2849TEST_F(ResolverTest, GetNameInfo_ReverseDns64QueryFromHostFile) {
2850 constexpr char dns64_name[] = "ipv4only.arpa.";
2851 constexpr char host_name[] = "localhost";
2852 // The address is synthesized by prefix64:localhost.
2853 constexpr char host_addr[] = "64:ff9b::7f00:1";
nuccachenf52f7a52018-07-17 18:07:23 +08002854 constexpr char listen_addr[] = "::1";
Xiao Ma7c75f452018-12-11 17:56:32 +09002855
2856 test::DNSResponder dns(listen_addr);
2857 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
nuccachenf52f7a52018-07-17 18:07:23 +08002858 const std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09002859 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachenf52f7a52018-07-17 18:07:23 +08002860
2861 // Wait for detecting prefix to complete.
2862 EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
2863
2864 // Using synthesized "localhost" address to be a trick for resolving host name
2865 // from host file /etc/hosts and "localhost" is the only name in /etc/hosts. Note that this is
2866 // not realistic: the code never synthesizes AAAA records for addresses in 127.0.0.0/8.
2867 char host[NI_MAXHOST];
Xiao Ma7c75f452018-12-11 17:56:32 +09002868 struct sockaddr_in6 sin6 = {.sin6_family = AF_INET6};
nuccachenf52f7a52018-07-17 18:07:23 +08002869 inet_pton(AF_INET6, host_addr, &sin6.sin6_addr);
2870 int rv = getnameinfo((const struct sockaddr*) &sin6, sizeof(sin6), host, sizeof(host), nullptr,
2871 0, NI_NAMEREQD);
2872 ASSERT_EQ(0, rv);
2873 // Expect no DNS queries; localhost is resolved via /etc/hosts.
2874 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
2875
2876 std::string result_str = host;
2877 EXPECT_EQ(result_str, host_name);
2878}
2879
nuccachenf52f7a52018-07-17 18:07:23 +08002880TEST_F(ResolverTest, GetHostByName2_Dns64Synthesize) {
Xiao Ma7c75f452018-12-11 17:56:32 +09002881 constexpr char listen_addr[] = "::1";
nuccachenf52f7a52018-07-17 18:07:23 +08002882 constexpr char dns64_name[] = "ipv4only.arpa.";
2883 constexpr char host_name[] = "ipv4only.example.com.";
Xiao Ma7c75f452018-12-11 17:56:32 +09002884 const std::vector<DnsRecord> records = {
2885 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2886 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2887 };
nuccachenf52f7a52018-07-17 18:07:23 +08002888
Xiao Ma7c75f452018-12-11 17:56:32 +09002889 test::DNSResponder dns(listen_addr);
2890 StartDns(dns, records);
nuccachenf52f7a52018-07-17 18:07:23 +08002891 const std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09002892 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachenf52f7a52018-07-17 18:07:23 +08002893
2894 // Wait for detecting prefix to complete.
2895 EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
2896
2897 // Query an IPv4-only hostname. Expect that gets a synthesized address.
2898 struct hostent* result = gethostbyname2("ipv4only", AF_INET6);
2899 ASSERT_TRUE(result != nullptr);
2900 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2901 std::string result_str = ToString(result);
2902 EXPECT_EQ(result_str, "64:ff9b::102:304");
2903}
nuccachenf52f7a52018-07-17 18:07:23 +08002904
2905TEST_F(ResolverTest, GetHostByName2_DnsQueryWithHavingNat64Prefix) {
2906 constexpr char dns64_name[] = "ipv4only.arpa.";
2907 constexpr char host_name[] = "v4v6.example.com.";
nuccachenf52f7a52018-07-17 18:07:23 +08002908 constexpr char listen_addr[] = "::1";
Xiao Ma7c75f452018-12-11 17:56:32 +09002909 const std::vector<DnsRecord> records = {
2910 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2911 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2912 {host_name, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
2913 };
2914
2915 test::DNSResponder dns(listen_addr);
2916 StartDns(dns, records);
nuccachenf52f7a52018-07-17 18:07:23 +08002917 const std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09002918 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachenf52f7a52018-07-17 18:07:23 +08002919
2920 // Wait for detecting prefix to complete.
2921 EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
2922
2923 // IPv4 DNS query. Prefix should have no effect on it.
2924 struct hostent* result = gethostbyname2("v4v6", AF_INET);
2925 ASSERT_TRUE(result != nullptr);
2926 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2927 std::string result_str = ToString(result);
2928 EXPECT_EQ(result_str, "1.2.3.4");
2929 dns.clearQueries();
2930
2931 // IPv6 DNS query. Prefix should have no effect on it.
2932 result = gethostbyname2("v4v6", AF_INET6);
2933 ASSERT_TRUE(result != nullptr);
2934 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2935 result_str = ToString(result);
2936 EXPECT_EQ(result_str, "2001:db8::102:304");
2937}
2938
2939TEST_F(ResolverTest, GetHostByName2_Dns64QuerySpecialUseIPv4Addresses) {
2940 constexpr char THIS_NETWORK[] = "this_network";
2941 constexpr char LOOPBACK[] = "loopback";
2942 constexpr char LINK_LOCAL[] = "link_local";
2943 constexpr char MULTICAST[] = "multicast";
2944 constexpr char LIMITED_BROADCAST[] = "limited_broadcast";
2945
2946 constexpr char ADDR_THIS_NETWORK[] = "0.0.0.1";
2947 constexpr char ADDR_LOOPBACK[] = "127.0.0.1";
2948 constexpr char ADDR_LINK_LOCAL[] = "169.254.0.1";
2949 constexpr char ADDR_MULTICAST[] = "224.0.0.1";
2950 constexpr char ADDR_LIMITED_BROADCAST[] = "255.255.255.255";
2951
2952 constexpr char listen_addr[] = "::1";
nuccachenf52f7a52018-07-17 18:07:23 +08002953 constexpr char dns64_name[] = "ipv4only.arpa.";
2954
Xiao Ma7c75f452018-12-11 17:56:32 +09002955 test::DNSResponder dns(listen_addr);
2956 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachenf52f7a52018-07-17 18:07:23 +08002957 const std::vector<std::string> servers = {listen_addr};
Xiao Ma7c75f452018-12-11 17:56:32 +09002958 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachenf52f7a52018-07-17 18:07:23 +08002959
2960 // Wait for detecting prefix to complete.
2961 EXPECT_TRUE(WaitForPrefix64Detected(TEST_NETID, 1000));
2962
2963 static const struct TestConfig {
2964 std::string name;
2965 std::string addr;
2966
2967 std::string asHostName() const {
2968 return StringPrintf("%s.example.com.",
2969 name.c_str());
2970 }
2971 } testConfigs[]{
2972 {THIS_NETWORK, ADDR_THIS_NETWORK},
2973 {LOOPBACK, ADDR_LOOPBACK},
2974 {LINK_LOCAL, ADDR_LINK_LOCAL},
2975 {MULTICAST, ADDR_MULTICAST},
2976 {LIMITED_BROADCAST, ADDR_LIMITED_BROADCAST}
2977 };
2978
2979 for (const auto& config : testConfigs) {
2980 const std::string testHostName = config.asHostName();
2981 SCOPED_TRACE(testHostName);
2982
2983 const char* host_name = testHostName.c_str();
2984 dns.addMapping(host_name, ns_type::ns_t_a, config.addr.c_str());
2985
2986 struct hostent* result = gethostbyname2(config.name.c_str(), AF_INET6);
2987 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2988
2989 // In AF_INET6 case, don't synthesize special use IPv4 address.
2990 // Expect to have no answer
2991 EXPECT_EQ(nullptr, result);
2992
2993 dns.clearQueries();
2994 }
Bernie Innocenticd257642018-12-20 15:56:40 +09002995}