blob: e68fab69260c6e1ea2828c9de36c3a00e2059641 [file] [log] [blame]
Ken Chenb9fa2062018-11-13 21:51:13 +08001/*
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 *
Lorenzo Colitti0a8b4aa2019-06-26 22:31:03 +090010 * Unless required by applicable law or agreed to in writing, software
Ken Chenb9fa2062018-11-13 21:51:13 +080011 * 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 Innocenti3952ccc2019-03-03 19:39:53 +090018#define LOG_TAG "resolv_integration_test"
Ken Chenb9fa2062018-11-13 21:51:13 +080019
Hungming Chen5bf09772019-04-25 11:16:13 +080020#include <android-base/logging.h>
Bernie Innocenti41b82c42019-06-05 22:38:25 +090021#include <android-base/parseint.h>
Mike Yu40e67072019-10-09 21:14:09 +080022#include <android-base/properties.h>
Bernie Innocenti41b82c42019-06-05 22:38:25 +090023#include <android-base/stringprintf.h>
24#include <android-base/unique_fd.h>
25#include <android/multinetwork.h> // ResNsendFlags
Ken Chenb9fa2062018-11-13 21:51:13 +080026#include <arpa/inet.h>
Luke Huang94b10b92018-11-21 20:13:38 +080027#include <arpa/nameser.h>
Hungming Chene8f970c2019-04-10 17:34:06 +080028#include <binder/ProcessState.h>
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +090029#include <bpf/BpfUtils.h>
Bernie Innocenti41b82c42019-06-05 22:38:25 +090030#include <cutils/sockets.h>
31#include <gmock/gmock-matchers.h>
32#include <gtest/gtest.h>
Ken Chenb9fa2062018-11-13 21:51:13 +080033#include <netdb.h>
Luke Huang9d2d25b2019-06-14 00:34:05 +080034#include <netdutils/InternetAddresses.h>
Luke Huang579ddc72019-06-14 00:59:39 +080035#include <netdutils/NetworkConstants.h> // SHA256_SIZE
Luke Huang9d2d25b2019-06-14 00:34:05 +080036#include <netdutils/ResponseCode.h>
Hungming Chen63779052019-10-30 15:06:13 +080037#include <netdutils/Slice.h>
Luke Huang9d2d25b2019-06-14 00:34:05 +080038#include <netdutils/SocketOption.h>
Mike Yu40e67072019-10-09 21:14:09 +080039#include <netdutils/Stopwatch.h>
Luke Huang94b10b92018-11-21 20:13:38 +080040#include <netinet/in.h>
Bernie Innocenti41b82c42019-06-05 22:38:25 +090041#include <openssl/base64.h>
Luke Huang94b10b92018-11-21 20:13:38 +080042#include <poll.h> /* poll */
Bernie Innocenti41b82c42019-06-05 22:38:25 +090043#include <private/android_filesystem_config.h>
Luke Huang94b10b92018-11-21 20:13:38 +080044#include <resolv.h>
Ken Chenb9fa2062018-11-13 21:51:13 +080045#include <stdarg.h>
Ken Chenb9fa2062018-11-13 21:51:13 +080046#include <stdlib.h>
Luke Huang94b10b92018-11-21 20:13:38 +080047#include <sys/socket.h>
48#include <sys/un.h>
Ken Chenb9fa2062018-11-13 21:51:13 +080049#include <unistd.h>
50
51#include <algorithm>
52#include <chrono>
53#include <iterator>
54#include <numeric>
55#include <thread>
56
Luke Huangf8215372019-11-22 11:53:41 +080057#include <aidl/android/net/IDnsResolver.h>
58#include <android/binder_manager.h>
59#include <android/binder_process.h>
Bernie Innocenti41b82c42019-06-05 22:38:25 +090060#include "NetdClient.h"
Bernie Innocenti41b82c42019-06-05 22:38:25 +090061#include "ResolverStats.h"
Luke Huangf8215372019-11-22 11:53:41 +080062#include "netid_client.h" // NETID_UNSET
63#include "params.h" // MAXNS
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +090064#include "test_utils.h"
Hungming Chene8f970c2019-04-10 17:34:06 +080065#include "tests/dns_metrics_listener/dns_metrics_listener.h"
chenbruceb43ec752019-07-24 20:19:41 +080066#include "tests/dns_responder/dns_responder.h"
Luke Huangf8215372019-11-22 11:53:41 +080067#include "tests/dns_responder/dns_responder_client_ndk.h"
chenbruceb43ec752019-07-24 20:19:41 +080068#include "tests/dns_responder/dns_tls_frontend.h"
Luke Huangfde82482019-06-04 01:04:53 +080069#include "tests/resolv_test_utils.h"
Ken Chenb9fa2062018-11-13 21:51:13 +080070
Luke Huang0d592bc2019-05-25 18:24:03 +080071// Valid VPN netId range is 100 ~ 65535
72constexpr int TEST_VPN_NETID = 65502;
Luke Huang94b10b92018-11-21 20:13:38 +080073constexpr int MAXPACKET = (8 * 1024);
Ken Chenb9fa2062018-11-13 21:51:13 +080074
Sehee Park2c118782019-05-07 13:02:45 +090075// Use maximum reserved appId for applications to avoid conflict with existing uids.
76static const int TEST_UID = 99999;
77
waynema0e73c2e2019-07-31 15:04:08 +080078// Currently the hostname of TLS server must match the CN filed on the server's certificate.
79// Inject a test CA whose hostname is "example.com" for DNS-OVER-TLS tests.
80static const std::string kDefaultPrivateDnsHostName = "example.com";
81static const std::string kDefaultIncorrectPrivateDnsHostName = "www.example.com";
82
Ken Chenb9fa2062018-11-13 21:51:13 +080083// Semi-public Bionic hook used by the NDK (frameworks/base/native/android/net.c)
84// Tested here for convenience.
85extern "C" int android_getaddrinfofornet(const char* hostname, const char* servname,
86 const addrinfo* hints, unsigned netid, unsigned mark,
87 struct addrinfo** result);
88
Luke Huangf8215372019-11-22 11:53:41 +080089using aidl::android::net::INetd;
Luke Huang9807e6b2019-05-20 16:17:12 +080090using android::base::ParseInt;
Ken Chenb9fa2062018-11-13 21:51:13 +080091using android::base::StringPrintf;
Luke Huang9807e6b2019-05-20 16:17:12 +080092using android::base::unique_fd;
Ken Chenb9fa2062018-11-13 21:51:13 +080093using android::net::ResolverStats;
Hungming Chene8f970c2019-04-10 17:34:06 +080094using android::net::metrics::DnsMetricsListener;
Ken Chenb9fa2062018-11-13 21:51:13 +080095using android::netdutils::enableSockopt;
Hungming Chen63779052019-10-30 15:06:13 +080096using android::netdutils::makeSlice;
Luke Huang9807e6b2019-05-20 16:17:12 +080097using android::netdutils::ResponseCode;
Luke Huang9d2d25b2019-06-14 00:34:05 +080098using android::netdutils::ScopedAddrinfo;
Mike Yu40e67072019-10-09 21:14:09 +080099using android::netdutils::Stopwatch;
Hungming Chen63779052019-10-30 15:06:13 +0800100using android::netdutils::toHex;
Ken Chenb9fa2062018-11-13 21:51:13 +0800101
102// TODO: move into libnetdutils?
103namespace {
Luke Huangfde82482019-06-04 01:04:53 +0800104
Ken Chenb9fa2062018-11-13 21:51:13 +0800105ScopedAddrinfo safe_getaddrinfo(const char* node, const char* service,
106 const struct addrinfo* hints) {
107 addrinfo* result = nullptr;
108 if (getaddrinfo(node, service, hints, &result) != 0) {
109 result = nullptr; // Should already be the case, but...
110 }
111 return ScopedAddrinfo(result);
112}
Luke Huangfde82482019-06-04 01:04:53 +0800113
Mike Yu40e67072019-10-09 21:14:09 +0800114std::pair<ScopedAddrinfo, int> safe_getaddrinfo_time_taken(const char* node, const char* service,
115 const addrinfo& hints) {
116 Stopwatch s;
117 ScopedAddrinfo result = safe_getaddrinfo(node, service, &hints);
118 return {std::move(result), s.timeTakenUs() / 1000};
119}
120
Ken Chenb9fa2062018-11-13 21:51:13 +0800121} // namespace
122
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900123class ResolverTest : public ::testing::Test {
Hungming Chene8f970c2019-04-10 17:34:06 +0800124 public:
Hungming Chen5bf09772019-04-25 11:16:13 +0800125 static void SetUpTestCase() {
126 // Get binder service.
127 // Note that |mDnsClient| is not used for getting binder service in this static function.
128 // The reason is that wants to keep |mDnsClient| as a non-static data member. |mDnsClient|
129 // which sets up device network configuration could be independent from every test.
Luke Huangf8215372019-11-22 11:53:41 +0800130 // TODO: Perhaps add a static function in resolv_test_binder_utils.{cpp,h} to get binder
131 // service.
132
133 AIBinder* binder = AServiceManager_getService("dnsresolver");
134 ndk::SpAIBinder resolvBinder = ndk::SpAIBinder(binder);
135 auto resolvService = aidl::android::net::IDnsResolver::fromBinder(resolvBinder);
Hungming Chen5bf09772019-04-25 11:16:13 +0800136 ASSERT_NE(nullptr, resolvService.get());
137
138 // Subscribe the death recipient to the service IDnsResolver for detecting Netd death.
Luke Huangf8215372019-11-22 11:53:41 +0800139 sResolvDeathRecipient = AIBinder_DeathRecipient_new([](void*) {
140 constexpr char errorMessage[] = "Netd died";
141 LOG(ERROR) << errorMessage;
142 GTEST_LOG_(FATAL) << errorMessage;
143 });
144 ASSERT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, sResolvDeathRecipient, nullptr));
Hungming Chen5bf09772019-04-25 11:16:13 +0800145
146 // Subscribe the DNS listener for verifying DNS metrics event contents.
Luke Huangf8215372019-11-22 11:53:41 +0800147 sDnsMetricsListener = ndk::SharedRefBase::make<DnsMetricsListener>(
148 TEST_NETID /*monitor specific network*/);
Hungming Chen5bf09772019-04-25 11:16:13 +0800149 ASSERT_TRUE(resolvService->registerEventListener(sDnsMetricsListener).isOk());
150
151 // Start the binder thread pool for listening DNS metrics events and receiving death
152 // recipient.
Luke Huangf8215372019-11-22 11:53:41 +0800153 ABinderProcess_startThreadPool();
Hungming Chene8f970c2019-04-10 17:34:06 +0800154 }
Luke Huangf8215372019-11-22 11:53:41 +0800155 static void TearDownTestCase() { AIBinder_DeathRecipient_delete(sResolvDeathRecipient); }
Hungming Chene8f970c2019-04-10 17:34:06 +0800156
Ken Chenb9fa2062018-11-13 21:51:13 +0800157 protected:
Xiao Ma09b71022018-12-11 17:56:32 +0900158 struct DnsRecord {
159 std::string host_name; // host name
160 ns_type type; // record type
161 std::string addr; // ipv4/v6 address
162 };
163
Hungming Chen5bf09772019-04-25 11:16:13 +0800164 class ResolvDeathRecipient : public android::IBinder::DeathRecipient {
165 public:
166 ~ResolvDeathRecipient() override = default;
Hungming Chene8f970c2019-04-10 17:34:06 +0800167
Hungming Chen5bf09772019-04-25 11:16:13 +0800168 // GTEST assertion macros are not invoked for generating a test failure in the death
169 // recipient because the macros can't indicate failed test if Netd died between tests.
170 // Moreover, continuing testing may have no meaningful after Netd death. Therefore, the
171 // death recipient aborts process by GTEST_LOG_(FATAL) once Netd died.
172 void binderDied(const android::wp<android::IBinder>& /*who*/) override {
Hungming Chen9e6185a2019-06-04 16:09:19 +0800173 constexpr char errorMessage[] = "Netd died";
Hungming Chen5bf09772019-04-25 11:16:13 +0800174 LOG(ERROR) << errorMessage;
175 GTEST_LOG_(FATAL) << errorMessage;
176 }
177 };
Hungming Chene8f970c2019-04-10 17:34:06 +0800178
Hungming Chen5bf09772019-04-25 11:16:13 +0800179 void SetUp() { mDnsClient.SetUp(); }
Hungming Chene8f970c2019-04-10 17:34:06 +0800180 void TearDown() { mDnsClient.TearDown(); }
nuccachena26cc2a2018-07-17 18:07:23 +0800181
Xiao Ma09b71022018-12-11 17:56:32 +0900182 void StartDns(test::DNSResponder& dns, const std::vector<DnsRecord>& records) {
183 for (const auto& r : records) {
184 dns.addMapping(r.host_name, r.type, r.addr);
185 }
186
187 ASSERT_TRUE(dns.startServer());
188 dns.clearQueries();
189 }
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900190
Hungming Chene8f970c2019-04-10 17:34:06 +0800191 bool WaitForNat64Prefix(ExpectNat64PrefixStatus status,
192 std::chrono::milliseconds timeout = std::chrono::milliseconds(1000)) {
Hungming Chen5bf09772019-04-25 11:16:13 +0800193 return sDnsMetricsListener->waitForNat64Prefix(status, timeout);
Hungming Chene8f970c2019-04-10 17:34:06 +0800194 }
195
Mike Yu724f77d2019-08-16 11:14:50 +0800196 bool WaitForPrivateDnsValidation(std::string serverAddr, bool validated) {
197 return sDnsMetricsListener->waitForPrivateDnsValidation(serverAddr, validated);
198 }
199
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900200 DnsResponderClient mDnsClient;
Xiao Ma09b71022018-12-11 17:56:32 +0900201
Hungming Chen5bf09772019-04-25 11:16:13 +0800202 // Use a shared static DNS listener for all tests to avoid registering lots of listeners
203 // which may be released late until process terminated. Currently, registered DNS listener
204 // is removed by binder death notification which is fired when the process hosting an
205 // IBinder has gone away. If every test in ResolverTest registers its DNS listener, Netd
206 // may temporarily hold lots of dead listeners until the unit test process terminates.
207 // TODO: Perhaps add an unregistering listener binder call or fork a listener process which
208 // could be terminated earlier.
Luke Huangf8215372019-11-22 11:53:41 +0800209 static std::shared_ptr<DnsMetricsListener>
210 sDnsMetricsListener; // Initialized in SetUpTestCase.
Hungming Chen5bf09772019-04-25 11:16:13 +0800211
212 // Use a shared static death recipient to monitor the service death. The static death
213 // recipient could monitor the death not only during the test but also between tests.
Luke Huangf8215372019-11-22 11:53:41 +0800214 static AIBinder_DeathRecipient* sResolvDeathRecipient; // Initialized in SetUpTestCase.
Ken Chenb9fa2062018-11-13 21:51:13 +0800215};
216
Hungming Chen5bf09772019-04-25 11:16:13 +0800217// Initialize static member of class.
Luke Huangf8215372019-11-22 11:53:41 +0800218std::shared_ptr<DnsMetricsListener> ResolverTest::sDnsMetricsListener;
219AIBinder_DeathRecipient* ResolverTest::sResolvDeathRecipient;
Hungming Chen5bf09772019-04-25 11:16:13 +0800220
Ken Chenb9fa2062018-11-13 21:51:13 +0800221TEST_F(ResolverTest, GetHostByName) {
Xiao Ma09b71022018-12-11 17:56:32 +0900222 constexpr char nonexistent_host_name[] = "nonexistent.example.com.";
223
224 test::DNSResponder dns;
225 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.3"}});
226 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800227
228 const hostent* result;
Ken Chenb9fa2062018-11-13 21:51:13 +0800229 result = gethostbyname("nonexistent");
230 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, nonexistent_host_name));
231 ASSERT_TRUE(result == nullptr);
232 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
233
234 dns.clearQueries();
235 result = gethostbyname("hello");
Xiao Ma09b71022018-12-11 17:56:32 +0900236 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
Ken Chenb9fa2062018-11-13 21:51:13 +0800237 ASSERT_FALSE(result == nullptr);
238 ASSERT_EQ(4, result->h_length);
239 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
240 EXPECT_EQ("1.2.3.3", ToString(result));
241 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800242}
243
lifr4e4a2e02019-01-29 16:53:51 +0800244TEST_F(ResolverTest, GetHostByName_cnames) {
245 constexpr char host_name[] = "host.example.com.";
246 size_t cnamecount = 0;
247 test::DNSResponder dns;
248
249 const std::vector<DnsRecord> records = {
250 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
251 {"a.example.com.", ns_type::ns_t_cname, "b.example.com."},
252 {"b.example.com.", ns_type::ns_t_cname, "c.example.com."},
253 {"c.example.com.", ns_type::ns_t_cname, "d.example.com."},
254 {"d.example.com.", ns_type::ns_t_cname, "e.example.com."},
255 {"e.example.com.", ns_type::ns_t_cname, host_name},
256 {host_name, ns_type::ns_t_a, "1.2.3.3"},
257 {host_name, ns_type::ns_t_aaaa, "2001:db8::42"},
258 };
259 StartDns(dns, records);
260 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
261
262 // using gethostbyname2() to resolve ipv4 hello.example.com. to 1.2.3.3
263 // Ensure the v4 address and cnames are correct
264 const hostent* result;
265 result = gethostbyname2("hello", AF_INET);
266 ASSERT_FALSE(result == nullptr);
267
268 for (int i = 0; result != nullptr && result->h_aliases[i] != nullptr; i++) {
269 std::string domain_name = records[i].host_name.substr(0, records[i].host_name.size() - 1);
270 EXPECT_EQ(result->h_aliases[i], domain_name);
271 cnamecount++;
272 }
273 // The size of "Non-cname type" record in DNS records is 2
274 ASSERT_EQ(cnamecount, records.size() - 2);
275 ASSERT_EQ(4, result->h_length);
276 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
277 EXPECT_EQ("1.2.3.3", ToString(result));
278 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
279 EXPECT_EQ(1U, dns.queries().size()) << dns.dumpQueries();
280
281 // using gethostbyname2() to resolve ipv6 hello.example.com. to 2001:db8::42
282 // Ensure the v6 address and cnames are correct
283 cnamecount = 0;
284 dns.clearQueries();
285 result = gethostbyname2("hello", AF_INET6);
286 for (unsigned i = 0; result != nullptr && result->h_aliases[i] != nullptr; i++) {
287 std::string domain_name = records[i].host_name.substr(0, records[i].host_name.size() - 1);
288 EXPECT_EQ(result->h_aliases[i], domain_name);
289 cnamecount++;
290 }
291 // The size of "Non-cname type" DNS record in records is 2
292 ASSERT_EQ(cnamecount, records.size() - 2);
293 ASSERT_FALSE(result == nullptr);
294 ASSERT_EQ(16, result->h_length);
295 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
296 EXPECT_EQ("2001:db8::42", ToString(result));
297 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
298}
299
300TEST_F(ResolverTest, GetHostByName_cnamesInfiniteLoop) {
301 test::DNSResponder dns;
302 const std::vector<DnsRecord> records = {
303 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
304 {"a.example.com.", ns_type::ns_t_cname, kHelloExampleCom},
305 };
306 StartDns(dns, records);
307 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
308
309 const hostent* result;
310 result = gethostbyname2("hello", AF_INET);
311 ASSERT_TRUE(result == nullptr);
312
313 dns.clearQueries();
314 result = gethostbyname2("hello", AF_INET6);
315 ASSERT_TRUE(result == nullptr);
316}
317
Ken Chenb9fa2062018-11-13 21:51:13 +0800318TEST_F(ResolverTest, GetHostByName_localhost) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800319 constexpr char name_camelcase[] = "LocalHost";
Ken Chenb9fa2062018-11-13 21:51:13 +0800320 constexpr char name_ip6_dot[] = "ip6-localhost.";
321 constexpr char name_ip6_fqdn[] = "ip6-localhost.example.com.";
322
323 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma09b71022018-12-11 17:56:32 +0900324 test::DNSResponder dns;
325 StartDns(dns, {});
326 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800327
328 // Expect no DNS queries; localhost is resolved via /etc/hosts
Xiao Ma09b71022018-12-11 17:56:32 +0900329 const hostent* result = gethostbyname(kLocalHost);
Ken Chenb9fa2062018-11-13 21:51:13 +0800330 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
331 ASSERT_FALSE(result == nullptr);
332 ASSERT_EQ(4, result->h_length);
333 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900334 EXPECT_EQ(kLocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800335 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
336
337 // Ensure the hosts file resolver ignores case of hostnames
338 result = gethostbyname(name_camelcase);
339 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
340 ASSERT_FALSE(result == nullptr);
341 ASSERT_EQ(4, result->h_length);
342 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900343 EXPECT_EQ(kLocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800344 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
345
346 // The hosts file also contains ip6-localhost, but gethostbyname() won't
chenbruce018fdb22019-06-12 18:08:04 +0800347 // return it. This would be easy to
Ken Chenb9fa2062018-11-13 21:51:13 +0800348 // change, but there's no point in changing the legacy behavior; new code
349 // should be calling getaddrinfo() anyway.
350 // So we check the legacy behavior, which results in amusing A-record
351 // lookups for ip6-localhost, with and without search domains appended.
352 dns.clearQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900353 result = gethostbyname(kIp6LocalHost);
Sehee Parkbbca0202018-11-16 10:53:16 +0900354 EXPECT_EQ(2U, dns.queries().size()) << dns.dumpQueries();
355 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, name_ip6_dot)) << dns.dumpQueries();
356 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, name_ip6_fqdn)) << dns.dumpQueries();
Ken Chenb9fa2062018-11-13 21:51:13 +0800357 ASSERT_TRUE(result == nullptr);
358
359 // Finally, use gethostbyname2() to resolve ip6-localhost to ::1 from
360 // the hosts file.
361 dns.clearQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900362 result = gethostbyname2(kIp6LocalHost, AF_INET6);
Ken Chenb9fa2062018-11-13 21:51:13 +0800363 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
364 ASSERT_FALSE(result == nullptr);
365 ASSERT_EQ(16, result->h_length);
366 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900367 EXPECT_EQ(kIp6LocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800368 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800369}
370
371TEST_F(ResolverTest, GetHostByName_numeric) {
372 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma09b71022018-12-11 17:56:32 +0900373 test::DNSResponder dns;
374 StartDns(dns, {});
375 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800376
377 // Numeric v4 address: expect no DNS queries
378 constexpr char numeric_v4[] = "192.168.0.1";
Ken Chenb9fa2062018-11-13 21:51:13 +0800379 const hostent* result = gethostbyname(numeric_v4);
Sehee Parkbbca0202018-11-16 10:53:16 +0900380 EXPECT_EQ(0U, dns.queries().size());
Ken Chenb9fa2062018-11-13 21:51:13 +0800381 ASSERT_FALSE(result == nullptr);
382 ASSERT_EQ(4, result->h_length); // v4
383 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
384 EXPECT_EQ(numeric_v4, ToString(result));
385 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
386
387 // gethostbyname() recognizes a v6 address, and fails with no DNS queries
388 constexpr char numeric_v6[] = "2001:db8::42";
389 dns.clearQueries();
390 result = gethostbyname(numeric_v6);
Sehee Parkbbca0202018-11-16 10:53:16 +0900391 EXPECT_EQ(0U, dns.queries().size());
Ken Chenb9fa2062018-11-13 21:51:13 +0800392 EXPECT_TRUE(result == nullptr);
393
394 // Numeric v6 address with gethostbyname2(): succeeds with no DNS queries
395 dns.clearQueries();
396 result = gethostbyname2(numeric_v6, AF_INET6);
Sehee Parkbbca0202018-11-16 10:53:16 +0900397 EXPECT_EQ(0U, dns.queries().size());
Ken Chenb9fa2062018-11-13 21:51:13 +0800398 ASSERT_FALSE(result == nullptr);
399 ASSERT_EQ(16, result->h_length); // v6
400 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
401 EXPECT_EQ(numeric_v6, ToString(result));
402 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
403
404 // Numeric v6 address with scope work with getaddrinfo(),
405 // but gethostbyname2() does not understand them; it issues two dns
406 // queries, then fails. This hardly ever happens, there's no point
407 // in fixing this. This test simply verifies the current (bogus)
408 // behavior to avoid further regressions (like crashes, or leaks).
409 constexpr char numeric_v6_scope[] = "fe80::1%lo";
410 dns.clearQueries();
411 result = gethostbyname2(numeric_v6_scope, AF_INET6);
Sehee Parkbbca0202018-11-16 10:53:16 +0900412 EXPECT_EQ(2U, dns.queries().size()); // OUCH!
Ken Chenb9fa2062018-11-13 21:51:13 +0800413 ASSERT_TRUE(result == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800414}
415
416TEST_F(ResolverTest, BinderSerialization) {
Luke Huangf8215372019-11-22 11:53:41 +0800417 using aidl::android::net::IDnsResolver;
Ken Chenb9fa2062018-11-13 21:51:13 +0800418 std::vector<int> params_offsets = {
Luke Huang5bd827c2019-03-14 16:10:04 +0800419 IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY,
420 IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD,
421 IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES,
422 IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES,
423 IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC,
424 IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT,
Ken Chenb9fa2062018-11-13 21:51:13 +0800425 };
Bernie Innocentib102dd22018-12-04 14:57:48 +0900426 const int size = static_cast<int>(params_offsets.size());
Luke Huang5bd827c2019-03-14 16:10:04 +0800427 EXPECT_EQ(size, IDnsResolver::RESOLVER_PARAMS_COUNT);
Ken Chenb9fa2062018-11-13 21:51:13 +0800428 std::sort(params_offsets.begin(), params_offsets.end());
Bernie Innocentib102dd22018-12-04 14:57:48 +0900429 for (int i = 0; i < size; ++i) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800430 EXPECT_EQ(params_offsets[i], i);
431 }
432}
433
434TEST_F(ResolverTest, GetHostByName_Binder) {
Luke Huangf8215372019-11-22 11:53:41 +0800435 using aidl::android::net::IDnsResolver;
Ken Chenb9fa2062018-11-13 21:51:13 +0800436
Luke Huangf8215372019-11-22 11:53:41 +0800437 std::vector<std::string> domains = {"example.com"};
Ken Chenb9fa2062018-11-13 21:51:13 +0800438 std::vector<std::unique_ptr<test::DNSResponder>> dns;
439 std::vector<std::string> servers;
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900440 std::vector<DnsResponderClient::Mapping> mappings;
441 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupMappings(1, domains, &mappings));
442 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupDNSServers(4, mappings, &dns, &servers));
Ken Chenb9fa2062018-11-13 21:51:13 +0800443 ASSERT_EQ(1U, mappings.size());
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900444 const DnsResponderClient::Mapping& mapping = mappings[0];
Ken Chenb9fa2062018-11-13 21:51:13 +0800445
Xiao Ma09b71022018-12-11 17:56:32 +0900446 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains, kDefaultParams));
Ken Chenb9fa2062018-11-13 21:51:13 +0800447
448 const hostent* result = gethostbyname(mapping.host.c_str());
Bernie Innocentib102dd22018-12-04 14:57:48 +0900449 const size_t total_queries =
Luke Huangfde82482019-06-04 01:04:53 +0800450 std::accumulate(dns.begin(), dns.end(), 0, [&mapping](size_t total, auto& d) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800451 return total + GetNumQueriesForType(*d, ns_type::ns_t_a, mapping.entry.c_str());
452 });
453
454 EXPECT_LE(1U, total_queries);
455 ASSERT_FALSE(result == nullptr);
456 ASSERT_EQ(4, result->h_length);
457 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
458 EXPECT_EQ(mapping.ip4, ToString(result));
459 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
460
461 std::vector<std::string> res_servers;
462 std::vector<std::string> res_domains;
Mike Yu0a1c53d2018-11-26 13:26:21 +0900463 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900464 res_params res_params;
Ken Chenb9fa2062018-11-13 21:51:13 +0800465 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +0800466 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800467 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
468 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
469 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chenb9fa2062018-11-13 21:51:13 +0800470 EXPECT_EQ(servers.size(), res_servers.size());
471 EXPECT_EQ(domains.size(), res_domains.size());
Mike Yu0a1c53d2018-11-26 13:26:21 +0900472 EXPECT_EQ(0U, res_tls_servers.size());
Luke Huang5bd827c2019-03-14 16:10:04 +0800473 ASSERT_EQ(static_cast<size_t>(IDnsResolver::RESOLVER_PARAMS_COUNT), kDefaultParams.size());
474 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY],
475 res_params.sample_validity);
476 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD],
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900477 res_params.success_threshold);
Luke Huang5bd827c2019-03-14 16:10:04 +0800478 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
479 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
480 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
Ken Chenb9fa2062018-11-13 21:51:13 +0800481 res_params.base_timeout_msec);
482 EXPECT_EQ(servers.size(), res_stats.size());
483
Bernie Innocenti0c067e42019-04-01 15:33:16 +0900484 EXPECT_THAT(res_servers, testing::UnorderedElementsAreArray(servers));
485 EXPECT_THAT(res_domains, testing::UnorderedElementsAreArray(domains));
Ken Chenb9fa2062018-11-13 21:51:13 +0800486}
487
488TEST_F(ResolverTest, GetAddrInfo) {
Xiao Ma09b71022018-12-11 17:56:32 +0900489 constexpr char listen_addr[] = "127.0.0.4";
490 constexpr char listen_addr2[] = "127.0.0.5";
491 constexpr char host_name[] = "howdy.example.com.";
Ken Chenb9fa2062018-11-13 21:51:13 +0800492
Xiao Ma09b71022018-12-11 17:56:32 +0900493 const std::vector<DnsRecord> records = {
494 {host_name, ns_type::ns_t_a, "1.2.3.4"},
495 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
496 };
497 test::DNSResponder dns(listen_addr);
498 test::DNSResponder dns2(listen_addr2);
499 StartDns(dns, records);
500 StartDns(dns2, records);
Ken Chenb9fa2062018-11-13 21:51:13 +0800501
Xiao Ma09b71022018-12-11 17:56:32 +0900502 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr}));
Ken Chenb9fa2062018-11-13 21:51:13 +0800503 dns.clearQueries();
504 dns2.clearQueries();
505
506 ScopedAddrinfo result = safe_getaddrinfo("howdy", nullptr, nullptr);
507 EXPECT_TRUE(result != nullptr);
508 size_t found = GetNumQueries(dns, host_name);
509 EXPECT_LE(1U, found);
510 // Could be A or AAAA
511 std::string result_str = ToString(result);
512 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
Luke Huangf8215372019-11-22 11:53:41 +0800513 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +0800514
515 // Verify that the name is cached.
516 size_t old_found = found;
517 result = safe_getaddrinfo("howdy", nullptr, nullptr);
518 EXPECT_TRUE(result != nullptr);
519 found = GetNumQueries(dns, host_name);
520 EXPECT_LE(1U, found);
521 EXPECT_EQ(old_found, found);
522 result_str = ToString(result);
Luke Huangf8215372019-11-22 11:53:41 +0800523 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4") << result_str;
Ken Chenb9fa2062018-11-13 21:51:13 +0800524
525 // Change the DNS resolver, ensure that queries are still cached.
Xiao Ma09b71022018-12-11 17:56:32 +0900526 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr2}));
Ken Chenb9fa2062018-11-13 21:51:13 +0800527 dns.clearQueries();
528 dns2.clearQueries();
529
530 result = safe_getaddrinfo("howdy", nullptr, nullptr);
531 EXPECT_TRUE(result != nullptr);
532 found = GetNumQueries(dns, host_name);
533 size_t found2 = GetNumQueries(dns2, host_name);
534 EXPECT_EQ(0U, found);
535 EXPECT_LE(0U, found2);
536
537 // Could be A or AAAA
538 result_str = ToString(result);
539 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
Luke Huangf8215372019-11-22 11:53:41 +0800540 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +0800541}
542
543TEST_F(ResolverTest, GetAddrInfoV4) {
Xiao Ma09b71022018-12-11 17:56:32 +0900544 test::DNSResponder dns;
545 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.5"}});
546 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800547
Xiao Ma09b71022018-12-11 17:56:32 +0900548 const addrinfo hints = {.ai_family = AF_INET};
549 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
Ken Chenb9fa2062018-11-13 21:51:13 +0800550 EXPECT_TRUE(result != nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900551 EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
Ken Chenb9fa2062018-11-13 21:51:13 +0800552 EXPECT_EQ("1.2.3.5", ToString(result));
553}
554
555TEST_F(ResolverTest, GetAddrInfo_localhost) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800556 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma09b71022018-12-11 17:56:32 +0900557 test::DNSResponder dns;
558 StartDns(dns, {});
559 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800560
Xiao Ma09b71022018-12-11 17:56:32 +0900561 ScopedAddrinfo result = safe_getaddrinfo(kLocalHost, nullptr, nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800562 EXPECT_TRUE(result != nullptr);
563 // Expect no DNS queries; localhost is resolved via /etc/hosts
564 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900565 EXPECT_EQ(kLocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800566
Xiao Ma09b71022018-12-11 17:56:32 +0900567 result = safe_getaddrinfo(kIp6LocalHost, nullptr, nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800568 EXPECT_TRUE(result != nullptr);
569 // Expect no DNS queries; ip6-localhost is resolved via /etc/hosts
570 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900571 EXPECT_EQ(kIp6LocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800572}
573
Luke Huangd8ac4752019-06-18 17:05:47 +0800574TEST_F(ResolverTest, GetAddrInfo_InvalidSocketType) {
575 test::DNSResponder dns;
576 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.5"}});
577 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
578
579 // TODO: Test other invalid socket types.
580 const addrinfo hints = {
581 .ai_family = AF_UNSPEC,
Luke Huangd8ac4752019-06-18 17:05:47 +0800582 .ai_socktype = SOCK_PACKET,
Nick Desaulnierscd6395a2019-10-11 09:15:24 -0700583 .ai_protocol = ANY,
Luke Huangd8ac4752019-06-18 17:05:47 +0800584 };
585 addrinfo* result = nullptr;
586 // This is a valid hint, but the query won't be sent because the socket type is
587 // not supported.
588 EXPECT_EQ(EAI_NODATA, getaddrinfo("hello", nullptr, &hints, &result));
589 ScopedAddrinfo result_cleanup(result);
590 EXPECT_EQ(nullptr, result);
591}
592
Ken Chen92bed612018-12-22 21:46:55 +0800593// Verify if the resolver correctly handle multiple queries simultaneously
594// step 1: set dns server#1 into deferred responding mode.
595// step 2: thread#1 query "hello.example.com." --> resolver send query to server#1.
596// step 3: thread#2 query "hello.example.com." --> resolver hold the request and wait for
597// response of previous pending query sent by thread#1.
598// step 4: thread#3 query "konbanha.example.com." --> resolver send query to server#3. Server
599// respond to resolver immediately.
600// step 5: check if server#1 get 1 query by thread#1, server#2 get 0 query, server#3 get 1 query.
601// step 6: resume dns server#1 to respond dns query in step#2.
602// step 7: thread#1 and #2 should get returned from DNS query after step#6. Also, check the
603// number of queries in server#2 is 0 to ensure thread#2 does not wake up unexpectedly
604// before signaled by thread#1.
605TEST_F(ResolverTest, GetAddrInfoV4_deferred_resp) {
606 const char* listen_addr1 = "127.0.0.9";
607 const char* listen_addr2 = "127.0.0.10";
608 const char* listen_addr3 = "127.0.0.11";
609 const char* listen_srv = "53";
610 const char* host_name_deferred = "hello.example.com.";
611 const char* host_name_normal = "konbanha.example.com.";
Mike Yufc125e42019-05-15 20:41:28 +0800612 test::DNSResponder dns1(listen_addr1, listen_srv, ns_rcode::ns_r_servfail);
613 test::DNSResponder dns2(listen_addr2, listen_srv, ns_rcode::ns_r_servfail);
614 test::DNSResponder dns3(listen_addr3, listen_srv, ns_rcode::ns_r_servfail);
Ken Chen92bed612018-12-22 21:46:55 +0800615 dns1.addMapping(host_name_deferred, ns_type::ns_t_a, "1.2.3.4");
616 dns2.addMapping(host_name_deferred, ns_type::ns_t_a, "1.2.3.4");
617 dns3.addMapping(host_name_normal, ns_type::ns_t_a, "1.2.3.5");
618 ASSERT_TRUE(dns1.startServer());
619 ASSERT_TRUE(dns2.startServer());
620 ASSERT_TRUE(dns3.startServer());
621 const std::vector<std::string> servers_for_t1 = {listen_addr1};
622 const std::vector<std::string> servers_for_t2 = {listen_addr2};
623 const std::vector<std::string> servers_for_t3 = {listen_addr3};
624 addrinfo hints = {.ai_family = AF_INET};
625 const std::vector<int> params = {300, 25, 8, 8, 5000};
626 bool t3_task_done = false;
627
628 dns1.setDeferredResp(true);
629 std::thread t1([&, this]() {
630 ASSERT_TRUE(
631 mDnsClient.SetResolversForNetwork(servers_for_t1, kDefaultSearchDomains, params));
632 ScopedAddrinfo result = safe_getaddrinfo(host_name_deferred, nullptr, &hints);
633 // t3's dns query should got returned first
634 EXPECT_TRUE(t3_task_done);
635 EXPECT_EQ(1U, GetNumQueries(dns1, host_name_deferred));
636 EXPECT_TRUE(result != nullptr);
637 EXPECT_EQ("1.2.3.4", ToString(result));
638 });
639
640 // ensuring t1 and t2 handler functions are processed in order
641 usleep(100 * 1000);
642 std::thread t2([&, this]() {
643 ASSERT_TRUE(
644 mDnsClient.SetResolversForNetwork(servers_for_t2, kDefaultSearchDomains, params));
645 ScopedAddrinfo result = safe_getaddrinfo(host_name_deferred, nullptr, &hints);
646 EXPECT_TRUE(t3_task_done);
647 EXPECT_EQ(0U, GetNumQueries(dns2, host_name_deferred));
648 EXPECT_TRUE(result != nullptr);
649 EXPECT_EQ("1.2.3.4", ToString(result));
650
651 std::vector<std::string> res_servers;
652 std::vector<std::string> res_domains;
653 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900654 res_params res_params;
Ken Chen92bed612018-12-22 21:46:55 +0800655 std::vector<ResolverStats> res_stats;
656 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800657 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
658 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains,
659 &res_tls_servers, &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chen92bed612018-12-22 21:46:55 +0800660 EXPECT_EQ(0, wait_for_pending_req_timeout_count);
661 });
662
663 // ensuring t2 and t3 handler functions are processed in order
664 usleep(100 * 1000);
665 std::thread t3([&, this]() {
666 ASSERT_TRUE(
667 mDnsClient.SetResolversForNetwork(servers_for_t3, kDefaultSearchDomains, params));
668 ScopedAddrinfo result = safe_getaddrinfo(host_name_normal, nullptr, &hints);
669 EXPECT_EQ(1U, GetNumQueries(dns1, host_name_deferred));
670 EXPECT_EQ(0U, GetNumQueries(dns2, host_name_deferred));
671 EXPECT_EQ(1U, GetNumQueries(dns3, host_name_normal));
672 EXPECT_TRUE(result != nullptr);
673 EXPECT_EQ("1.2.3.5", ToString(result));
674
675 t3_task_done = true;
676 dns1.setDeferredResp(false);
677 });
678 t3.join();
679 t1.join();
680 t2.join();
681}
682
lifr4e4a2e02019-01-29 16:53:51 +0800683TEST_F(ResolverTest, GetAddrInfo_cnames) {
684 constexpr char host_name[] = "host.example.com.";
685 test::DNSResponder dns;
686 const std::vector<DnsRecord> records = {
687 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
688 {"a.example.com.", ns_type::ns_t_cname, "b.example.com."},
689 {"b.example.com.", ns_type::ns_t_cname, "c.example.com."},
690 {"c.example.com.", ns_type::ns_t_cname, "d.example.com."},
691 {"d.example.com.", ns_type::ns_t_cname, "e.example.com."},
692 {"e.example.com.", ns_type::ns_t_cname, host_name},
693 {host_name, ns_type::ns_t_a, "1.2.3.3"},
694 {host_name, ns_type::ns_t_aaaa, "2001:db8::42"},
695 };
696 StartDns(dns, records);
697 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
698
699 addrinfo hints = {.ai_family = AF_INET};
700 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
701 EXPECT_TRUE(result != nullptr);
702 EXPECT_EQ("1.2.3.3", ToString(result));
703
704 dns.clearQueries();
705 hints = {.ai_family = AF_INET6};
706 result = safe_getaddrinfo("hello", nullptr, &hints);
707 EXPECT_TRUE(result != nullptr);
708 EXPECT_EQ("2001:db8::42", ToString(result));
709}
710
711TEST_F(ResolverTest, GetAddrInfo_cnamesNoIpAddress) {
712 test::DNSResponder dns;
713 const std::vector<DnsRecord> records = {
714 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
715 };
716 StartDns(dns, records);
717 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
718
719 addrinfo hints = {.ai_family = AF_INET};
720 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
721 EXPECT_TRUE(result == nullptr);
722
723 dns.clearQueries();
724 hints = {.ai_family = AF_INET6};
725 result = safe_getaddrinfo("hello", nullptr, &hints);
726 EXPECT_TRUE(result == nullptr);
727}
728
729TEST_F(ResolverTest, GetAddrInfo_cnamesIllegalRdata) {
730 test::DNSResponder dns;
731 const std::vector<DnsRecord> records = {
732 {kHelloExampleCom, ns_type::ns_t_cname, ".!#?"},
733 };
734 StartDns(dns, records);
735 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
736
737 addrinfo hints = {.ai_family = AF_INET};
738 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
739 EXPECT_TRUE(result == nullptr);
740
741 dns.clearQueries();
742 hints = {.ai_family = AF_INET6};
743 result = safe_getaddrinfo("hello", nullptr, &hints);
744 EXPECT_TRUE(result == nullptr);
745}
746
Ken Chenb9fa2062018-11-13 21:51:13 +0800747TEST_F(ResolverTest, MultidomainResolution) {
Xiao Ma09b71022018-12-11 17:56:32 +0900748 constexpr char host_name[] = "nihao.example2.com.";
Luke Huangf8215372019-11-22 11:53:41 +0800749 std::vector<std::string> searchDomains = {"example1.com", "example2.com", "example3.com"};
Ken Chenb9fa2062018-11-13 21:51:13 +0800750
Xiao Ma09b71022018-12-11 17:56:32 +0900751 test::DNSResponder dns("127.0.0.6");
752 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.3"}});
753 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({"127.0.0.6"}, searchDomains));
754
Ken Chenb9fa2062018-11-13 21:51:13 +0800755 const hostent* result = gethostbyname("nihao");
Xiao Ma09b71022018-12-11 17:56:32 +0900756
Ken Chenb9fa2062018-11-13 21:51:13 +0800757 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
758 ASSERT_FALSE(result == nullptr);
759 ASSERT_EQ(4, result->h_length);
760 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
761 EXPECT_EQ("1.2.3.3", ToString(result));
762 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800763}
764
765TEST_F(ResolverTest, GetAddrInfoV6_numeric) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800766 constexpr char host_name[] = "ohayou.example.com.";
767 constexpr char numeric_addr[] = "fe80::1%lo";
768
Xiao Ma09b71022018-12-11 17:56:32 +0900769 test::DNSResponder dns;
Ken Chenb9fa2062018-11-13 21:51:13 +0800770 dns.setResponseProbability(0.0);
Xiao Ma09b71022018-12-11 17:56:32 +0900771 StartDns(dns, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
772 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800773
774 addrinfo hints = {.ai_family = AF_INET6};
775 ScopedAddrinfo result = safe_getaddrinfo(numeric_addr, nullptr, &hints);
776 EXPECT_TRUE(result != nullptr);
777 EXPECT_EQ(numeric_addr, ToString(result));
778 EXPECT_TRUE(dns.queries().empty()); // Ensure no DNS queries were sent out
779
780 // Now try a non-numeric hostname query with the AI_NUMERICHOST flag set.
781 // We should fail without sending out a DNS query.
782 hints.ai_flags |= AI_NUMERICHOST;
783 result = safe_getaddrinfo(host_name, nullptr, &hints);
784 EXPECT_TRUE(result == nullptr);
785 EXPECT_TRUE(dns.queries().empty()); // Ensure no DNS queries were sent out
786}
787
788TEST_F(ResolverTest, GetAddrInfoV6_failing) {
Xiao Ma09b71022018-12-11 17:56:32 +0900789 constexpr char listen_addr0[] = "127.0.0.7";
790 constexpr char listen_addr1[] = "127.0.0.8";
Ken Chenb9fa2062018-11-13 21:51:13 +0800791 const char* host_name = "ohayou.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +0900792
793 test::DNSResponder dns0(listen_addr0);
794 test::DNSResponder dns1(listen_addr1);
Ken Chenb9fa2062018-11-13 21:51:13 +0800795 dns0.setResponseProbability(0.0);
Xiao Ma09b71022018-12-11 17:56:32 +0900796 StartDns(dns0, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
797 StartDns(dns1, {{host_name, ns_type::ns_t_aaaa, "2001:db8::6"}});
798
Luke Huangf8215372019-11-22 11:53:41 +0800799 std::vector<std::string> servers = {listen_addr0, listen_addr1};
Ken Chenb9fa2062018-11-13 21:51:13 +0800800 // <sample validity in s> <success threshold in percent> <min samples> <max samples>
801 int sample_count = 8;
Luke Huangf8215372019-11-22 11:53:41 +0800802 const std::vector<int> params = {300, 25, sample_count, sample_count};
Xiao Ma09b71022018-12-11 17:56:32 +0900803 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, kDefaultSearchDomains, params));
Ken Chenb9fa2062018-11-13 21:51:13 +0800804
805 // Repeatedly perform resolutions for non-existing domains until MAXNSSAMPLES resolutions have
806 // reached the dns0, which is set to fail. No more requests should then arrive at that server
807 // for the next sample_lifetime seconds.
808 // TODO: This approach is implementation-dependent, change once metrics reporting is available.
Xiao Ma09b71022018-12-11 17:56:32 +0900809 const addrinfo hints = {.ai_family = AF_INET6};
Bernie Innocentib102dd22018-12-04 14:57:48 +0900810 for (int i = 0; i < sample_count; ++i) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800811 std::string domain = StringPrintf("nonexistent%d", i);
812 ScopedAddrinfo result = safe_getaddrinfo(domain.c_str(), nullptr, &hints);
813 }
814 // Due to 100% errors for all possible samples, the server should be ignored from now on and
815 // only the second one used for all following queries, until NSSAMPLE_VALIDITY is reached.
816 dns0.clearQueries();
817 dns1.clearQueries();
818 ScopedAddrinfo result = safe_getaddrinfo("ohayou", nullptr, &hints);
819 EXPECT_TRUE(result != nullptr);
820 EXPECT_EQ(0U, GetNumQueries(dns0, host_name));
821 EXPECT_EQ(1U, GetNumQueries(dns1, host_name));
822}
823
824TEST_F(ResolverTest, GetAddrInfoV6_nonresponsive) {
Xiao Ma09b71022018-12-11 17:56:32 +0900825 constexpr char listen_addr0[] = "127.0.0.7";
826 constexpr char listen_addr1[] = "127.0.0.8";
827 constexpr char listen_srv[] = "53";
828 constexpr char host_name1[] = "ohayou.example.com.";
829 constexpr char host_name2[] = "ciao.example.com.";
Luke Huang483cf332019-06-03 17:24:51 +0800830 const std::vector<std::string> defaultSearchDomain = {"example.com"};
831 // The minimal timeout is 1000ms, so we can't decrease timeout
832 // So reduce retry count.
833 const std::vector<int> reduceRetryParams = {
834 300, // sample validity in seconds
835 25, // success threshod in percent
836 8, 8, // {MIN,MAX}_SAMPLES
837 1000, // BASE_TIMEOUT_MSEC
838 1, // retry count
839 };
Xiao Ma09b71022018-12-11 17:56:32 +0900840 const std::vector<DnsRecord> records0 = {
841 {host_name1, ns_type::ns_t_aaaa, "2001:db8::5"},
842 {host_name2, ns_type::ns_t_aaaa, "2001:db8::5"},
843 };
844 const std::vector<DnsRecord> records1 = {
845 {host_name1, ns_type::ns_t_aaaa, "2001:db8::6"},
846 {host_name2, ns_type::ns_t_aaaa, "2001:db8::6"},
847 };
Ken Chenb9fa2062018-11-13 21:51:13 +0800848
849 // dns0 does not respond with 100% probability, while
850 // dns1 responds normally, at least initially.
Mike Yufc125e42019-05-15 20:41:28 +0800851 test::DNSResponder dns0(listen_addr0, listen_srv, static_cast<ns_rcode>(-1));
852 test::DNSResponder dns1(listen_addr1, listen_srv, static_cast<ns_rcode>(-1));
Ken Chenb9fa2062018-11-13 21:51:13 +0800853 dns0.setResponseProbability(0.0);
Xiao Ma09b71022018-12-11 17:56:32 +0900854 StartDns(dns0, records0);
855 StartDns(dns1, records1);
Luke Huang483cf332019-06-03 17:24:51 +0800856 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr0, listen_addr1}, defaultSearchDomain,
857 reduceRetryParams));
Ken Chenb9fa2062018-11-13 21:51:13 +0800858
Luke Huang483cf332019-06-03 17:24:51 +0800859 // Specify ai_socktype to make getaddrinfo will only query 1 time
860 const addrinfo hints = {.ai_family = AF_INET6, .ai_socktype = SOCK_STREAM};
Ken Chenb9fa2062018-11-13 21:51:13 +0800861
862 // dns0 will ignore the request, and we'll fallback to dns1 after the first
863 // retry.
864 ScopedAddrinfo result = safe_getaddrinfo(host_name1, nullptr, &hints);
865 EXPECT_TRUE(result != nullptr);
866 EXPECT_EQ(1U, GetNumQueries(dns0, host_name1));
867 EXPECT_EQ(1U, GetNumQueries(dns1, host_name1));
868
869 // Now make dns1 also ignore 100% requests... The resolve should alternate
Luke Huang483cf332019-06-03 17:24:51 +0800870 // queries between the nameservers and fail
Ken Chenb9fa2062018-11-13 21:51:13 +0800871 dns1.setResponseProbability(0.0);
872 addrinfo* result2 = nullptr;
873 EXPECT_EQ(EAI_NODATA, getaddrinfo(host_name2, nullptr, &hints, &result2));
874 EXPECT_EQ(nullptr, result2);
Luke Huang483cf332019-06-03 17:24:51 +0800875 EXPECT_EQ(1U, GetNumQueries(dns0, host_name2));
876 EXPECT_EQ(1U, GetNumQueries(dns1, host_name2));
Ken Chenb9fa2062018-11-13 21:51:13 +0800877}
878
879TEST_F(ResolverTest, GetAddrInfoV6_concurrent) {
Xiao Ma09b71022018-12-11 17:56:32 +0900880 constexpr char listen_addr0[] = "127.0.0.9";
881 constexpr char listen_addr1[] = "127.0.0.10";
882 constexpr char listen_addr2[] = "127.0.0.11";
883 constexpr char host_name[] = "konbanha.example.com.";
884
885 test::DNSResponder dns0(listen_addr0);
886 test::DNSResponder dns1(listen_addr1);
887 test::DNSResponder dns2(listen_addr2);
888 StartDns(dns0, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
889 StartDns(dns1, {{host_name, ns_type::ns_t_aaaa, "2001:db8::6"}});
890 StartDns(dns2, {{host_name, ns_type::ns_t_aaaa, "2001:db8::7"}});
891
Luke Huangf8215372019-11-22 11:53:41 +0800892 const std::vector<std::string> servers = {listen_addr0, listen_addr1, listen_addr2};
Ken Chenb9fa2062018-11-13 21:51:13 +0800893 std::vector<std::thread> threads(10);
894 for (std::thread& thread : threads) {
Luke Huangf8215372019-11-22 11:53:41 +0800895 thread = std::thread([this, &servers]() {
896 unsigned delay = arc4random_uniform(1 * 1000 * 1000); // <= 1s
Ken Chenb9fa2062018-11-13 21:51:13 +0800897 usleep(delay);
898 std::vector<std::string> serverSubset;
899 for (const auto& server : servers) {
900 if (arc4random_uniform(2)) {
901 serverSubset.push_back(server);
902 }
903 }
904 if (serverSubset.empty()) serverSubset = servers;
Xiao Ma09b71022018-12-11 17:56:32 +0900905 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(serverSubset));
906 const addrinfo hints = {.ai_family = AF_INET6};
Ken Chenb9fa2062018-11-13 21:51:13 +0800907 addrinfo* result = nullptr;
908 int rv = getaddrinfo("konbanha", nullptr, &hints, &result);
909 EXPECT_EQ(0, rv) << "error [" << rv << "] " << gai_strerror(rv);
910 if (result) {
911 freeaddrinfo(result);
912 result = nullptr;
913 }
914 });
915 }
916 for (std::thread& thread : threads) {
917 thread.join();
918 }
Ken Chen92bed612018-12-22 21:46:55 +0800919
920 std::vector<std::string> res_servers;
921 std::vector<std::string> res_domains;
922 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900923 res_params res_params;
Ken Chen92bed612018-12-22 21:46:55 +0800924 std::vector<ResolverStats> res_stats;
925 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800926 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
927 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
928 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chen92bed612018-12-22 21:46:55 +0800929 EXPECT_EQ(0, wait_for_pending_req_timeout_count);
Ken Chenb9fa2062018-11-13 21:51:13 +0800930}
931
Ken Chenb9fa2062018-11-13 21:51:13 +0800932TEST_F(ResolverTest, EmptySetup) {
Luke Huangf8215372019-11-22 11:53:41 +0800933 using aidl::android::net::IDnsResolver;
Ken Chenb9fa2062018-11-13 21:51:13 +0800934 std::vector<std::string> servers;
935 std::vector<std::string> domains;
Xiao Ma09b71022018-12-11 17:56:32 +0900936 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Ken Chenb9fa2062018-11-13 21:51:13 +0800937 std::vector<std::string> res_servers;
938 std::vector<std::string> res_domains;
Mike Yu0a1c53d2018-11-26 13:26:21 +0900939 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900940 res_params res_params;
Ken Chenb9fa2062018-11-13 21:51:13 +0800941 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +0800942 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800943 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
944 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
945 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chenb9fa2062018-11-13 21:51:13 +0800946 EXPECT_EQ(0U, res_servers.size());
947 EXPECT_EQ(0U, res_domains.size());
Mike Yu0a1c53d2018-11-26 13:26:21 +0900948 EXPECT_EQ(0U, res_tls_servers.size());
Luke Huang5bd827c2019-03-14 16:10:04 +0800949 ASSERT_EQ(static_cast<size_t>(IDnsResolver::RESOLVER_PARAMS_COUNT), kDefaultParams.size());
950 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY],
951 res_params.sample_validity);
952 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD],
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900953 res_params.success_threshold);
Luke Huang5bd827c2019-03-14 16:10:04 +0800954 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
955 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
956 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
Ken Chenb9fa2062018-11-13 21:51:13 +0800957 res_params.base_timeout_msec);
Luke Huang5bd827c2019-03-14 16:10:04 +0800958 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT], res_params.retry_count);
Ken Chenb9fa2062018-11-13 21:51:13 +0800959}
960
961TEST_F(ResolverTest, SearchPathChange) {
Xiao Ma09b71022018-12-11 17:56:32 +0900962 constexpr char listen_addr[] = "127.0.0.13";
963 constexpr char host_name1[] = "test13.domain1.org.";
964 constexpr char host_name2[] = "test13.domain2.org.";
Luke Huangf8215372019-11-22 11:53:41 +0800965 std::vector<std::string> servers = {listen_addr};
966 std::vector<std::string> domains = {"domain1.org"};
Xiao Ma09b71022018-12-11 17:56:32 +0900967
968 const std::vector<DnsRecord> records = {
969 {host_name1, ns_type::ns_t_aaaa, "2001:db8::13"},
970 {host_name2, ns_type::ns_t_aaaa, "2001:db8::1:13"},
971 };
972 test::DNSResponder dns(listen_addr);
973 StartDns(dns, records);
974 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Ken Chenb9fa2062018-11-13 21:51:13 +0800975
976 const addrinfo hints = {.ai_family = AF_INET6};
977 ScopedAddrinfo result = safe_getaddrinfo("test13", nullptr, &hints);
978 EXPECT_TRUE(result != nullptr);
979 EXPECT_EQ(1U, dns.queries().size());
980 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
981 EXPECT_EQ("2001:db8::13", ToString(result));
982
983 // Test that changing the domain search path on its own works.
Luke Huangf8215372019-11-22 11:53:41 +0800984 domains = {"domain2.org"};
Xiao Ma09b71022018-12-11 17:56:32 +0900985 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Ken Chenb9fa2062018-11-13 21:51:13 +0800986 dns.clearQueries();
987
988 result = safe_getaddrinfo("test13", nullptr, &hints);
989 EXPECT_TRUE(result != nullptr);
990 EXPECT_EQ(1U, dns.queries().size());
991 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
992 EXPECT_EQ("2001:db8::1:13", ToString(result));
993}
994
Luke Huang2dac4382019-06-24 13:28:44 +0800995namespace {
996
Luke Huangf8215372019-11-22 11:53:41 +0800997std::vector<std::string> getResolverDomains(aidl::android::net::IDnsResolver* dnsResolverService,
Luke Huang2dac4382019-06-24 13:28:44 +0800998 unsigned netId) {
999 std::vector<std::string> res_servers;
1000 std::vector<std::string> res_domains;
1001 std::vector<std::string> res_tls_servers;
1002 res_params res_params;
1003 std::vector<ResolverStats> res_stats;
1004 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +08001005 DnsResponderClient::GetResolverInfo(dnsResolverService, netId, &res_servers, &res_domains,
1006 &res_tls_servers, &res_params, &res_stats,
1007 &wait_for_pending_req_timeout_count);
Luke Huang2dac4382019-06-24 13:28:44 +08001008 return res_domains;
1009}
1010
1011} // namespace
1012
1013TEST_F(ResolverTest, SearchPathPrune) {
1014 constexpr size_t DUPLICATED_DOMAIN_NUM = 3;
1015 constexpr char listen_addr[] = "127.0.0.13";
1016 constexpr char domian_name1[] = "domain13.org.";
1017 constexpr char domian_name2[] = "domain14.org.";
1018 constexpr char host_name1[] = "test13.domain13.org.";
1019 constexpr char host_name2[] = "test14.domain14.org.";
1020 std::vector<std::string> servers = {listen_addr};
1021
1022 std::vector<std::string> testDomains1;
1023 std::vector<std::string> testDomains2;
1024 // Domain length should be <= 255
1025 // Max number of domains in search path is 6
1026 for (size_t i = 0; i < MAXDNSRCH + 1; i++) {
1027 // Fill up with invalid domain
1028 testDomains1.push_back(std::string(300, i + '0'));
1029 // Fill up with valid but duplicated domain
1030 testDomains2.push_back(StringPrintf("domain%zu.org", i % DUPLICATED_DOMAIN_NUM));
1031 }
1032
1033 // Add valid domain used for query.
1034 testDomains1.push_back(domian_name1);
1035
1036 // Add valid domain twice used for query.
1037 testDomains2.push_back(domian_name2);
1038 testDomains2.push_back(domian_name2);
1039
1040 const std::vector<DnsRecord> records = {
1041 {host_name1, ns_type::ns_t_aaaa, "2001:db8::13"},
1042 {host_name2, ns_type::ns_t_aaaa, "2001:db8::1:13"},
1043 };
1044 test::DNSResponder dns(listen_addr);
1045 StartDns(dns, records);
1046 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, testDomains1));
1047
1048 const addrinfo hints = {.ai_family = AF_INET6};
1049 ScopedAddrinfo result = safe_getaddrinfo("test13", nullptr, &hints);
1050
1051 EXPECT_TRUE(result != nullptr);
1052
1053 EXPECT_EQ(1U, dns.queries().size());
1054 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
1055 EXPECT_EQ("2001:db8::13", ToString(result));
1056
1057 const auto& res_domains1 = getResolverDomains(mDnsClient.resolvService(), TEST_NETID);
1058 // Expect 1 valid domain, invalid domains are removed.
1059 ASSERT_EQ(1U, res_domains1.size());
1060 EXPECT_EQ(domian_name1, res_domains1[0]);
1061
1062 dns.clearQueries();
1063
1064 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, testDomains2));
1065
1066 result = safe_getaddrinfo("test14", nullptr, &hints);
1067 EXPECT_TRUE(result != nullptr);
1068
1069 // (3 domains * 2 retries) + 1 success query = 7
1070 EXPECT_EQ(7U, dns.queries().size());
1071 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
1072 EXPECT_EQ("2001:db8::1:13", ToString(result));
1073
1074 const auto& res_domains2 = getResolverDomains(mDnsClient.resolvService(), TEST_NETID);
1075 // Expect 4 valid domain, duplicate domains are removed.
1076 EXPECT_EQ(DUPLICATED_DOMAIN_NUM + 1U, res_domains2.size());
1077 EXPECT_THAT(
1078 std::vector<std::string>({"domain0.org", "domain1.org", "domain2.org", domian_name2}),
1079 testing::ElementsAreArray(res_domains2));
1080}
1081
Mike Yu0a1c53d2018-11-26 13:26:21 +09001082// If we move this function to dns_responder_client, it will complicate the dependency need of
1083// dns_tls_frontend.h.
1084static void setupTlsServers(const std::vector<std::string>& servers,
waynema0e73c2e2019-07-31 15:04:08 +08001085 std::vector<std::unique_ptr<test::DnsTlsFrontend>>* tls) {
Xiao Ma09b71022018-12-11 17:56:32 +09001086 constexpr char listen_udp[] = "53";
1087 constexpr char listen_tls[] = "853";
Mike Yu0a1c53d2018-11-26 13:26:21 +09001088
1089 for (const auto& server : servers) {
1090 auto t = std::make_unique<test::DnsTlsFrontend>(server, listen_tls, server, listen_udp);
1091 t = std::make_unique<test::DnsTlsFrontend>(server, listen_tls, server, listen_udp);
1092 t->startServer();
Mike Yu0a1c53d2018-11-26 13:26:21 +09001093 tls->push_back(std::move(t));
1094 }
1095}
1096
Mike Yu0a1c53d2018-11-26 13:26:21 +09001097TEST_F(ResolverTest, MaxServerPrune_Binder) {
Mike Yu0a1c53d2018-11-26 13:26:21 +09001098 std::vector<std::string> domains;
1099 std::vector<std::unique_ptr<test::DNSResponder>> dns;
1100 std::vector<std::unique_ptr<test::DnsTlsFrontend>> tls;
1101 std::vector<std::string> servers;
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +09001102 std::vector<DnsResponderClient::Mapping> mappings;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001103
1104 for (unsigned i = 0; i < MAXDNSRCH + 1; i++) {
1105 domains.push_back(StringPrintf("example%u.com", i));
1106 }
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +09001107 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupMappings(1, domains, &mappings));
1108 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupDNSServers(MAXNS + 1, mappings, &dns, &servers));
waynema0e73c2e2019-07-31 15:04:08 +08001109 ASSERT_NO_FATAL_FAILURE(setupTlsServers(servers, &tls));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001110
waynema0e73c2e2019-07-31 15:04:08 +08001111 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, domains, kDefaultParams,
1112 kDefaultPrivateDnsHostName));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001113
Mike Yu383855b2019-01-15 17:53:27 +08001114 // If the private DNS validation hasn't completed yet before backend DNS servers stop,
1115 // TLS servers will get stuck in handleOneRequest(), which causes this test stuck in
1116 // ~DnsTlsFrontend() because the TLS server loop threads can't be terminated.
1117 // So, wait for private DNS validation done before stopping backend DNS servers.
1118 for (int i = 0; i < MAXNS; i++) {
chenbruceaff85842019-05-31 15:46:42 +08001119 LOG(INFO) << "Waiting for private DNS validation on " << tls[i]->listen_address() << ".";
Mike Yu724f77d2019-08-16 11:14:50 +08001120 EXPECT_TRUE(WaitForPrivateDnsValidation(tls[i]->listen_address(), true));
chenbruceaff85842019-05-31 15:46:42 +08001121 LOG(INFO) << "private DNS validation on " << tls[i]->listen_address() << " done.";
Mike Yu383855b2019-01-15 17:53:27 +08001122 }
1123
Mike Yu0a1c53d2018-11-26 13:26:21 +09001124 std::vector<std::string> res_servers;
1125 std::vector<std::string> res_domains;
1126 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +09001127 res_params res_params;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001128 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +08001129 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +08001130 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
1131 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
1132 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001133
1134 // Check the size of the stats and its contents.
1135 EXPECT_EQ(static_cast<size_t>(MAXNS), res_servers.size());
1136 EXPECT_EQ(static_cast<size_t>(MAXNS), res_tls_servers.size());
1137 EXPECT_EQ(static_cast<size_t>(MAXDNSRCH), res_domains.size());
1138 EXPECT_TRUE(std::equal(servers.begin(), servers.begin() + MAXNS, res_servers.begin()));
1139 EXPECT_TRUE(std::equal(servers.begin(), servers.begin() + MAXNS, res_tls_servers.begin()));
1140 EXPECT_TRUE(std::equal(domains.begin(), domains.begin() + MAXDNSRCH, res_domains.begin()));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001141}
1142
1143TEST_F(ResolverTest, ResolverStats) {
Xiao Ma09b71022018-12-11 17:56:32 +09001144 constexpr char listen_addr1[] = "127.0.0.4";
1145 constexpr char listen_addr2[] = "127.0.0.5";
1146 constexpr char listen_addr3[] = "127.0.0.6";
Mike Yu0a1c53d2018-11-26 13:26:21 +09001147
1148 // Set server 1 timeout.
Mike Yufc125e42019-05-15 20:41:28 +08001149 test::DNSResponder dns1(listen_addr1, "53", static_cast<ns_rcode>(-1));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001150 dns1.setResponseProbability(0.0);
1151 ASSERT_TRUE(dns1.startServer());
1152
1153 // Set server 2 responding server failure.
Xiao Ma09b71022018-12-11 17:56:32 +09001154 test::DNSResponder dns2(listen_addr2);
Mike Yu0a1c53d2018-11-26 13:26:21 +09001155 dns2.setResponseProbability(0.0);
1156 ASSERT_TRUE(dns2.startServer());
1157
1158 // Set server 3 workable.
Xiao Ma09b71022018-12-11 17:56:32 +09001159 test::DNSResponder dns3(listen_addr3);
1160 dns3.addMapping(kHelloExampleCom, ns_type::ns_t_a, "1.2.3.4");
Mike Yu0a1c53d2018-11-26 13:26:21 +09001161 ASSERT_TRUE(dns3.startServer());
1162
1163 std::vector<std::string> servers = {listen_addr1, listen_addr2, listen_addr3};
Xiao Ma09b71022018-12-11 17:56:32 +09001164 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001165
1166 dns3.clearQueries();
Xiao Ma09b71022018-12-11 17:56:32 +09001167 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
Mike Yu0a1c53d2018-11-26 13:26:21 +09001168 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
Xiao Ma09b71022018-12-11 17:56:32 +09001169 size_t found = GetNumQueries(dns3, kHelloExampleCom);
Mike Yu0a1c53d2018-11-26 13:26:21 +09001170 EXPECT_LE(1U, found);
1171 std::string result_str = ToString(result);
1172 EXPECT_TRUE(result_str == "1.2.3.4") << ", result_str='" << result_str << "'";
1173
1174 std::vector<std::string> res_servers;
1175 std::vector<std::string> res_domains;
1176 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +09001177 res_params res_params;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001178 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +08001179 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +08001180 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
1181 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
1182 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001183
1184 EXPECT_EQ(1, res_stats[0].timeouts);
1185 EXPECT_EQ(1, res_stats[1].errors);
1186 EXPECT_EQ(1, res_stats[2].successes);
Mike Yu0a1c53d2018-11-26 13:26:21 +09001187}
1188
Ken Chenb9fa2062018-11-13 21:51:13 +08001189// Test what happens if the specified TLS server is nonexistent.
1190TEST_F(ResolverTest, GetHostByName_TlsMissing) {
Xiao Ma09b71022018-12-11 17:56:32 +09001191 constexpr char listen_addr[] = "127.0.0.3";
1192 constexpr char host_name[] = "tlsmissing.example.com.";
1193
1194 test::DNSResponder dns;
1195 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.3"}});
Luke Huangf8215372019-11-22 11:53:41 +08001196 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001197
1198 // There's nothing listening on this address, so validation will either fail or
1199 /// hang. Either way, queries will continue to flow to the DNSResponder.
waynema0e73c2e2019-07-31 15:04:08 +08001200 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Ken Chenb9fa2062018-11-13 21:51:13 +08001201
1202 const hostent* result;
1203
1204 result = gethostbyname("tlsmissing");
1205 ASSERT_FALSE(result == nullptr);
1206 EXPECT_EQ("1.2.3.3", ToString(result));
1207
1208 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001209 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001210}
1211
1212// Test what happens if the specified TLS server replies with garbage.
1213TEST_F(ResolverTest, GetHostByName_TlsBroken) {
Xiao Ma09b71022018-12-11 17:56:32 +09001214 constexpr char listen_addr[] = "127.0.0.3";
1215 constexpr char host_name1[] = "tlsbroken1.example.com.";
1216 constexpr char host_name2[] = "tlsbroken2.example.com.";
1217 const std::vector<DnsRecord> records = {
1218 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1219 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1220 };
1221
1222 test::DNSResponder dns;
1223 StartDns(dns, records);
Luke Huangf8215372019-11-22 11:53:41 +08001224 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001225
1226 // Bind the specified private DNS socket but don't respond to any client sockets yet.
1227 int s = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
1228 ASSERT_TRUE(s >= 0);
1229 struct sockaddr_in tlsServer = {
Luke Huangf8215372019-11-22 11:53:41 +08001230 .sin_family = AF_INET,
1231 .sin_port = htons(853),
Ken Chenb9fa2062018-11-13 21:51:13 +08001232 };
1233 ASSERT_TRUE(inet_pton(AF_INET, listen_addr, &tlsServer.sin_addr));
1234 ASSERT_TRUE(enableSockopt(s, SOL_SOCKET, SO_REUSEPORT).ok());
1235 ASSERT_TRUE(enableSockopt(s, SOL_SOCKET, SO_REUSEADDR).ok());
1236 ASSERT_FALSE(bind(s, reinterpret_cast<struct sockaddr*>(&tlsServer), sizeof(tlsServer)));
1237 ASSERT_FALSE(listen(s, 1));
1238
1239 // Trigger TLS validation.
waynema0e73c2e2019-07-31 15:04:08 +08001240 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Ken Chenb9fa2062018-11-13 21:51:13 +08001241
1242 struct sockaddr_storage cliaddr;
1243 socklen_t sin_size = sizeof(cliaddr);
Luke Huangf8215372019-11-22 11:53:41 +08001244 int new_fd = accept4(s, reinterpret_cast<struct sockaddr*>(&cliaddr), &sin_size, SOCK_CLOEXEC);
Ken Chenb9fa2062018-11-13 21:51:13 +08001245 ASSERT_TRUE(new_fd > 0);
1246
1247 // We've received the new file descriptor but not written to it or closed, so the
1248 // validation is still pending. Queries should still flow correctly because the
1249 // server is not used until validation succeeds.
1250 const hostent* result;
1251 result = gethostbyname("tlsbroken1");
1252 ASSERT_FALSE(result == nullptr);
1253 EXPECT_EQ("1.2.3.1", ToString(result));
1254
1255 // Now we cause the validation to fail.
1256 std::string garbage = "definitely not a valid TLS ServerHello";
1257 write(new_fd, garbage.data(), garbage.size());
1258 close(new_fd);
1259
1260 // Validation failure shouldn't interfere with lookups, because lookups won't be sent
1261 // to the TLS server unless validation succeeds.
1262 result = gethostbyname("tlsbroken2");
1263 ASSERT_FALSE(result == nullptr);
1264 EXPECT_EQ("1.2.3.2", ToString(result));
1265
1266 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001267 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001268 close(s);
1269}
1270
1271TEST_F(ResolverTest, GetHostByName_Tls) {
Xiao Ma09b71022018-12-11 17:56:32 +09001272 constexpr char listen_addr[] = "127.0.0.3";
1273 constexpr char listen_udp[] = "53";
1274 constexpr char listen_tls[] = "853";
1275 constexpr char host_name1[] = "tls1.example.com.";
1276 constexpr char host_name2[] = "tls2.example.com.";
1277 constexpr char host_name3[] = "tls3.example.com.";
1278 const std::vector<DnsRecord> records = {
1279 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1280 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1281 {host_name3, ns_type::ns_t_a, "1.2.3.3"},
1282 };
1283
1284 test::DNSResponder dns;
1285 StartDns(dns, records);
Luke Huangf8215372019-11-22 11:53:41 +08001286 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001287
1288 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1289 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08001290 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08001291 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Ken Chenb9fa2062018-11-13 21:51:13 +08001292
Mike Yu724f77d2019-08-16 11:14:50 +08001293 const hostent* result = gethostbyname("tls1");
Ken Chenb9fa2062018-11-13 21:51:13 +08001294 ASSERT_FALSE(result == nullptr);
1295 EXPECT_EQ("1.2.3.1", ToString(result));
1296
1297 // Wait for query to get counted.
1298 EXPECT_TRUE(tls.waitForQueries(2, 5000));
1299
1300 // Stop the TLS server. Since we're in opportunistic mode, queries will
1301 // fall back to the locally-assigned (clear text) nameservers.
1302 tls.stopServer();
1303
1304 dns.clearQueries();
1305 result = gethostbyname("tls2");
1306 EXPECT_FALSE(result == nullptr);
1307 EXPECT_EQ("1.2.3.2", ToString(result));
1308 const auto queries = dns.queries();
1309 EXPECT_EQ(1U, queries.size());
1310 EXPECT_EQ("tls2.example.com.", queries[0].first);
1311 EXPECT_EQ(ns_t_a, queries[0].second);
1312
1313 // Reset the resolvers without enabling TLS. Queries should still be routed
1314 // to the UDP endpoint.
Xiao Ma09b71022018-12-11 17:56:32 +09001315 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001316
1317 result = gethostbyname("tls3");
1318 ASSERT_FALSE(result == nullptr);
1319 EXPECT_EQ("1.2.3.3", ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +08001320}
1321
Ken Chenb9fa2062018-11-13 21:51:13 +08001322TEST_F(ResolverTest, GetHostByName_TlsFailover) {
Xiao Ma09b71022018-12-11 17:56:32 +09001323 constexpr char listen_addr1[] = "127.0.0.3";
1324 constexpr char listen_addr2[] = "127.0.0.4";
1325 constexpr char listen_udp[] = "53";
1326 constexpr char listen_tls[] = "853";
1327 constexpr char host_name1[] = "tlsfailover1.example.com.";
1328 constexpr char host_name2[] = "tlsfailover2.example.com.";
1329 const std::vector<DnsRecord> records1 = {
1330 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1331 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1332 };
1333 const std::vector<DnsRecord> records2 = {
1334 {host_name1, ns_type::ns_t_a, "1.2.3.3"},
1335 {host_name2, ns_type::ns_t_a, "1.2.3.4"},
1336 };
1337
1338 test::DNSResponder dns1(listen_addr1);
1339 test::DNSResponder dns2(listen_addr2);
1340 StartDns(dns1, records1);
1341 StartDns(dns2, records2);
1342
Luke Huangf8215372019-11-22 11:53:41 +08001343 std::vector<std::string> servers = {listen_addr1, listen_addr2};
Ken Chenb9fa2062018-11-13 21:51:13 +08001344
1345 test::DnsTlsFrontend tls1(listen_addr1, listen_tls, listen_addr1, listen_udp);
1346 test::DnsTlsFrontend tls2(listen_addr2, listen_tls, listen_addr2, listen_udp);
1347 ASSERT_TRUE(tls1.startServer());
1348 ASSERT_TRUE(tls2.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08001349 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
1350 kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08001351 EXPECT_TRUE(WaitForPrivateDnsValidation(tls1.listen_address(), true));
1352 EXPECT_TRUE(WaitForPrivateDnsValidation(tls2.listen_address(), true));
Ken Chenb9fa2062018-11-13 21:51:13 +08001353
Mike Yu724f77d2019-08-16 11:14:50 +08001354 const hostent* result = gethostbyname("tlsfailover1");
Ken Chenb9fa2062018-11-13 21:51:13 +08001355 ASSERT_FALSE(result == nullptr);
1356 EXPECT_EQ("1.2.3.1", ToString(result));
1357
1358 // Wait for query to get counted.
1359 EXPECT_TRUE(tls1.waitForQueries(2, 5000));
1360 // No new queries should have reached tls2.
1361 EXPECT_EQ(1, tls2.queries());
1362
1363 // Stop tls1. Subsequent queries should attempt to reach tls1, fail, and retry to tls2.
1364 tls1.stopServer();
1365
1366 result = gethostbyname("tlsfailover2");
1367 EXPECT_EQ("1.2.3.4", ToString(result));
1368
1369 // Wait for query to get counted.
1370 EXPECT_TRUE(tls2.waitForQueries(2, 5000));
1371
1372 // No additional queries should have reached the insecure servers.
1373 EXPECT_EQ(2U, dns1.queries().size());
1374 EXPECT_EQ(2U, dns2.queries().size());
1375
1376 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001377 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Ken Chenb9fa2062018-11-13 21:51:13 +08001378}
1379
1380TEST_F(ResolverTest, GetHostByName_BadTlsName) {
Xiao Ma09b71022018-12-11 17:56:32 +09001381 constexpr char listen_addr[] = "127.0.0.3";
1382 constexpr char listen_udp[] = "53";
1383 constexpr char listen_tls[] = "853";
1384 constexpr char host_name[] = "badtlsname.example.com.";
1385
1386 test::DNSResponder dns;
1387 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.1"}});
Luke Huangf8215372019-11-22 11:53:41 +08001388 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001389
1390 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1391 ASSERT_TRUE(tls.startServer());
Xiao Ma09b71022018-12-11 17:56:32 +09001392 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
waynema0e73c2e2019-07-31 15:04:08 +08001393 kDefaultIncorrectPrivateDnsHostName));
Ken Chenb9fa2062018-11-13 21:51:13 +08001394
waynema0e73c2e2019-07-31 15:04:08 +08001395 // The TLS handshake would fail because the name of TLS server doesn't
1396 // match with TLS server's certificate.
Mike Yu724f77d2019-08-16 11:14:50 +08001397 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), false));
Ken Chenb9fa2062018-11-13 21:51:13 +08001398
1399 // The query should fail hard, because a name was specified.
1400 EXPECT_EQ(nullptr, gethostbyname("badtlsname"));
1401
1402 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001403 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001404}
1405
1406TEST_F(ResolverTest, GetAddrInfo_Tls) {
Xiao Ma09b71022018-12-11 17:56:32 +09001407 constexpr char listen_addr[] = "127.0.0.3";
1408 constexpr char listen_udp[] = "53";
1409 constexpr char listen_tls[] = "853";
1410 constexpr char host_name[] = "addrinfotls.example.com.";
1411 const std::vector<DnsRecord> records = {
1412 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1413 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1414 };
1415
1416 test::DNSResponder dns;
1417 StartDns(dns, records);
Luke Huangf8215372019-11-22 11:53:41 +08001418 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001419
1420 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1421 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08001422 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
1423 kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08001424 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Ken Chenb9fa2062018-11-13 21:51:13 +08001425
1426 dns.clearQueries();
1427 ScopedAddrinfo result = safe_getaddrinfo("addrinfotls", nullptr, nullptr);
1428 EXPECT_TRUE(result != nullptr);
1429 size_t found = GetNumQueries(dns, host_name);
1430 EXPECT_LE(1U, found);
1431 // Could be A or AAAA
1432 std::string result_str = ToString(result);
1433 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
Luke Huangf8215372019-11-22 11:53:41 +08001434 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +08001435 // Wait for both A and AAAA queries to get counted.
1436 EXPECT_TRUE(tls.waitForQueries(3, 5000));
1437
1438 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001439 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001440}
1441
1442TEST_F(ResolverTest, TlsBypass) {
1443 const char OFF[] = "off";
1444 const char OPPORTUNISTIC[] = "opportunistic";
1445 const char STRICT[] = "strict";
1446
1447 const char GETHOSTBYNAME[] = "gethostbyname";
1448 const char GETADDRINFO[] = "getaddrinfo";
1449 const char GETADDRINFOFORNET[] = "getaddrinfofornet";
1450
1451 const unsigned BYPASS_NETID = NETID_USE_LOCAL_NAMESERVERS | TEST_NETID;
1452
Ken Chenb9fa2062018-11-13 21:51:13 +08001453 const char ADDR4[] = "192.0.2.1";
1454 const char ADDR6[] = "2001:db8::1";
1455
1456 const char cleartext_addr[] = "127.0.0.53";
1457 const char cleartext_port[] = "53";
1458 const char tls_port[] = "853";
Luke Huangf8215372019-11-22 11:53:41 +08001459 const std::vector<std::string> servers = {cleartext_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001460
Xiao Ma09b71022018-12-11 17:56:32 +09001461 test::DNSResponder dns(cleartext_addr);
Ken Chenb9fa2062018-11-13 21:51:13 +08001462 ASSERT_TRUE(dns.startServer());
1463
1464 test::DnsTlsFrontend tls(cleartext_addr, tls_port, cleartext_addr, cleartext_port);
Mike Yudd4ac2d2019-05-31 16:52:11 +08001465 ASSERT_TRUE(tls.startServer());
Ken Chenb9fa2062018-11-13 21:51:13 +08001466
Luke Huangf8215372019-11-22 11:53:41 +08001467 // clang-format off
Ken Chenb9fa2062018-11-13 21:51:13 +08001468 struct TestConfig {
1469 const std::string mode;
1470 const bool withWorkingTLS;
1471 const std::string method;
1472
1473 std::string asHostName() const {
Luke Huangf8215372019-11-22 11:53:41 +08001474 return StringPrintf("%s.%s.%s.", mode.c_str(), withWorkingTLS ? "tlsOn" : "tlsOff",
Ken Chenb9fa2062018-11-13 21:51:13 +08001475 method.c_str());
1476 }
1477 } testConfigs[]{
Ken Chenb9fa2062018-11-13 21:51:13 +08001478 {OFF, true, GETHOSTBYNAME},
1479 {OPPORTUNISTIC, true, GETHOSTBYNAME},
1480 {STRICT, true, GETHOSTBYNAME},
Ken Chenb9fa2062018-11-13 21:51:13 +08001481 {OFF, true, GETADDRINFO},
1482 {OPPORTUNISTIC, true, GETADDRINFO},
1483 {STRICT, true, GETADDRINFO},
Ken Chenb9fa2062018-11-13 21:51:13 +08001484 {OFF, true, GETADDRINFOFORNET},
1485 {OPPORTUNISTIC, true, GETADDRINFOFORNET},
1486 {STRICT, true, GETADDRINFOFORNET},
Mike Yudd4ac2d2019-05-31 16:52:11 +08001487 {OFF, false, GETHOSTBYNAME},
1488 {OPPORTUNISTIC, false, GETHOSTBYNAME},
1489 {STRICT, false, GETHOSTBYNAME},
1490 {OFF, false, GETADDRINFO},
1491 {OPPORTUNISTIC, false, GETADDRINFO},
1492 {STRICT, false, GETADDRINFO},
1493 {OFF, false, GETADDRINFOFORNET},
1494 {OPPORTUNISTIC, false, GETADDRINFOFORNET},
1495 {STRICT, false, GETADDRINFOFORNET},
Ken Chenb9fa2062018-11-13 21:51:13 +08001496 };
Luke Huangf8215372019-11-22 11:53:41 +08001497 // clang-format on
Ken Chenb9fa2062018-11-13 21:51:13 +08001498
1499 for (const auto& config : testConfigs) {
1500 const std::string testHostName = config.asHostName();
1501 SCOPED_TRACE(testHostName);
1502
1503 // Don't tempt test bugs due to caching.
1504 const char* host_name = testHostName.c_str();
1505 dns.addMapping(host_name, ns_type::ns_t_a, ADDR4);
1506 dns.addMapping(host_name, ns_type::ns_t_aaaa, ADDR6);
1507
Mike Yudd4ac2d2019-05-31 16:52:11 +08001508 if (config.withWorkingTLS) {
1509 if (!tls.running()) {
1510 ASSERT_TRUE(tls.startServer());
1511 }
1512 } else {
1513 if (tls.running()) {
1514 ASSERT_TRUE(tls.stopServer());
1515 }
1516 }
Ken Chenb9fa2062018-11-13 21:51:13 +08001517
1518 if (config.mode == OFF) {
Xiao Ma09b71022018-12-11 17:56:32 +09001519 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, kDefaultSearchDomains,
1520 kDefaultParams));
Ken Chenb9fa2062018-11-13 21:51:13 +08001521 } else if (config.mode == OPPORTUNISTIC) {
Xiao Ma09b71022018-12-11 17:56:32 +09001522 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08001523 kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08001524
1525 // Wait for the validation event. If the server is running, the validation should
1526 // be successful; otherwise, the validation should be failed.
1527 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), config.withWorkingTLS));
Ken Chenb9fa2062018-11-13 21:51:13 +08001528 } else if (config.mode == STRICT) {
Xiao Ma09b71022018-12-11 17:56:32 +09001529 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08001530 kDefaultParams, kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08001531
1532 // Wait for the validation event.
1533 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), config.withWorkingTLS));
Ken Chenb9fa2062018-11-13 21:51:13 +08001534 }
Mike Yudd4ac2d2019-05-31 16:52:11 +08001535 tls.clearQueries();
Ken Chenb9fa2062018-11-13 21:51:13 +08001536
1537 const hostent* h_result = nullptr;
1538 ScopedAddrinfo ai_result;
1539
1540 if (config.method == GETHOSTBYNAME) {
1541 ASSERT_EQ(0, setNetworkForResolv(BYPASS_NETID));
1542 h_result = gethostbyname(host_name);
1543
1544 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
1545 ASSERT_FALSE(h_result == nullptr);
1546 ASSERT_EQ(4, h_result->h_length);
1547 ASSERT_FALSE(h_result->h_addr_list[0] == nullptr);
1548 EXPECT_EQ(ADDR4, ToString(h_result));
1549 EXPECT_TRUE(h_result->h_addr_list[1] == nullptr);
1550 } else if (config.method == GETADDRINFO) {
1551 ASSERT_EQ(0, setNetworkForResolv(BYPASS_NETID));
1552 ai_result = safe_getaddrinfo(host_name, nullptr, nullptr);
1553 EXPECT_TRUE(ai_result != nullptr);
1554
1555 EXPECT_LE(1U, GetNumQueries(dns, host_name));
1556 // Could be A or AAAA
1557 const std::string result_str = ToString(ai_result);
1558 EXPECT_TRUE(result_str == ADDR4 || result_str == ADDR6)
Luke Huangf8215372019-11-22 11:53:41 +08001559 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +08001560 } else if (config.method == GETADDRINFOFORNET) {
1561 addrinfo* raw_ai_result = nullptr;
1562 EXPECT_EQ(0, android_getaddrinfofornet(host_name, /*servname=*/nullptr,
1563 /*hints=*/nullptr, BYPASS_NETID, MARK_UNSET,
1564 &raw_ai_result));
1565 ai_result.reset(raw_ai_result);
1566
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)
Luke Huangf8215372019-11-22 11:53:41 +08001571 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +08001572 }
1573
Mike Yudd4ac2d2019-05-31 16:52:11 +08001574 EXPECT_EQ(0, tls.queries());
Ken Chenb9fa2062018-11-13 21:51:13 +08001575
1576 // Clear per-process resolv netid.
1577 ASSERT_EQ(0, setNetworkForResolv(NETID_UNSET));
Ken Chenb9fa2062018-11-13 21:51:13 +08001578 dns.clearQueries();
1579 }
Ken Chenb9fa2062018-11-13 21:51:13 +08001580}
1581
1582TEST_F(ResolverTest, StrictMode_NoTlsServers) {
Xiao Ma09b71022018-12-11 17:56:32 +09001583 constexpr char cleartext_addr[] = "127.0.0.53";
Luke Huangf8215372019-11-22 11:53:41 +08001584 const std::vector<std::string> servers = {cleartext_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001585 constexpr char host_name[] = "strictmode.notlsips.example.com.";
1586 const std::vector<DnsRecord> records = {
1587 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1588 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1589 };
Ken Chenb9fa2062018-11-13 21:51:13 +08001590
Xiao Ma09b71022018-12-11 17:56:32 +09001591 test::DNSResponder dns(cleartext_addr);
1592 StartDns(dns, records);
Ken Chenb9fa2062018-11-13 21:51:13 +08001593
waynema0e73c2e2019-07-31 15:04:08 +08001594 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
1595 kDefaultIncorrectPrivateDnsHostName));
Ken Chenb9fa2062018-11-13 21:51:13 +08001596
1597 addrinfo* ai_result = nullptr;
1598 EXPECT_NE(0, getaddrinfo(host_name, nullptr, nullptr, &ai_result));
1599 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
1600}
Luke Huang94b10b92018-11-21 20:13:38 +08001601
1602namespace {
1603
Luke Huang70931aa2019-01-31 11:57:41 +08001604int getAsyncResponse(int fd, int* rcode, uint8_t* buf, int bufLen) {
Luke Huang94b10b92018-11-21 20:13:38 +08001605 struct pollfd wait_fd[1];
1606 wait_fd[0].fd = fd;
1607 wait_fd[0].events = POLLIN;
1608 short revents;
1609 int ret;
1610
1611 ret = poll(wait_fd, 1, -1);
1612 revents = wait_fd[0].revents;
1613 if (revents & POLLIN) {
1614 int n = resNetworkResult(fd, rcode, buf, bufLen);
Luke Huangba7bef92018-12-26 16:53:03 +08001615 // Verify that resNetworkResult() closed the fd
1616 char dummy;
1617 EXPECT_EQ(-1, read(fd, &dummy, sizeof dummy));
1618 EXPECT_EQ(EBADF, errno);
Luke Huang94b10b92018-11-21 20:13:38 +08001619 return n;
1620 }
1621 return -1;
1622}
1623
Luke Huang70931aa2019-01-31 11:57:41 +08001624std::string toString(uint8_t* buf, int bufLen, int ipType) {
Luke Huang94b10b92018-11-21 20:13:38 +08001625 ns_msg handle;
1626 int ancount, n = 0;
1627 ns_rr rr;
1628
Luke Huangf8215372019-11-22 11:53:41 +08001629 if (ns_initparse((const uint8_t*)buf, bufLen, &handle) >= 0) {
Luke Huang94b10b92018-11-21 20:13:38 +08001630 ancount = ns_msg_count(handle, ns_s_an);
1631 if (ns_parserr(&handle, ns_s_an, n, &rr) == 0) {
Luke Huang70931aa2019-01-31 11:57:41 +08001632 const uint8_t* rdata = ns_rr_rdata(rr);
Luke Huang94b10b92018-11-21 20:13:38 +08001633 char buffer[INET6_ADDRSTRLEN];
Luke Huangf8215372019-11-22 11:53:41 +08001634 if (inet_ntop(ipType, (const char*)rdata, buffer, sizeof(buffer))) {
Luke Huang94b10b92018-11-21 20:13:38 +08001635 return buffer;
1636 }
1637 }
1638 }
1639 return "";
1640}
1641
1642int dns_open_proxy() {
1643 int s = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
1644 if (s == -1) {
1645 return -1;
1646 }
1647 const int one = 1;
1648 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1649
1650 static const struct sockaddr_un proxy_addr = {
1651 .sun_family = AF_UNIX,
1652 .sun_path = "/dev/socket/dnsproxyd",
1653 };
1654
Luke Huangf8215372019-11-22 11:53:41 +08001655 if (TEMP_FAILURE_RETRY(connect(s, (const struct sockaddr*)&proxy_addr, sizeof(proxy_addr))) !=
Luke Huang94b10b92018-11-21 20:13:38 +08001656 0) {
1657 close(s);
1658 return -1;
1659 }
1660
1661 return s;
1662}
1663
Luke Huangba7bef92018-12-26 16:53:03 +08001664void expectAnswersValid(int fd, int ipType, const std::string& expectedAnswer) {
1665 int rcode = -1;
1666 uint8_t buf[MAXPACKET] = {};
1667
1668 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
1669 EXPECT_GT(res, 0);
1670 EXPECT_EQ(expectedAnswer, toString(buf, res, ipType));
1671}
1672
1673void expectAnswersNotValid(int fd, int expectedErrno) {
1674 int rcode = -1;
1675 uint8_t buf[MAXPACKET] = {};
1676
1677 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
1678 EXPECT_EQ(expectedErrno, res);
1679}
1680
Luke Huang94b10b92018-11-21 20:13:38 +08001681} // namespace
1682
1683TEST_F(ResolverTest, Async_NormalQueryV4V6) {
Xiao Ma09b71022018-12-11 17:56:32 +09001684 constexpr char listen_addr[] = "127.0.0.4";
1685 constexpr char host_name[] = "howdy.example.com.";
1686 const std::vector<DnsRecord> records = {
1687 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1688 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1689 };
1690
1691 test::DNSResponder dns(listen_addr);
1692 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001693 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001694 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001695
Luke Huangba7bef92018-12-26 16:53:03 +08001696 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
1697 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001698 EXPECT_TRUE(fd1 != -1);
1699 EXPECT_TRUE(fd2 != -1);
1700
Luke Huang70931aa2019-01-31 11:57:41 +08001701 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001702 int rcode;
1703 int res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
1704 EXPECT_GT(res, 0);
1705 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
1706
1707 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
1708 EXPECT_GT(res, 0);
1709 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
1710
1711 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
1712
1713 // Re-query verify cache works
Luke Huangba7bef92018-12-26 16:53:03 +08001714 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
1715 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001716
1717 EXPECT_TRUE(fd1 != -1);
1718 EXPECT_TRUE(fd2 != -1);
1719
1720 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
1731TEST_F(ResolverTest, Async_BadQuery) {
Xiao Ma09b71022018-12-11 17:56:32 +09001732 constexpr char listen_addr[] = "127.0.0.4";
1733 constexpr char host_name[] = "howdy.example.com.";
1734 const std::vector<DnsRecord> records = {
1735 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1736 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1737 };
1738
1739 test::DNSResponder dns(listen_addr);
1740 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001741 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001742 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001743
1744 static struct {
1745 int fd;
1746 const char* dname;
1747 const int queryType;
1748 const int expectRcode;
1749 } kTestData[] = {
Luke Huangba7bef92018-12-26 16:53:03 +08001750 {-1, "", ns_t_aaaa, 0},
1751 {-1, "as65ass46", ns_t_aaaa, 0},
1752 {-1, "454564564564", ns_t_aaaa, 0},
1753 {-1, "h645235", ns_t_a, 0},
1754 {-1, "www.google.com", ns_t_a, 0},
Luke Huang94b10b92018-11-21 20:13:38 +08001755 };
1756
1757 for (auto& td : kTestData) {
1758 SCOPED_TRACE(td.dname);
Luke Huangba7bef92018-12-26 16:53:03 +08001759 td.fd = resNetworkQuery(TEST_NETID, td.dname, ns_c_in, td.queryType, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001760 EXPECT_TRUE(td.fd != -1);
1761 }
1762
1763 // dns_responder return empty resp(packet only contains query part) with no error currently
1764 for (const auto& td : kTestData) {
Luke Huang70931aa2019-01-31 11:57:41 +08001765 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001766 int rcode;
1767 SCOPED_TRACE(td.dname);
1768 int res = getAsyncResponse(td.fd, &rcode, buf, MAXPACKET);
1769 EXPECT_GT(res, 0);
1770 EXPECT_EQ(rcode, td.expectRcode);
1771 }
1772}
1773
1774TEST_F(ResolverTest, Async_EmptyAnswer) {
Xiao Ma09b71022018-12-11 17:56:32 +09001775 constexpr char listen_addr[] = "127.0.0.4";
1776 constexpr char host_name[] = "howdy.example.com.";
1777 const std::vector<DnsRecord> records = {
1778 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1779 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1780 };
1781
1782 test::DNSResponder dns(listen_addr);
1783 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001784 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001785 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001786
Luke Huang9c264bb2018-12-18 16:44:41 +08001787 // TODO: Disable retry to make this test explicit.
1788 auto& cv = dns.getCv();
1789 auto& cvMutex = dns.getCvMutex();
1790 int fd1;
1791 // Wait on the condition variable to ensure that the DNS server has handled our first query.
1792 {
1793 std::unique_lock lk(cvMutex);
Luke Huangba7bef92018-12-26 16:53:03 +08001794 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huang9c264bb2018-12-18 16:44:41 +08001795 EXPECT_TRUE(fd1 != -1);
1796 EXPECT_EQ(std::cv_status::no_timeout, cv.wait_for(lk, std::chrono::seconds(1)));
1797 }
Luke Huang94b10b92018-11-21 20:13:38 +08001798
Luke Huang94b10b92018-11-21 20:13:38 +08001799 dns.setResponseProbability(0.0);
Luke Huang94b10b92018-11-21 20:13:38 +08001800
Luke Huangba7bef92018-12-26 16:53:03 +08001801 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001802 EXPECT_TRUE(fd2 != -1);
1803
Luke Huangba7bef92018-12-26 16:53:03 +08001804 int fd3 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001805 EXPECT_TRUE(fd3 != -1);
1806
Luke Huang9c264bb2018-12-18 16:44:41 +08001807 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001808 int rcode;
1809
Luke Huang9c264bb2018-12-18 16:44:41 +08001810 // expect no response
1811 int res = getAsyncResponse(fd3, &rcode, buf, MAXPACKET);
1812 EXPECT_EQ(-ETIMEDOUT, res);
Luke Huang94b10b92018-11-21 20:13:38 +08001813
Luke Huang9c264bb2018-12-18 16:44:41 +08001814 // expect no response
Luke Huang94b10b92018-11-21 20:13:38 +08001815 memset(buf, 0, MAXPACKET);
Luke Huang9c264bb2018-12-18 16:44:41 +08001816 res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
1817 EXPECT_EQ(-ETIMEDOUT, res);
Luke Huang94b10b92018-11-21 20:13:38 +08001818
Luke Huang94b10b92018-11-21 20:13:38 +08001819 dns.setResponseProbability(1.0);
Luke Huang94b10b92018-11-21 20:13:38 +08001820
Luke Huangba7bef92018-12-26 16:53:03 +08001821 int fd4 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001822 EXPECT_TRUE(fd4 != -1);
1823
1824 memset(buf, 0, MAXPACKET);
1825 res = getAsyncResponse(fd4, &rcode, buf, MAXPACKET);
1826 EXPECT_GT(res, 0);
1827 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
1828
1829 memset(buf, 0, MAXPACKET);
1830 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
1831 EXPECT_GT(res, 0);
1832 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
1833}
1834
1835TEST_F(ResolverTest, Async_MalformedQuery) {
Xiao Ma09b71022018-12-11 17:56:32 +09001836 constexpr char listen_addr[] = "127.0.0.4";
1837 constexpr char host_name[] = "howdy.example.com.";
1838 const std::vector<DnsRecord> records = {
1839 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1840 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1841 };
1842
1843 test::DNSResponder dns(listen_addr);
1844 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001845 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001846 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001847
1848 int fd = dns_open_proxy();
1849 EXPECT_TRUE(fd > 0);
1850
1851 const std::string badMsg = "16-52512#";
Xiao Ma09b71022018-12-11 17:56:32 +09001852 static const struct {
Luke Huang94b10b92018-11-21 20:13:38 +08001853 const std::string cmd;
1854 const int expectErr;
1855 } kTestData[] = {
Luke Huangba7bef92018-12-26 16:53:03 +08001856 // Too few arguments
Luke Huang94b10b92018-11-21 20:13:38 +08001857 {"resnsend " + badMsg + '\0', -EINVAL},
1858 // Bad netId
Luke Huangba7bef92018-12-26 16:53:03 +08001859 {"resnsend badnetId 0 " + badMsg + '\0', -EINVAL},
Luke Huang94b10b92018-11-21 20:13:38 +08001860 // Bad raw data
Luke Huangba7bef92018-12-26 16:53:03 +08001861 {"resnsend " + std::to_string(TEST_NETID) + " 0 " + badMsg + '\0', -EILSEQ},
Luke Huang94b10b92018-11-21 20:13:38 +08001862 };
1863
1864 for (unsigned int i = 0; i < std::size(kTestData); i++) {
1865 auto& td = kTestData[i];
1866 SCOPED_TRACE(td.cmd);
1867 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, td.cmd.c_str(), td.cmd.size()));
1868 EXPECT_EQ(rc, static_cast<ssize_t>(td.cmd.size()));
1869
1870 int32_t tmp;
1871 rc = TEMP_FAILURE_RETRY(read(fd, &tmp, sizeof(tmp)));
1872 EXPECT_TRUE(rc > 0);
1873 EXPECT_EQ(static_cast<int>(ntohl(tmp)), td.expectErr);
1874 }
1875 // Normal query with answer buffer
1876 // This is raw data of query "howdy.example.com" type 1 class 1
1877 std::string query = "81sBAAABAAAAAAAABWhvd2R5B2V4YW1wbGUDY29tAAABAAE=";
Luke Huangba7bef92018-12-26 16:53:03 +08001878 std::string cmd = "resnsend " + std::to_string(TEST_NETID) + " 0 " + query + '\0';
Luke Huang94b10b92018-11-21 20:13:38 +08001879 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size()));
1880 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size()));
1881
Luke Huang70931aa2019-01-31 11:57:41 +08001882 uint8_t smallBuf[1] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001883 int rcode;
1884 rc = getAsyncResponse(fd, &rcode, smallBuf, 1);
Luke Huangba7bef92018-12-26 16:53:03 +08001885 EXPECT_EQ(-EMSGSIZE, rc);
Luke Huang94b10b92018-11-21 20:13:38 +08001886
1887 // Do the normal test with large buffer again
1888 fd = dns_open_proxy();
1889 EXPECT_TRUE(fd > 0);
1890 rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size()));
1891 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size()));
Luke Huang70931aa2019-01-31 11:57:41 +08001892 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001893 rc = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
1894 EXPECT_EQ("1.2.3.4", toString(buf, rc, AF_INET));
Mike Yu4f3747b2018-12-02 17:54:29 +09001895}
1896
Luke Huangba7bef92018-12-26 16:53:03 +08001897TEST_F(ResolverTest, Async_CacheFlags) {
Xiao Ma09b71022018-12-11 17:56:32 +09001898 constexpr char listen_addr[] = "127.0.0.4";
1899 constexpr char host_name[] = "howdy.example.com.";
Luke Huang40f5f492019-05-09 19:37:35 +08001900 constexpr char another_host_name[] = "howdy.example2.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09001901 const std::vector<DnsRecord> records = {
1902 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1903 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
Luke Huang40f5f492019-05-09 19:37:35 +08001904 {another_host_name, ns_type::ns_t_a, "1.2.3.5"},
1905 {another_host_name, ns_type::ns_t_aaaa, "::1.2.3.5"},
Xiao Ma09b71022018-12-11 17:56:32 +09001906 };
1907
1908 test::DNSResponder dns(listen_addr);
1909 StartDns(dns, records);
Luke Huangba7bef92018-12-26 16:53:03 +08001910 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001911 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huangba7bef92018-12-26 16:53:03 +08001912
1913 // ANDROID_RESOLV_NO_CACHE_STORE
1914 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1915 ANDROID_RESOLV_NO_CACHE_STORE);
1916 EXPECT_TRUE(fd1 != -1);
1917 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1918 ANDROID_RESOLV_NO_CACHE_STORE);
1919 EXPECT_TRUE(fd2 != -1);
1920 int fd3 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1921 ANDROID_RESOLV_NO_CACHE_STORE);
1922 EXPECT_TRUE(fd3 != -1);
1923
1924 expectAnswersValid(fd3, AF_INET, "1.2.3.4");
1925 expectAnswersValid(fd2, AF_INET, "1.2.3.4");
1926 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
1927
1928 // No cache exists, expect 3 queries
1929 EXPECT_EQ(3U, GetNumQueries(dns, host_name));
1930
1931 // Re-query and cache
1932 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
1933
1934 EXPECT_TRUE(fd1 != -1);
1935
1936 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
1937
1938 // Now we have cache, expect 4 queries
1939 EXPECT_EQ(4U, GetNumQueries(dns, host_name));
1940
1941 // ANDROID_RESOLV_NO_CACHE_LOOKUP
1942 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1943 ANDROID_RESOLV_NO_CACHE_LOOKUP);
1944 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1945 ANDROID_RESOLV_NO_CACHE_LOOKUP);
1946
1947 EXPECT_TRUE(fd1 != -1);
1948 EXPECT_TRUE(fd2 != -1);
1949
1950 expectAnswersValid(fd2, AF_INET, "1.2.3.4");
1951 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
1952
1953 // Skip cache, expect 6 queries
1954 EXPECT_EQ(6U, GetNumQueries(dns, host_name));
1955
1956 // Re-query verify cache works
1957 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1958 ANDROID_RESOLV_NO_CACHE_STORE);
1959 EXPECT_TRUE(fd1 != -1);
1960 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
1961
1962 // Cache hits, expect still 6 queries
1963 EXPECT_EQ(6U, GetNumQueries(dns, host_name));
Luke Huanga1d74182019-03-19 17:30:36 +08001964
1965 // Start to verify if ANDROID_RESOLV_NO_CACHE_LOOKUP does write response into cache
1966 dns.clearQueries();
1967
1968 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
1969 ANDROID_RESOLV_NO_CACHE_LOOKUP);
1970 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
1971 ANDROID_RESOLV_NO_CACHE_LOOKUP);
1972
1973 EXPECT_TRUE(fd1 != -1);
1974 EXPECT_TRUE(fd2 != -1);
1975
1976 expectAnswersValid(fd2, AF_INET6, "::1.2.3.4");
1977 expectAnswersValid(fd1, AF_INET6, "::1.2.3.4");
1978
1979 // Skip cache, expect 2 queries
1980 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
1981
1982 // Re-query without flags
1983 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
1984 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
1985
1986 EXPECT_TRUE(fd1 != -1);
1987 EXPECT_TRUE(fd2 != -1);
1988
1989 expectAnswersValid(fd2, AF_INET6, "::1.2.3.4");
1990 expectAnswersValid(fd1, AF_INET6, "::1.2.3.4");
1991
1992 // Cache hits, expect still 2 queries
1993 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
Luke Huang40f5f492019-05-09 19:37:35 +08001994
1995 // Test both ANDROID_RESOLV_NO_CACHE_STORE and ANDROID_RESOLV_NO_CACHE_LOOKUP are set
1996 dns.clearQueries();
1997
1998 // Make sure that the cache of "howdy.example2.com" exists.
1999 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_aaaa, 0);
2000 EXPECT_TRUE(fd1 != -1);
2001 expectAnswersValid(fd1, AF_INET6, "::1.2.3.5");
2002 EXPECT_EQ(1U, GetNumQueries(dns, another_host_name));
2003
2004 // Re-query with testFlags
2005 const int testFlag = ANDROID_RESOLV_NO_CACHE_STORE | ANDROID_RESOLV_NO_CACHE_LOOKUP;
2006 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_aaaa, testFlag);
2007 EXPECT_TRUE(fd1 != -1);
2008 expectAnswersValid(fd1, AF_INET6, "::1.2.3.5");
2009 // Expect cache lookup is skipped.
2010 EXPECT_EQ(2U, GetNumQueries(dns, another_host_name));
2011
2012 // Do another query with testFlags
2013 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_a, testFlag);
2014 EXPECT_TRUE(fd1 != -1);
2015 expectAnswersValid(fd1, AF_INET, "1.2.3.5");
2016 // Expect cache lookup is skipped.
2017 EXPECT_EQ(3U, GetNumQueries(dns, another_host_name));
2018
2019 // Re-query with no flags
2020 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_a, 0);
2021 EXPECT_TRUE(fd1 != -1);
2022 expectAnswersValid(fd1, AF_INET, "1.2.3.5");
2023 // Expect no cache hit because cache storing is also skipped in previous query.
2024 EXPECT_EQ(4U, GetNumQueries(dns, another_host_name));
Luke Huangba7bef92018-12-26 16:53:03 +08002025}
2026
2027TEST_F(ResolverTest, Async_NoRetryFlag) {
Luke Huang70931aa2019-01-31 11:57:41 +08002028 constexpr char listen_addr0[] = "127.0.0.4";
2029 constexpr char listen_addr1[] = "127.0.0.6";
Xiao Ma09b71022018-12-11 17:56:32 +09002030 constexpr char host_name[] = "howdy.example.com.";
2031 const std::vector<DnsRecord> records = {
2032 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2033 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
2034 };
2035
Luke Huang70931aa2019-01-31 11:57:41 +08002036 test::DNSResponder dns0(listen_addr0);
2037 test::DNSResponder dns1(listen_addr1);
2038 StartDns(dns0, records);
2039 StartDns(dns1, records);
2040 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr0, listen_addr1}));
Luke Huangba7bef92018-12-26 16:53:03 +08002041
Luke Huang70931aa2019-01-31 11:57:41 +08002042 dns0.clearQueries();
2043 dns1.clearQueries();
2044
2045 dns0.setResponseProbability(0.0);
2046 dns1.setResponseProbability(0.0);
Luke Huangba7bef92018-12-26 16:53:03 +08002047
2048 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2049 ANDROID_RESOLV_NO_RETRY);
2050 EXPECT_TRUE(fd1 != -1);
2051
2052 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
2053 ANDROID_RESOLV_NO_RETRY);
2054 EXPECT_TRUE(fd2 != -1);
2055
2056 // expect no response
2057 expectAnswersNotValid(fd1, -ETIMEDOUT);
2058 expectAnswersNotValid(fd2, -ETIMEDOUT);
2059
Luke Huang70931aa2019-01-31 11:57:41 +08002060 // No retry case, expect total 2 queries. The server is selected randomly.
2061 EXPECT_EQ(2U, GetNumQueries(dns0, host_name) + GetNumQueries(dns1, host_name));
Luke Huangba7bef92018-12-26 16:53:03 +08002062
Luke Huang70931aa2019-01-31 11:57:41 +08002063 dns0.clearQueries();
2064 dns1.clearQueries();
Luke Huangba7bef92018-12-26 16:53:03 +08002065
2066 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
2067 EXPECT_TRUE(fd1 != -1);
2068
2069 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
2070 EXPECT_TRUE(fd2 != -1);
2071
2072 // expect no response
2073 expectAnswersNotValid(fd1, -ETIMEDOUT);
2074 expectAnswersNotValid(fd2, -ETIMEDOUT);
2075
2076 // Retry case, expect 4 queries
Luke Huang70931aa2019-01-31 11:57:41 +08002077 EXPECT_EQ(4U, GetNumQueries(dns0, host_name));
2078 EXPECT_EQ(4U, GetNumQueries(dns1, host_name));
2079}
2080
2081TEST_F(ResolverTest, Async_VerifyQueryID) {
2082 constexpr char listen_addr[] = "127.0.0.4";
2083 constexpr char host_name[] = "howdy.example.com.";
2084 const std::vector<DnsRecord> records = {
2085 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2086 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
2087 };
2088
2089 test::DNSResponder dns(listen_addr);
2090 StartDns(dns, records);
2091 std::vector<std::string> servers = {listen_addr};
2092 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
2093
2094 const uint8_t queryBuf1[] = {
2095 /* Header */
2096 0x55, 0x66, /* Transaction ID */
2097 0x01, 0x00, /* Flags */
2098 0x00, 0x01, /* Questions */
2099 0x00, 0x00, /* Answer RRs */
2100 0x00, 0x00, /* Authority RRs */
2101 0x00, 0x00, /* Additional RRs */
2102 /* Queries */
2103 0x05, 0x68, 0x6f, 0x77, 0x64, 0x79, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
2104 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
2105 0x00, 0x01, /* Type */
2106 0x00, 0x01 /* Class */
2107 };
2108
2109 int fd = resNetworkSend(TEST_NETID, queryBuf1, sizeof(queryBuf1), 0);
2110 EXPECT_TRUE(fd != -1);
2111
2112 uint8_t buf[MAXPACKET] = {};
2113 int rcode;
2114
2115 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
2116 EXPECT_GT(res, 0);
2117 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
2118
2119 auto hp = reinterpret_cast<HEADER*>(buf);
2120 EXPECT_EQ(21862U, htons(hp->id));
2121
2122 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
2123
2124 const uint8_t queryBuf2[] = {
2125 /* Header */
2126 0x00, 0x53, /* Transaction ID */
2127 0x01, 0x00, /* Flags */
2128 0x00, 0x01, /* Questions */
2129 0x00, 0x00, /* Answer RRs */
2130 0x00, 0x00, /* Authority RRs */
2131 0x00, 0x00, /* Additional RRs */
2132 /* Queries */
2133 0x05, 0x68, 0x6f, 0x77, 0x64, 0x79, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
2134 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
2135 0x00, 0x01, /* Type */
2136 0x00, 0x01 /* Class */
2137 };
2138
2139 // Re-query verify cache works and query id is correct
2140 fd = resNetworkSend(TEST_NETID, queryBuf2, sizeof(queryBuf2), 0);
2141
2142 EXPECT_TRUE(fd != -1);
2143
2144 res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
2145 EXPECT_GT(res, 0);
2146 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
2147
2148 EXPECT_EQ(0x0053U, htons(hp->id));
2149
2150 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
Luke Huangba7bef92018-12-26 16:53:03 +08002151}
2152
Mike Yu4f3747b2018-12-02 17:54:29 +09002153// This test checks that the resolver should not generate the request containing OPT RR when using
Ken Chen0a015532019-01-02 14:59:38 +08002154// cleartext DNS. If we query the DNS server not supporting EDNS0 and it reponds with
2155// FORMERR_ON_EDNS, we will fallback to no EDNS0 and try again. If the server does no response, we
2156// won't retry so that we get no answer.
Mike Yu4f3747b2018-12-02 17:54:29 +09002157TEST_F(ResolverTest, BrokenEdns) {
2158 typedef test::DNSResponder::Edns Edns;
2159 enum ExpectResult { EXPECT_FAILURE, EXPECT_SUCCESS };
2160
2161 const char OFF[] = "off";
2162 const char OPPORTUNISTIC_UDP[] = "opportunistic_udp";
2163 const char OPPORTUNISTIC_TLS[] = "opportunistic_tls";
2164 const char STRICT[] = "strict";
2165 const char GETHOSTBYNAME[] = "gethostbyname";
2166 const char GETADDRINFO[] = "getaddrinfo";
Mike Yu4f3747b2018-12-02 17:54:29 +09002167 const char ADDR4[] = "192.0.2.1";
2168 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2169 const char CLEARTEXT_PORT[] = "53";
2170 const char TLS_PORT[] = "853";
Luke Huangf8215372019-11-22 11:53:41 +08002171 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
Mike Yu4f3747b2018-12-02 17:54:29 +09002172
Mike Yufc125e42019-05-15 20:41:28 +08002173 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, ns_rcode::ns_r_servfail);
Mike Yu4f3747b2018-12-02 17:54:29 +09002174 ASSERT_TRUE(dns.startServer());
2175
2176 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2177
Luke Huangf8215372019-11-22 11:53:41 +08002178 // clang-format off
Mike Yu4f3747b2018-12-02 17:54:29 +09002179 static const struct TestConfig {
2180 std::string mode;
2181 std::string method;
2182 Edns edns;
2183 ExpectResult expectResult;
2184
2185 std::string asHostName() const {
2186 const char* ednsString;
2187 switch (edns) {
2188 case Edns::ON:
2189 ednsString = "ednsOn";
2190 break;
Ken Chen0a015532019-01-02 14:59:38 +08002191 case Edns::FORMERR_ON_EDNS:
Mike Yu4f3747b2018-12-02 17:54:29 +09002192 ednsString = "ednsFormerr";
2193 break;
2194 case Edns::DROP:
2195 ednsString = "ednsDrop";
2196 break;
2197 default:
2198 ednsString = "";
2199 break;
2200 }
2201 return StringPrintf("%s.%s.%s.", mode.c_str(), method.c_str(), ednsString);
2202 }
2203 } testConfigs[] = {
2204 // In OPPORTUNISTIC_TLS, we get no answer if the DNS server supports TLS but not EDNS0.
2205 // Could such server exist? if so, we might need to fallback to query cleartext DNS.
2206 // Another thing is that {OPPORTUNISTIC_TLS, Edns::DROP} and {STRICT, Edns::DROP} are
2207 // commented out since TLS timeout is not configurable.
2208 // TODO: Uncomment them after TLS timeout is configurable.
2209 {OFF, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2210 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2211 {OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2212 {STRICT, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
Ken Chen0a015532019-01-02 14:59:38 +08002213 {OFF, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2214 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2215 {OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
2216 {STRICT, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
Mike Yu4f3747b2018-12-02 17:54:29 +09002217 {OFF, GETHOSTBYNAME, Edns::DROP, EXPECT_SUCCESS},
2218 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::DROP, EXPECT_SUCCESS},
2219 //{OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::DROP, EXPECT_FAILURE},
2220 //{STRICT, GETHOSTBYNAME, Edns::DROP, EXPECT_FAILURE},
2221 {OFF, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2222 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2223 {OPPORTUNISTIC_TLS, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2224 {STRICT, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
Ken Chen0a015532019-01-02 14:59:38 +08002225 {OFF, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2226 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2227 {OPPORTUNISTIC_TLS, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
2228 {STRICT, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
Mike Yu4f3747b2018-12-02 17:54:29 +09002229 {OFF, GETADDRINFO, Edns::DROP, EXPECT_SUCCESS},
2230 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::DROP, EXPECT_SUCCESS},
2231 //{OPPORTUNISTIC_TLS, GETADDRINFO, Edns::DROP, EXPECT_FAILURE},
2232 //{STRICT, GETADDRINFO, Edns::DROP, EXPECT_FAILURE},
2233 };
Luke Huangf8215372019-11-22 11:53:41 +08002234 // clang-format on
Mike Yu4f3747b2018-12-02 17:54:29 +09002235
2236 for (const auto& config : testConfigs) {
2237 const std::string testHostName = config.asHostName();
2238 SCOPED_TRACE(testHostName);
2239
2240 const char* host_name = testHostName.c_str();
2241 dns.addMapping(host_name, ns_type::ns_t_a, ADDR4);
2242 dns.setEdns(config.edns);
2243
2244 if (config.mode == OFF) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002245 if (tls.running()) {
2246 ASSERT_TRUE(tls.stopServer());
2247 }
Xiao Ma09b71022018-12-11 17:56:32 +09002248 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Mike Yu4f3747b2018-12-02 17:54:29 +09002249 } else if (config.mode == OPPORTUNISTIC_UDP) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002250 if (tls.running()) {
2251 ASSERT_TRUE(tls.stopServer());
2252 }
Xiao Ma09b71022018-12-11 17:56:32 +09002253 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08002254 kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002255 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), false));
Mike Yu4f3747b2018-12-02 17:54:29 +09002256 } else if (config.mode == OPPORTUNISTIC_TLS) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002257 if (!tls.running()) {
2258 ASSERT_TRUE(tls.startServer());
2259 }
Xiao Ma09b71022018-12-11 17:56:32 +09002260 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08002261 kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002262 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yu4f3747b2018-12-02 17:54:29 +09002263 } else if (config.mode == STRICT) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002264 if (!tls.running()) {
2265 ASSERT_TRUE(tls.startServer());
2266 }
Xiao Ma09b71022018-12-11 17:56:32 +09002267 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08002268 kDefaultParams, kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08002269 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yu4f3747b2018-12-02 17:54:29 +09002270 }
2271
2272 if (config.method == GETHOSTBYNAME) {
2273 const hostent* h_result = gethostbyname(host_name);
2274 if (config.expectResult == EXPECT_SUCCESS) {
2275 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2276 ASSERT_TRUE(h_result != nullptr);
2277 ASSERT_EQ(4, h_result->h_length);
2278 ASSERT_FALSE(h_result->h_addr_list[0] == nullptr);
2279 EXPECT_EQ(ADDR4, ToString(h_result));
2280 EXPECT_TRUE(h_result->h_addr_list[1] == nullptr);
2281 } else {
2282 EXPECT_EQ(0U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
2283 ASSERT_TRUE(h_result == nullptr);
2284 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2285 }
2286 } else if (config.method == GETADDRINFO) {
2287 ScopedAddrinfo ai_result;
2288 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2289 ai_result = safe_getaddrinfo(host_name, nullptr, &hints);
2290 if (config.expectResult == EXPECT_SUCCESS) {
2291 EXPECT_TRUE(ai_result != nullptr);
2292 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
2293 const std::string result_str = ToString(ai_result);
2294 EXPECT_EQ(ADDR4, result_str);
2295 } else {
2296 EXPECT_TRUE(ai_result == nullptr);
2297 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
2298 }
2299 } else {
2300 FAIL() << "Unsupported query method: " << config.method;
2301 }
2302
Mike Yudd4ac2d2019-05-31 16:52:11 +08002303 tls.clearQueries();
Mike Yu4f3747b2018-12-02 17:54:29 +09002304 dns.clearQueries();
2305 }
Mike Yu4f3747b2018-12-02 17:54:29 +09002306}
nuccachena26cc2a2018-07-17 18:07:23 +08002307
Ken Chen0a015532019-01-02 14:59:38 +08002308// DNS-over-TLS validation success, but server does not respond to TLS query after a while.
2309// Resolver should have a reasonable number of retries instead of spinning forever. We don't have
2310// an efficient way to know if resolver is stuck in an infinite loop. However, test case will be
2311// failed due to timeout.
2312TEST_F(ResolverTest, UnstableTls) {
2313 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2314 const char CLEARTEXT_PORT[] = "53";
2315 const char TLS_PORT[] = "853";
2316 const char* host_name1 = "nonexistent1.example.com.";
2317 const char* host_name2 = "nonexistent2.example.com.";
2318 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
2319
Mike Yufc125e42019-05-15 20:41:28 +08002320 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, ns_rcode::ns_r_servfail);
Ken Chen0a015532019-01-02 14:59:38 +08002321 ASSERT_TRUE(dns.startServer());
2322 dns.setEdns(test::DNSResponder::Edns::FORMERR_ON_EDNS);
2323 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2324 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08002325 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002326 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
2327
Ken Chen0a015532019-01-02 14:59:38 +08002328 // Shutdown TLS server to get an error. It's similar to no response case but without waiting.
2329 tls.stopServer();
2330
2331 const hostent* h_result = gethostbyname(host_name1);
2332 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
2333 ASSERT_TRUE(h_result == nullptr);
2334 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2335
2336 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2337 ScopedAddrinfo ai_result = safe_getaddrinfo(host_name2, nullptr, &hints);
2338 EXPECT_TRUE(ai_result == nullptr);
2339 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
2340}
2341
2342// DNS-over-TLS validation success, but server does not respond to TLS query after a while.
2343// Moreover, server responds RCODE=FORMERR even on non-EDNS query.
2344TEST_F(ResolverTest, BogusDnsServer) {
2345 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2346 const char CLEARTEXT_PORT[] = "53";
2347 const char TLS_PORT[] = "853";
2348 const char* host_name1 = "nonexistent1.example.com.";
2349 const char* host_name2 = "nonexistent2.example.com.";
2350 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
2351
Mike Yufc125e42019-05-15 20:41:28 +08002352 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, ns_rcode::ns_r_servfail);
Ken Chen0a015532019-01-02 14:59:38 +08002353 ASSERT_TRUE(dns.startServer());
2354 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2355 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08002356 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002357 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
2358
Ken Chen0a015532019-01-02 14:59:38 +08002359 // Shutdown TLS server to get an error. It's similar to no response case but without waiting.
2360 tls.stopServer();
2361 dns.setEdns(test::DNSResponder::Edns::FORMERR_UNCOND);
2362
2363 const hostent* h_result = gethostbyname(host_name1);
2364 EXPECT_EQ(0U, GetNumQueries(dns, host_name1));
2365 ASSERT_TRUE(h_result == nullptr);
2366 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2367
2368 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2369 ScopedAddrinfo ai_result = safe_getaddrinfo(host_name2, nullptr, &hints);
2370 EXPECT_TRUE(ai_result == nullptr);
2371 EXPECT_EQ(0U, GetNumQueries(dns, host_name2));
2372}
2373
nuccachena26cc2a2018-07-17 18:07:23 +08002374TEST_F(ResolverTest, GetAddrInfo_Dns64Synthesize) {
2375 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002376 constexpr char dns64_name[] = "ipv4only.arpa.";
2377 constexpr char host_name[] = "v4only.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002378 const std::vector<DnsRecord> records = {
2379 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2380 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2381 };
nuccachena26cc2a2018-07-17 18:07:23 +08002382
Xiao Ma09b71022018-12-11 17:56:32 +09002383 test::DNSResponder dns(listen_addr);
Xiao Ma09b71022018-12-11 17:56:32 +09002384 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002385
2386 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002387 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002388
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002389 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002390 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002391 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002392
2393 // hints are necessary in order to let netd know which type of addresses the caller is
2394 // interested in.
Xiao Ma09b71022018-12-11 17:56:32 +09002395 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachena26cc2a2018-07-17 18:07:23 +08002396 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, &hints);
2397 EXPECT_TRUE(result != nullptr);
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002398 // TODO: BUG: there should only be two queries, one AAAA (which returns no records) and one A
2399 // (which returns 1.2.3.4). But there is an extra AAAA.
2400 EXPECT_EQ(3U, GetNumQueries(dns, host_name));
nuccachena26cc2a2018-07-17 18:07:23 +08002401
2402 std::string result_str = ToString(result);
2403 EXPECT_EQ(result_str, "64:ff9b::102:304");
2404
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002405 // Stopping NAT64 prefix discovery disables synthesis.
Luke Huang5bd827c2019-03-14 16:10:04 +08002406 EXPECT_TRUE(mDnsClient.resolvService()->stopPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002407 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_NOT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002408
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002409 dns.clearQueries();
nuccachena26cc2a2018-07-17 18:07:23 +08002410
2411 result = safe_getaddrinfo("v4only", nullptr, &hints);
2412 EXPECT_TRUE(result != nullptr);
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002413 // TODO: BUG: there should only be one query, an AAAA (which returns no records), because the
2414 // A is already cached. But there is an extra AAAA.
2415 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
nuccachena26cc2a2018-07-17 18:07:23 +08002416
2417 result_str = ToString(result);
2418 EXPECT_EQ(result_str, "1.2.3.4");
2419}
2420
nuccachena26cc2a2018-07-17 18:07:23 +08002421TEST_F(ResolverTest, GetAddrInfo_Dns64QuerySpecified) {
2422 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002423 constexpr char dns64_name[] = "ipv4only.arpa.";
2424 constexpr char host_name[] = "v4only.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002425 const std::vector<DnsRecord> records = {
2426 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2427 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2428 };
nuccachena26cc2a2018-07-17 18:07:23 +08002429
Xiao Ma09b71022018-12-11 17:56:32 +09002430 test::DNSResponder dns(listen_addr);
2431 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002432 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002433 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002434
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002435 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002436 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002437 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002438
2439 // Ensure to synthesize AAAA if AF_INET6 is specified, and not to synthesize AAAA
2440 // in AF_INET case.
2441 addrinfo hints;
2442 memset(&hints, 0, sizeof(hints));
2443 hints.ai_family = AF_INET6;
2444 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, &hints);
2445 EXPECT_TRUE(result != nullptr);
2446 std::string result_str = ToString(result);
2447 EXPECT_EQ(result_str, "64:ff9b::102:304");
2448
2449 hints.ai_family = AF_INET;
2450 result = safe_getaddrinfo("v4only", nullptr, &hints);
2451 EXPECT_TRUE(result != nullptr);
2452 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2453 result_str = ToString(result);
2454 EXPECT_EQ(result_str, "1.2.3.4");
2455}
nuccachena26cc2a2018-07-17 18:07:23 +08002456
2457TEST_F(ResolverTest, GetAddrInfo_Dns64QueryUnspecifiedV6) {
2458 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002459 constexpr char dns64_name[] = "ipv4only.arpa.";
2460 constexpr char host_name[] = "v4v6.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002461 const std::vector<DnsRecord> records = {
2462 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2463 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2464 {host_name, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
2465 };
nuccachena26cc2a2018-07-17 18:07:23 +08002466
Xiao Ma09b71022018-12-11 17:56:32 +09002467 test::DNSResponder dns(listen_addr);
2468 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002469 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002470 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002471
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002472 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002473 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002474 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002475
Xiao Ma09b71022018-12-11 17:56:32 +09002476 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachena26cc2a2018-07-17 18:07:23 +08002477 ScopedAddrinfo result = safe_getaddrinfo("v4v6", nullptr, &hints);
2478 EXPECT_TRUE(result != nullptr);
2479 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2480
2481 // In AF_UNSPEC case, do not synthesize AAAA if there's at least one AAAA answer.
Xiao Ma09b71022018-12-11 17:56:32 +09002482 const std::vector<std::string> result_strs = ToStrings(result);
nuccachena26cc2a2018-07-17 18:07:23 +08002483 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_Dns64QueryUnspecifiedNoV6) {
2490 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002491 constexpr char dns64_name[] = "ipv4only.arpa.";
2492 constexpr char host_name[] = "v4v6.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002493 const std::vector<DnsRecord> records = {
2494 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2495 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2496 };
nuccachena26cc2a2018-07-17 18:07:23 +08002497
Xiao Ma09b71022018-12-11 17:56:32 +09002498 test::DNSResponder dns(listen_addr);
2499 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002500 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002501 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002502
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002503 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002504 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002505 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002506
Xiao Ma09b71022018-12-11 17:56:32 +09002507 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachena26cc2a2018-07-17 18:07:23 +08002508 ScopedAddrinfo result = safe_getaddrinfo("v4v6", nullptr, &hints);
2509 EXPECT_TRUE(result != nullptr);
2510 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2511
2512 // In AF_UNSPEC case, synthesize AAAA if there's no AAAA answer.
2513 std::string result_str = ToString(result);
2514 EXPECT_EQ(result_str, "64:ff9b::102:304");
2515}
2516
2517TEST_F(ResolverTest, GetAddrInfo_Dns64QuerySpecialUseIPv4Addresses) {
2518 constexpr char THIS_NETWORK[] = "this_network";
2519 constexpr char LOOPBACK[] = "loopback";
2520 constexpr char LINK_LOCAL[] = "link_local";
2521 constexpr char MULTICAST[] = "multicast";
2522 constexpr char LIMITED_BROADCAST[] = "limited_broadcast";
2523
2524 constexpr char ADDR_THIS_NETWORK[] = "0.0.0.1";
2525 constexpr char ADDR_LOOPBACK[] = "127.0.0.1";
2526 constexpr char ADDR_LINK_LOCAL[] = "169.254.0.1";
2527 constexpr char ADDR_MULTICAST[] = "224.0.0.1";
2528 constexpr char ADDR_LIMITED_BROADCAST[] = "255.255.255.255";
2529
2530 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002531 constexpr char dns64_name[] = "ipv4only.arpa.";
2532
Xiao Ma09b71022018-12-11 17:56:32 +09002533 test::DNSResponder dns(listen_addr);
2534 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachena26cc2a2018-07-17 18:07:23 +08002535 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002536 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002537
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002538 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002539 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002540 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002541
Luke Huangf8215372019-11-22 11:53:41 +08002542 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08002543 static const struct TestConfig {
2544 std::string name;
2545 std::string addr;
2546
2547 std::string asHostName() const { return StringPrintf("%s.example.com.", name.c_str()); }
2548 } testConfigs[]{
2549 {THIS_NETWORK, ADDR_THIS_NETWORK},
2550 {LOOPBACK, ADDR_LOOPBACK},
2551 {LINK_LOCAL, ADDR_LINK_LOCAL},
2552 {MULTICAST, ADDR_MULTICAST},
2553 {LIMITED_BROADCAST, ADDR_LIMITED_BROADCAST}
2554 };
Luke Huangf8215372019-11-22 11:53:41 +08002555 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08002556
2557 for (const auto& config : testConfigs) {
2558 const std::string testHostName = config.asHostName();
2559 SCOPED_TRACE(testHostName);
2560
2561 const char* host_name = testHostName.c_str();
2562 dns.addMapping(host_name, ns_type::ns_t_a, config.addr.c_str());
2563
2564 addrinfo hints;
2565 memset(&hints, 0, sizeof(hints));
2566 hints.ai_family = AF_INET6;
2567 ScopedAddrinfo result = safe_getaddrinfo(config.name.c_str(), nullptr, &hints);
2568 // In AF_INET6 case, don't return IPv4 answers
2569 EXPECT_TRUE(result == nullptr);
2570 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2571 dns.clearQueries();
2572
2573 memset(&hints, 0, sizeof(hints));
2574 hints.ai_family = AF_UNSPEC;
2575 result = safe_getaddrinfo(config.name.c_str(), nullptr, &hints);
2576 EXPECT_TRUE(result != nullptr);
2577 // Expect IPv6 query only. IPv4 answer has been cached in previous query.
2578 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2579 // In AF_UNSPEC case, don't synthesize special use IPv4 address.
2580 std::string result_str = ToString(result);
2581 EXPECT_EQ(result_str, config.addr.c_str());
2582 dns.clearQueries();
2583 }
2584}
2585
2586TEST_F(ResolverTest, GetAddrInfo_Dns64QueryWithNullArgumentHints) {
2587 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002588 constexpr char dns64_name[] = "ipv4only.arpa.";
2589 constexpr char host_name[] = "v4only.example.com.";
2590 constexpr char host_name2[] = "v4v6.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002591 const std::vector<DnsRecord> records = {
2592 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2593 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2594 {host_name2, ns_type::ns_t_a, "1.2.3.4"},
2595 {host_name2, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
2596 };
nuccachena26cc2a2018-07-17 18:07:23 +08002597
Xiao Ma09b71022018-12-11 17:56:32 +09002598 test::DNSResponder dns(listen_addr);
2599 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002600 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002601 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002602
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002603 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002604 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002605 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002606
2607 // Assign argument hints of getaddrinfo() as null is equivalent to set ai_family AF_UNSPEC.
2608 // In AF_UNSPEC case, synthesize AAAA if there has A answer only.
2609 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, nullptr);
2610 EXPECT_TRUE(result != nullptr);
2611 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2612 std::string result_str = ToString(result);
2613 EXPECT_EQ(result_str, "64:ff9b::102:304");
2614 dns.clearQueries();
2615
2616 // In AF_UNSPEC case, do not synthesize AAAA if there's at least one AAAA answer.
2617 result = safe_getaddrinfo("v4v6", nullptr, nullptr);
2618 EXPECT_TRUE(result != nullptr);
2619 EXPECT_LE(2U, GetNumQueries(dns, host_name2));
2620 std::vector<std::string> result_strs = ToStrings(result);
2621 for (const auto& str : result_strs) {
2622 EXPECT_TRUE(str == "1.2.3.4" || str == "2001:db8::102:304")
2623 << ", result_str='" << str << "'";
2624 }
2625}
2626
2627TEST_F(ResolverTest, GetAddrInfo_Dns64QueryNullArgumentNode) {
2628 constexpr char ADDR_ANYADDR_V4[] = "0.0.0.0";
2629 constexpr char ADDR_ANYADDR_V6[] = "::";
2630 constexpr char ADDR_LOCALHOST_V4[] = "127.0.0.1";
2631 constexpr char ADDR_LOCALHOST_V6[] = "::1";
2632
2633 constexpr char PORT_NAME_HTTP[] = "http";
2634 constexpr char PORT_NUMBER_HTTP[] = "80";
2635
2636 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002637 constexpr char dns64_name[] = "ipv4only.arpa.";
2638
Xiao Ma09b71022018-12-11 17:56:32 +09002639 test::DNSResponder dns(listen_addr);
2640 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachena26cc2a2018-07-17 18:07:23 +08002641 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002642 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002643
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002644 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002645 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002646 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002647
Luke Huangf8215372019-11-22 11:53:41 +08002648 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08002649 // If node is null, return address is listed by libc/getaddrinfo.c as follows.
2650 // - passive socket -> anyaddr (0.0.0.0 or ::)
2651 // - non-passive socket -> localhost (127.0.0.1 or ::1)
2652 static const struct TestConfig {
2653 int flag;
2654 std::string addr_v4;
2655 std::string addr_v6;
2656
2657 std::string asParameters() const {
2658 return StringPrintf("flag=%d, addr_v4=%s, addr_v6=%s", flag, addr_v4.c_str(),
2659 addr_v6.c_str());
2660 }
2661 } testConfigs[]{
2662 {0 /* non-passive */, ADDR_LOCALHOST_V4, ADDR_LOCALHOST_V6},
2663 {AI_PASSIVE, ADDR_ANYADDR_V4, ADDR_ANYADDR_V6}
2664 };
Luke Huangf8215372019-11-22 11:53:41 +08002665 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08002666
2667 for (const auto& config : testConfigs) {
2668 SCOPED_TRACE(config.asParameters());
2669
Xiao Ma09b71022018-12-11 17:56:32 +09002670 addrinfo hints = {
Nick Desaulnierscd6395a2019-10-11 09:15:24 -07002671 .ai_flags = config.flag,
Xiao Ma09b71022018-12-11 17:56:32 +09002672 .ai_family = AF_UNSPEC, // any address family
2673 .ai_socktype = 0, // any type
2674 .ai_protocol = 0, // any protocol
Xiao Ma09b71022018-12-11 17:56:32 +09002675 };
nuccachena26cc2a2018-07-17 18:07:23 +08002676
2677 // Assign hostname as null and service as port name.
2678 ScopedAddrinfo result = safe_getaddrinfo(nullptr, PORT_NAME_HTTP, &hints);
2679 ASSERT_TRUE(result != nullptr);
2680
2681 // Can't be synthesized because it should not get into Netd.
2682 std::vector<std::string> result_strs = ToStrings(result);
2683 for (const auto& str : result_strs) {
2684 EXPECT_TRUE(str == config.addr_v4 || str == config.addr_v6)
2685 << ", result_str='" << str << "'";
2686 }
2687
2688 // Assign hostname as null and service as numeric port number.
2689 hints.ai_flags = config.flag | AI_NUMERICSERV;
2690 result = safe_getaddrinfo(nullptr, PORT_NUMBER_HTTP, &hints);
2691 ASSERT_TRUE(result != nullptr);
2692
2693 // Can't be synthesized because it should not get into Netd.
2694 result_strs = ToStrings(result);
2695 for (const auto& str : result_strs) {
2696 EXPECT_TRUE(str == config.addr_v4 || str == config.addr_v6)
2697 << ", result_str='" << str << "'";
2698 }
2699 }
2700}
2701
2702TEST_F(ResolverTest, GetHostByAddr_ReverseDnsQueryWithHavingNat64Prefix) {
2703 struct hostent* result = nullptr;
2704 struct in_addr v4addr;
2705 struct in6_addr v6addr;
2706
2707 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002708 constexpr char dns64_name[] = "ipv4only.arpa.";
2709 constexpr char ptr_name[] = "v4v6.example.com.";
2710 // PTR record for IPv4 address 1.2.3.4
2711 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2712 // PTR record for IPv6 address 2001:db8::102:304
2713 constexpr char ptr_addr_v6[] =
2714 "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 Ma09b71022018-12-11 17:56:32 +09002715 const std::vector<DnsRecord> records = {
2716 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2717 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2718 {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name},
2719 };
nuccachena26cc2a2018-07-17 18:07:23 +08002720
Xiao Ma09b71022018-12-11 17:56:32 +09002721 test::DNSResponder dns(listen_addr);
2722 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002723 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002724 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002725
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002726 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002727 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002728 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002729
2730 // Reverse IPv4 DNS query. Prefix should have no effect on it.
2731 inet_pton(AF_INET, "1.2.3.4", &v4addr);
2732 result = gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET);
2733 ASSERT_TRUE(result != nullptr);
2734 std::string result_str = result->h_name ? result->h_name : "null";
2735 EXPECT_EQ(result_str, "v4v6.example.com");
2736
2737 // Reverse IPv6 DNS query. Prefix should have no effect on it.
2738 inet_pton(AF_INET6, "2001:db8::102:304", &v6addr);
2739 result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2740 ASSERT_TRUE(result != nullptr);
2741 result_str = result->h_name ? result->h_name : "null";
2742 EXPECT_EQ(result_str, "v4v6.example.com");
2743}
2744
2745TEST_F(ResolverTest, GetHostByAddr_ReverseDns64Query) {
2746 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002747 constexpr char dns64_name[] = "ipv4only.arpa.";
2748 constexpr char ptr_name[] = "v4only.example.com.";
2749 // PTR record for IPv4 address 1.2.3.4
2750 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2751 // PTR record for IPv6 address 64:ff9b::1.2.3.4
2752 constexpr char ptr_addr_v6_nomapping[] =
2753 "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.";
2754 constexpr char ptr_name_v6_synthesis[] = "v6synthesis.example.com.";
2755 // PTR record for IPv6 address 64:ff9b::5.6.7.8
2756 constexpr char ptr_addr_v6_synthesis[] =
2757 "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 Ma09b71022018-12-11 17:56:32 +09002758 const std::vector<DnsRecord> records = {
2759 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2760 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2761 {ptr_addr_v6_synthesis, ns_type::ns_t_ptr, ptr_name_v6_synthesis},
2762 };
nuccachena26cc2a2018-07-17 18:07:23 +08002763
Xiao Ma09b71022018-12-11 17:56:32 +09002764 test::DNSResponder dns(listen_addr);
2765 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002766 // "ptr_addr_v6_nomapping" is not mapped in DNS server
nuccachena26cc2a2018-07-17 18:07:23 +08002767 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002768 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002769
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002770 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002771 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002772 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002773
2774 // Synthesized PTR record doesn't exist on DNS server
2775 // Reverse IPv6 DNS64 query while DNS server doesn't have an answer for synthesized address.
2776 // After querying synthesized address failed, expect that prefix is removed from IPv6
2777 // synthesized address and do reverse IPv4 query instead.
2778 struct in6_addr v6addr;
2779 inet_pton(AF_INET6, "64:ff9b::1.2.3.4", &v6addr);
2780 struct hostent* result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2781 ASSERT_TRUE(result != nullptr);
2782 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_nomapping)); // PTR record not exist
2783 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4)); // PTR record exist
2784 std::string result_str = result->h_name ? result->h_name : "null";
2785 EXPECT_EQ(result_str, "v4only.example.com");
2786 // Check that return address has been mapped from IPv4 to IPv6 address because Netd
2787 // removes NAT64 prefix and does IPv4 DNS reverse lookup in this case. Then, Netd
2788 // fakes the return IPv4 address as original queried IPv6 address.
2789 result_str = ToString(result);
2790 EXPECT_EQ(result_str, "64:ff9b::102:304");
2791 dns.clearQueries();
2792
2793 // Synthesized PTR record exists on DNS server
2794 // Reverse IPv6 DNS64 query while DNS server has an answer for synthesized address.
2795 // Expect to Netd pass through synthesized address for DNS queries.
2796 inet_pton(AF_INET6, "64:ff9b::5.6.7.8", &v6addr);
2797 result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2798 ASSERT_TRUE(result != nullptr);
2799 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_synthesis));
2800 result_str = result->h_name ? result->h_name : "null";
2801 EXPECT_EQ(result_str, "v6synthesis.example.com");
2802}
2803
2804TEST_F(ResolverTest, GetHostByAddr_ReverseDns64QueryFromHostFile) {
2805 constexpr char dns64_name[] = "ipv4only.arpa.";
2806 constexpr char host_name[] = "localhost";
2807 // The address is synthesized by prefix64:localhost.
2808 constexpr char host_addr[] = "64:ff9b::7f00:1";
nuccachena26cc2a2018-07-17 18:07:23 +08002809 constexpr char listen_addr[] = "::1";
Xiao Ma09b71022018-12-11 17:56:32 +09002810
2811 test::DNSResponder dns(listen_addr);
2812 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
nuccachena26cc2a2018-07-17 18:07:23 +08002813 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002814 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002815
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002816 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002817 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002818 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002819
2820 // Using synthesized "localhost" address to be a trick for resolving host name
2821 // from host file /etc/hosts and "localhost" is the only name in /etc/hosts. Note that this is
2822 // not realistic: the code never synthesizes AAAA records for addresses in 127.0.0.0/8.
2823 struct in6_addr v6addr;
2824 inet_pton(AF_INET6, host_addr, &v6addr);
2825 struct hostent* result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2826 ASSERT_TRUE(result != nullptr);
2827 // Expect no DNS queries; localhost is resolved via /etc/hosts.
2828 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
2829
Luke Huangf8215372019-11-22 11:53:41 +08002830 ASSERT_EQ(sizeof(in6_addr), (unsigned)result->h_length);
nuccachena26cc2a2018-07-17 18:07:23 +08002831 ASSERT_EQ(AF_INET6, result->h_addrtype);
2832 std::string result_str = ToString(result);
2833 EXPECT_EQ(result_str, host_addr);
2834 result_str = result->h_name ? result->h_name : "null";
2835 EXPECT_EQ(result_str, host_name);
2836}
2837
Hungming Chen9e6185a2019-06-04 16:09:19 +08002838TEST_F(ResolverTest, GetHostByAddr_cnamesClasslessReverseDelegation) {
2839 // IPv4 addresses in the subnet with notation '/' or '-'.
2840 constexpr char addr_slash[] = "192.0.2.1";
2841 constexpr char addr_hyphen[] = "192.0.3.1";
2842
2843 // Used to verify DNS reverse query for classless reverse lookup zone. See detail in RFC 2317
2844 // section 4.
2845 const static std::vector<DnsRecord> records = {
2846 // The records for reverse querying "192.0.2.1" in the subnet with notation '/'.
2847 {"1.2.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0/25.2.0.192.in-addr.arpa."},
2848 {"1.0/25.2.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
2849
2850 // The records for reverse querying "192.0.3.1" in the subnet with notation '-'.
2851 {"1.3.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0-127.3.0.192.in-addr.arpa."},
2852 {"1.0-127.3.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
2853 };
2854
2855 test::DNSResponder dns;
2856 StartDns(dns, records);
2857 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
2858
2859 for (const auto& address : {addr_slash, addr_hyphen}) {
2860 SCOPED_TRACE(address);
2861
2862 in_addr v4addr;
2863 ASSERT_TRUE(inet_pton(AF_INET, address, &v4addr));
2864 hostent* result = gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET);
2865 ASSERT_TRUE(result != nullptr);
2866 EXPECT_STREQ("hello.example.com", result->h_name);
2867 }
2868}
2869
nuccachena26cc2a2018-07-17 18:07:23 +08002870TEST_F(ResolverTest, GetNameInfo_ReverseDnsQueryWithHavingNat64Prefix) {
2871 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002872 constexpr char dns64_name[] = "ipv4only.arpa.";
2873 constexpr char ptr_name[] = "v4v6.example.com.";
2874 // PTR record for IPv4 address 1.2.3.4
2875 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2876 // PTR record for IPv6 address 2001:db8::102:304
2877 constexpr char ptr_addr_v6[] =
2878 "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 Ma09b71022018-12-11 17:56:32 +09002879 const std::vector<DnsRecord> records = {
2880 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2881 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2882 {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name},
2883 };
nuccachena26cc2a2018-07-17 18:07:23 +08002884
Xiao Ma09b71022018-12-11 17:56:32 +09002885 test::DNSResponder dns(listen_addr);
2886 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002887 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002888 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002889
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002890 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002891 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002892 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002893
Luke Huangf8215372019-11-22 11:53:41 +08002894 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08002895 static const struct TestConfig {
2896 int flag;
2897 int family;
2898 std::string addr;
2899 std::string host;
2900
2901 std::string asParameters() const {
2902 return StringPrintf("flag=%d, family=%d, addr=%s, host=%s", flag, family, addr.c_str(),
2903 host.c_str());
2904 }
2905 } testConfigs[]{
2906 {NI_NAMEREQD, AF_INET, "1.2.3.4", "v4v6.example.com"},
2907 {NI_NUMERICHOST, AF_INET, "1.2.3.4", "1.2.3.4"},
2908 {0, AF_INET, "1.2.3.4", "v4v6.example.com"},
2909 {0, AF_INET, "5.6.7.8", "5.6.7.8"}, // unmapped
2910 {NI_NAMEREQD, AF_INET6, "2001:db8::102:304", "v4v6.example.com"},
2911 {NI_NUMERICHOST, AF_INET6, "2001:db8::102:304", "2001:db8::102:304"},
2912 {0, AF_INET6, "2001:db8::102:304", "v4v6.example.com"},
2913 {0, AF_INET6, "2001:db8::506:708", "2001:db8::506:708"}, // unmapped
2914 };
Luke Huangf8215372019-11-22 11:53:41 +08002915 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08002916
2917 // Reverse IPv4/IPv6 DNS query. Prefix should have no effect on it.
2918 for (const auto& config : testConfigs) {
2919 SCOPED_TRACE(config.asParameters());
2920
2921 int rv;
2922 char host[NI_MAXHOST];
2923 struct sockaddr_in sin;
2924 struct sockaddr_in6 sin6;
2925 if (config.family == AF_INET) {
2926 memset(&sin, 0, sizeof(sin));
2927 sin.sin_family = AF_INET;
2928 inet_pton(AF_INET, config.addr.c_str(), &sin.sin_addr);
Luke Huangf8215372019-11-22 11:53:41 +08002929 rv = getnameinfo((const struct sockaddr*)&sin, sizeof(sin), host, sizeof(host), nullptr,
2930 0, config.flag);
nuccachena26cc2a2018-07-17 18:07:23 +08002931 if (config.flag == NI_NAMEREQD) EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4));
2932 } else if (config.family == AF_INET6) {
2933 memset(&sin6, 0, sizeof(sin6));
2934 sin6.sin6_family = AF_INET6;
2935 inet_pton(AF_INET6, config.addr.c_str(), &sin6.sin6_addr);
Luke Huangf8215372019-11-22 11:53:41 +08002936 rv = getnameinfo((const struct sockaddr*)&sin6, sizeof(sin6), host, sizeof(host),
nuccachena26cc2a2018-07-17 18:07:23 +08002937 nullptr, 0, config.flag);
2938 if (config.flag == NI_NAMEREQD) EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6));
2939 }
2940 ASSERT_EQ(0, rv);
2941 std::string result_str = host;
2942 EXPECT_EQ(result_str, config.host);
2943 dns.clearQueries();
2944 }
2945}
2946
2947TEST_F(ResolverTest, GetNameInfo_ReverseDns64Query) {
2948 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002949 constexpr char dns64_name[] = "ipv4only.arpa.";
2950 constexpr char ptr_name[] = "v4only.example.com.";
2951 // PTR record for IPv4 address 1.2.3.4
2952 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2953 // PTR record for IPv6 address 64:ff9b::1.2.3.4
2954 constexpr char ptr_addr_v6_nomapping[] =
2955 "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.";
2956 constexpr char ptr_name_v6_synthesis[] = "v6synthesis.example.com.";
2957 // PTR record for IPv6 address 64:ff9b::5.6.7.8
2958 constexpr char ptr_addr_v6_synthesis[] =
2959 "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 Ma09b71022018-12-11 17:56:32 +09002960 const std::vector<DnsRecord> records = {
2961 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2962 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2963 {ptr_addr_v6_synthesis, ns_type::ns_t_ptr, ptr_name_v6_synthesis},
2964 };
nuccachena26cc2a2018-07-17 18:07:23 +08002965
Xiao Ma09b71022018-12-11 17:56:32 +09002966 test::DNSResponder dns(listen_addr);
2967 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002968 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002969 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002970
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002971 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002972 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002973 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002974
Luke Huangf8215372019-11-22 11:53:41 +08002975 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08002976 static const struct TestConfig {
2977 bool hasSynthesizedPtrRecord;
2978 int flag;
2979 std::string addr;
2980 std::string host;
2981
2982 std::string asParameters() const {
2983 return StringPrintf("hasSynthesizedPtrRecord=%d, flag=%d, addr=%s, host=%s",
2984 hasSynthesizedPtrRecord, flag, addr.c_str(), host.c_str());
2985 }
2986 } testConfigs[]{
2987 {false, NI_NAMEREQD, "64:ff9b::102:304", "v4only.example.com"},
2988 {false, NI_NUMERICHOST, "64:ff9b::102:304", "64:ff9b::102:304"},
2989 {false, 0, "64:ff9b::102:304", "v4only.example.com"},
2990 {true, NI_NAMEREQD, "64:ff9b::506:708", "v6synthesis.example.com"},
2991 {true, NI_NUMERICHOST, "64:ff9b::506:708", "64:ff9b::506:708"},
2992 {true, 0, "64:ff9b::506:708", "v6synthesis.example.com"}
2993 };
Luke Huangf8215372019-11-22 11:53:41 +08002994 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08002995
2996 // hasSynthesizedPtrRecord = false
2997 // Synthesized PTR record doesn't exist on DNS server
2998 // Reverse IPv6 DNS64 query while DNS server doesn't have an answer for synthesized address.
2999 // After querying synthesized address failed, expect that prefix is removed from IPv6
3000 // synthesized address and do reverse IPv4 query instead.
3001 //
3002 // hasSynthesizedPtrRecord = true
3003 // Synthesized PTR record exists on DNS server
3004 // Reverse IPv6 DNS64 query while DNS server has an answer for synthesized address.
3005 // Expect to just pass through synthesized address for DNS queries.
3006 for (const auto& config : testConfigs) {
3007 SCOPED_TRACE(config.asParameters());
3008
3009 char host[NI_MAXHOST];
3010 struct sockaddr_in6 sin6;
3011 memset(&sin6, 0, sizeof(sin6));
3012 sin6.sin6_family = AF_INET6;
3013 inet_pton(AF_INET6, config.addr.c_str(), &sin6.sin6_addr);
Luke Huangf8215372019-11-22 11:53:41 +08003014 int rv = getnameinfo((const struct sockaddr*)&sin6, sizeof(sin6), host, sizeof(host),
nuccachena26cc2a2018-07-17 18:07:23 +08003015 nullptr, 0, config.flag);
3016 ASSERT_EQ(0, rv);
3017 if (config.flag == NI_NAMEREQD) {
3018 if (config.hasSynthesizedPtrRecord) {
3019 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_synthesis));
3020 } else {
3021 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_nomapping)); // PTR record not exist.
3022 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4)); // PTR record exist.
3023 }
3024 }
3025 std::string result_str = host;
3026 EXPECT_EQ(result_str, config.host);
3027 dns.clearQueries();
3028 }
3029}
3030
3031TEST_F(ResolverTest, GetNameInfo_ReverseDns64QueryFromHostFile) {
3032 constexpr char dns64_name[] = "ipv4only.arpa.";
3033 constexpr char host_name[] = "localhost";
3034 // The address is synthesized by prefix64:localhost.
3035 constexpr char host_addr[] = "64:ff9b::7f00:1";
nuccachena26cc2a2018-07-17 18:07:23 +08003036 constexpr char listen_addr[] = "::1";
Xiao Ma09b71022018-12-11 17:56:32 +09003037
3038 test::DNSResponder dns(listen_addr);
3039 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
nuccachena26cc2a2018-07-17 18:07:23 +08003040 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003041 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003042
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003043 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003044 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003045 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003046
3047 // Using synthesized "localhost" address to be a trick for resolving host name
3048 // from host file /etc/hosts and "localhost" is the only name in /etc/hosts. Note that this is
3049 // not realistic: the code never synthesizes AAAA records for addresses in 127.0.0.0/8.
3050 char host[NI_MAXHOST];
Xiao Ma09b71022018-12-11 17:56:32 +09003051 struct sockaddr_in6 sin6 = {.sin6_family = AF_INET6};
nuccachena26cc2a2018-07-17 18:07:23 +08003052 inet_pton(AF_INET6, host_addr, &sin6.sin6_addr);
Luke Huangf8215372019-11-22 11:53:41 +08003053 int rv = getnameinfo((const struct sockaddr*)&sin6, sizeof(sin6), host, sizeof(host), nullptr,
nuccachena26cc2a2018-07-17 18:07:23 +08003054 0, NI_NAMEREQD);
3055 ASSERT_EQ(0, rv);
3056 // Expect no DNS queries; localhost is resolved via /etc/hosts.
3057 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
3058
3059 std::string result_str = host;
3060 EXPECT_EQ(result_str, host_name);
3061}
3062
Hungming Chen9e6185a2019-06-04 16:09:19 +08003063TEST_F(ResolverTest, GetNameInfo_cnamesClasslessReverseDelegation) {
3064 // IPv4 addresses in the subnet with notation '/' or '-'.
3065 constexpr char addr_slash[] = "192.0.2.1";
3066 constexpr char addr_hyphen[] = "192.0.3.1";
3067
3068 // Used to verify DNS reverse query for classless reverse lookup zone. See detail in RFC 2317
3069 // section 4.
3070 const static std::vector<DnsRecord> records = {
3071 // The records for reverse querying "192.0.2.1" in the subnet with notation '/'.
3072 {"1.2.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0/25.2.0.192.in-addr.arpa."},
3073 {"1.0/25.2.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
3074
3075 // The records for reverse querying "192.0.3.1" in the subnet with notation '-'.
3076 {"1.3.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0-127.3.0.192.in-addr.arpa."},
3077 {"1.0-127.3.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
3078 };
3079
3080 test::DNSResponder dns;
3081 StartDns(dns, records);
3082 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3083
3084 for (const auto& address : {addr_slash, addr_hyphen}) {
3085 SCOPED_TRACE(address);
3086
3087 char host[NI_MAXHOST];
3088 sockaddr_in sin = {.sin_family = AF_INET};
3089 ASSERT_TRUE(inet_pton(AF_INET, address, &sin.sin_addr));
3090 int rv = getnameinfo((const sockaddr*)&sin, sizeof(sin), host, sizeof(host), nullptr, 0,
3091 NI_NAMEREQD);
3092 ASSERT_EQ(0, rv);
3093 EXPECT_STREQ("hello.example.com", host);
3094 }
3095}
3096
nuccachena26cc2a2018-07-17 18:07:23 +08003097TEST_F(ResolverTest, GetHostByName2_Dns64Synthesize) {
Xiao Ma09b71022018-12-11 17:56:32 +09003098 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08003099 constexpr char dns64_name[] = "ipv4only.arpa.";
3100 constexpr char host_name[] = "ipv4only.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09003101 const std::vector<DnsRecord> records = {
3102 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
3103 {host_name, ns_type::ns_t_a, "1.2.3.4"},
3104 };
nuccachena26cc2a2018-07-17 18:07:23 +08003105
Xiao Ma09b71022018-12-11 17:56:32 +09003106 test::DNSResponder dns(listen_addr);
3107 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08003108 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003109 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003110
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003111 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003112 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003113 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003114
3115 // Query an IPv4-only hostname. Expect that gets a synthesized address.
3116 struct hostent* result = gethostbyname2("ipv4only", AF_INET6);
3117 ASSERT_TRUE(result != nullptr);
3118 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3119 std::string result_str = ToString(result);
3120 EXPECT_EQ(result_str, "64:ff9b::102:304");
3121}
nuccachena26cc2a2018-07-17 18:07:23 +08003122
3123TEST_F(ResolverTest, GetHostByName2_DnsQueryWithHavingNat64Prefix) {
3124 constexpr char dns64_name[] = "ipv4only.arpa.";
3125 constexpr char host_name[] = "v4v6.example.com.";
nuccachena26cc2a2018-07-17 18:07:23 +08003126 constexpr char listen_addr[] = "::1";
Xiao Ma09b71022018-12-11 17:56:32 +09003127 const std::vector<DnsRecord> records = {
3128 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
3129 {host_name, ns_type::ns_t_a, "1.2.3.4"},
3130 {host_name, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
3131 };
3132
3133 test::DNSResponder dns(listen_addr);
3134 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08003135 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003136 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003137
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003138 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003139 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003140 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003141
3142 // IPv4 DNS query. Prefix should have no effect on it.
3143 struct hostent* result = gethostbyname2("v4v6", AF_INET);
3144 ASSERT_TRUE(result != nullptr);
3145 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3146 std::string result_str = ToString(result);
3147 EXPECT_EQ(result_str, "1.2.3.4");
3148 dns.clearQueries();
3149
3150 // IPv6 DNS query. Prefix should have no effect on it.
3151 result = gethostbyname2("v4v6", AF_INET6);
3152 ASSERT_TRUE(result != nullptr);
3153 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3154 result_str = ToString(result);
3155 EXPECT_EQ(result_str, "2001:db8::102:304");
3156}
3157
3158TEST_F(ResolverTest, GetHostByName2_Dns64QuerySpecialUseIPv4Addresses) {
3159 constexpr char THIS_NETWORK[] = "this_network";
3160 constexpr char LOOPBACK[] = "loopback";
3161 constexpr char LINK_LOCAL[] = "link_local";
3162 constexpr char MULTICAST[] = "multicast";
3163 constexpr char LIMITED_BROADCAST[] = "limited_broadcast";
3164
3165 constexpr char ADDR_THIS_NETWORK[] = "0.0.0.1";
3166 constexpr char ADDR_LOOPBACK[] = "127.0.0.1";
3167 constexpr char ADDR_LINK_LOCAL[] = "169.254.0.1";
3168 constexpr char ADDR_MULTICAST[] = "224.0.0.1";
3169 constexpr char ADDR_LIMITED_BROADCAST[] = "255.255.255.255";
3170
3171 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08003172 constexpr char dns64_name[] = "ipv4only.arpa.";
3173
Xiao Ma09b71022018-12-11 17:56:32 +09003174 test::DNSResponder dns(listen_addr);
3175 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachena26cc2a2018-07-17 18:07:23 +08003176 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003177 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003178
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003179 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003180 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003181 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003182
Luke Huangf8215372019-11-22 11:53:41 +08003183 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08003184 static const struct TestConfig {
3185 std::string name;
3186 std::string addr;
3187
3188 std::string asHostName() const {
Luke Huangf8215372019-11-22 11:53:41 +08003189 return StringPrintf("%s.example.com.", name.c_str());
nuccachena26cc2a2018-07-17 18:07:23 +08003190 }
3191 } testConfigs[]{
3192 {THIS_NETWORK, ADDR_THIS_NETWORK},
3193 {LOOPBACK, ADDR_LOOPBACK},
3194 {LINK_LOCAL, ADDR_LINK_LOCAL},
3195 {MULTICAST, ADDR_MULTICAST},
3196 {LIMITED_BROADCAST, ADDR_LIMITED_BROADCAST}
3197 };
Luke Huangf8215372019-11-22 11:53:41 +08003198 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08003199
3200 for (const auto& config : testConfigs) {
3201 const std::string testHostName = config.asHostName();
3202 SCOPED_TRACE(testHostName);
3203
3204 const char* host_name = testHostName.c_str();
3205 dns.addMapping(host_name, ns_type::ns_t_a, config.addr.c_str());
3206
3207 struct hostent* result = gethostbyname2(config.name.c_str(), AF_INET6);
3208 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3209
3210 // In AF_INET6 case, don't synthesize special use IPv4 address.
3211 // Expect to have no answer
3212 EXPECT_EQ(nullptr, result);
3213
3214 dns.clearQueries();
3215 }
Bernie Innocenti2fef2b82018-12-20 15:56:40 +09003216}
Mike Yuf14e1a92019-05-10 13:54:58 +08003217
3218TEST_F(ResolverTest, PrefixDiscoveryBypassTls) {
3219 constexpr char listen_addr[] = "::1";
3220 constexpr char cleartext_port[] = "53";
3221 constexpr char tls_port[] = "853";
3222 constexpr char dns64_name[] = "ipv4only.arpa.";
3223 const std::vector<std::string> servers = {listen_addr};
3224
3225 test::DNSResponder dns(listen_addr);
3226 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
3227 test::DnsTlsFrontend tls(listen_addr, tls_port, listen_addr, cleartext_port);
3228 ASSERT_TRUE(tls.startServer());
3229
3230 // Setup OPPORTUNISTIC mode and wait for the validation complete.
waynema0e73c2e2019-07-31 15:04:08 +08003231 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08003232 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yuf14e1a92019-05-10 13:54:58 +08003233 tls.clearQueries();
3234
3235 // Start NAT64 prefix discovery and wait for it complete.
3236 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003237 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
Mike Yuf14e1a92019-05-10 13:54:58 +08003238
3239 // Verify it bypassed TLS even though there's a TLS server available.
3240 EXPECT_EQ(0, tls.queries());
3241 EXPECT_EQ(1U, GetNumQueries(dns, dns64_name));
3242
3243 // Restart the testing network to reset the cache.
3244 mDnsClient.TearDown();
3245 mDnsClient.SetUp();
3246 dns.clearQueries();
3247
3248 // Setup STRICT mode and wait for the validation complete.
waynema0e73c2e2019-07-31 15:04:08 +08003249 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
3250 kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08003251 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yuf14e1a92019-05-10 13:54:58 +08003252 tls.clearQueries();
3253
3254 // Start NAT64 prefix discovery and wait for it to complete.
3255 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003256 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
Mike Yuf14e1a92019-05-10 13:54:58 +08003257
3258 // Verify it bypassed TLS despite STRICT mode.
3259 EXPECT_EQ(0, tls.queries());
3260 EXPECT_EQ(1U, GetNumQueries(dns, dns64_name));
3261}
Luke Huang9807e6b2019-05-20 16:17:12 +08003262
3263namespace {
3264
Luke Huang0d592bc2019-05-25 18:24:03 +08003265class ScopedSetNetworkForProcess {
3266 public:
3267 explicit ScopedSetNetworkForProcess(unsigned netId) {
3268 mStoredNetId = getNetworkForProcess();
3269 if (netId == mStoredNetId) return;
3270 EXPECT_EQ(0, setNetworkForProcess(netId));
3271 }
3272 ~ScopedSetNetworkForProcess() { EXPECT_EQ(0, setNetworkForProcess(mStoredNetId)); }
3273
3274 private:
3275 unsigned mStoredNetId;
3276};
3277
3278class ScopedSetNetworkForResolv {
3279 public:
3280 explicit ScopedSetNetworkForResolv(unsigned netId) { EXPECT_EQ(0, setNetworkForResolv(netId)); }
3281 ~ScopedSetNetworkForResolv() { EXPECT_EQ(0, setNetworkForResolv(NETID_UNSET)); }
3282};
3283
Luke Huang9807e6b2019-05-20 16:17:12 +08003284void sendCommand(int fd, const std::string& cmd) {
3285 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size() + 1));
3286 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size() + 1));
3287}
3288
3289int32_t readBE32(int fd) {
3290 int32_t tmp;
3291 int n = TEMP_FAILURE_RETRY(read(fd, &tmp, sizeof(tmp)));
3292 EXPECT_TRUE(n > 0);
3293 return ntohl(tmp);
3294}
3295
Luke Huang0d592bc2019-05-25 18:24:03 +08003296int readResponseCode(int fd) {
Luke Huang9807e6b2019-05-20 16:17:12 +08003297 char buf[4];
3298 int n = TEMP_FAILURE_RETRY(read(fd, &buf, sizeof(buf)));
3299 EXPECT_TRUE(n > 0);
3300 // The format of response code is that 4 bytes for the code & null.
3301 buf[3] = '\0';
3302 int result;
3303 EXPECT_TRUE(ParseInt(buf, &result));
3304 return result;
3305}
3306
Luke Huang0d592bc2019-05-25 18:24:03 +08003307bool checkAndClearUseLocalNameserversFlag(unsigned* netid) {
3308 if (netid == nullptr || ((*netid) & NETID_USE_LOCAL_NAMESERVERS) == 0) {
3309 return false;
3310 }
3311 *netid = (*netid) & ~NETID_USE_LOCAL_NAMESERVERS;
3312 return true;
3313}
3314
Luke Huangf8215372019-11-22 11:53:41 +08003315aidl::android::net::UidRangeParcel makeUidRangeParcel(int start, int stop) {
3316 aidl::android::net::UidRangeParcel res;
Luke Huang0d592bc2019-05-25 18:24:03 +08003317 res.start = start;
3318 res.stop = stop;
3319
3320 return res;
3321}
3322
3323void expectNetIdWithLocalNameserversFlag(unsigned netId) {
3324 unsigned dnsNetId = 0;
3325 EXPECT_EQ(0, getNetworkForDns(&dnsNetId));
3326 EXPECT_TRUE(checkAndClearUseLocalNameserversFlag(&dnsNetId));
3327 EXPECT_EQ(netId, static_cast<unsigned>(dnsNetId));
3328}
3329
3330void expectDnsNetIdEquals(unsigned netId) {
3331 unsigned dnsNetId = 0;
3332 EXPECT_EQ(0, getNetworkForDns(&dnsNetId));
3333 EXPECT_EQ(netId, static_cast<unsigned>(dnsNetId));
3334}
3335
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003336void expectDnsNetIdIsDefaultNetwork(INetd* netdService) {
Luke Huang0d592bc2019-05-25 18:24:03 +08003337 int currentNetid;
3338 EXPECT_TRUE(netdService->networkGetDefault(&currentNetid).isOk());
3339 expectDnsNetIdEquals(currentNetid);
3340}
3341
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003342void expectDnsNetIdWithVpn(INetd* netdService, unsigned vpnNetId, unsigned expectedNetId) {
Luke Huang0d592bc2019-05-25 18:24:03 +08003343 EXPECT_TRUE(netdService->networkCreateVpn(vpnNetId, false /* secure */).isOk());
3344 uid_t uid = getuid();
3345 // Add uid to VPN
3346 EXPECT_TRUE(netdService->networkAddUidRanges(vpnNetId, {makeUidRangeParcel(uid, uid)}).isOk());
3347 expectDnsNetIdEquals(expectedNetId);
3348 EXPECT_TRUE(netdService->networkDestroy(vpnNetId).isOk());
3349}
3350
Luke Huang9807e6b2019-05-20 16:17:12 +08003351} // namespace
3352
3353TEST_F(ResolverTest, getDnsNetId) {
3354 // We've called setNetworkForProcess in SetupOemNetwork, so reset to default first.
3355 setNetworkForProcess(NETID_UNSET);
Luke Huang0d592bc2019-05-25 18:24:03 +08003356
3357 expectDnsNetIdIsDefaultNetwork(mDnsClient.netdService());
3358 expectDnsNetIdWithVpn(mDnsClient.netdService(), TEST_VPN_NETID, TEST_VPN_NETID);
Luke Huang9807e6b2019-05-20 16:17:12 +08003359
3360 // Test with setNetworkForProcess
Luke Huang0d592bc2019-05-25 18:24:03 +08003361 {
3362 ScopedSetNetworkForProcess scopedSetNetworkForProcess(TEST_NETID);
3363 expectDnsNetIdEquals(TEST_NETID);
3364 }
3365
3366 // Test with setNetworkForProcess with NETID_USE_LOCAL_NAMESERVERS
3367 {
3368 ScopedSetNetworkForProcess scopedSetNetworkForProcess(TEST_NETID |
3369 NETID_USE_LOCAL_NAMESERVERS);
3370 expectNetIdWithLocalNameserversFlag(TEST_NETID);
3371 }
Luke Huang9807e6b2019-05-20 16:17:12 +08003372
3373 // Test with setNetworkForResolv
Luke Huang0d592bc2019-05-25 18:24:03 +08003374 {
3375 ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID);
3376 expectDnsNetIdEquals(TEST_NETID);
3377 }
3378
3379 // Test with setNetworkForResolv with NETID_USE_LOCAL_NAMESERVERS
3380 {
3381 ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID |
3382 NETID_USE_LOCAL_NAMESERVERS);
3383 expectNetIdWithLocalNameserversFlag(TEST_NETID);
3384 }
3385
3386 // Test with setNetworkForResolv under bypassable vpn
3387 {
3388 ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID);
3389 expectDnsNetIdWithVpn(mDnsClient.netdService(), TEST_VPN_NETID, TEST_NETID);
3390 }
Luke Huang9807e6b2019-05-20 16:17:12 +08003391
3392 // Create socket connected to DnsProxyListener
3393 int fd = dns_open_proxy();
3394 EXPECT_TRUE(fd > 0);
3395 unique_fd ufd(fd);
3396
3397 // Test command with wrong netId
3398 sendCommand(fd, "getdnsnetid abc");
Luke Huang0d592bc2019-05-25 18:24:03 +08003399 EXPECT_EQ(ResponseCode::DnsProxyQueryResult, readResponseCode(fd));
Luke Huang9807e6b2019-05-20 16:17:12 +08003400 EXPECT_EQ(-EINVAL, readBE32(fd));
3401
3402 // Test unsupported command
3403 sendCommand(fd, "getdnsnetidNotSupported");
3404 // Keep in sync with FrameworkListener.cpp (500, "Command not recognized")
Luke Huang0d592bc2019-05-25 18:24:03 +08003405 EXPECT_EQ(500, readResponseCode(fd));
Luke Huang9807e6b2019-05-20 16:17:12 +08003406}
Sehee Park2c118782019-05-07 13:02:45 +09003407
3408TEST_F(ResolverTest, BlockDnsQueryWithUidRule) {
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003409 // This test relies on blocking traffic on loopback, which xt_qtaguid does not do.
3410 // See aosp/358413 and b/34444781 for why.
3411 SKIP_IF_BPF_NOT_SUPPORTED;
3412
Sehee Park2c118782019-05-07 13:02:45 +09003413 constexpr char listen_addr1[] = "127.0.0.4";
3414 constexpr char listen_addr2[] = "::1";
3415 constexpr char host_name[] = "howdy.example.com.";
3416 const std::vector<DnsRecord> records = {
3417 {host_name, ns_type::ns_t_a, "1.2.3.4"},
3418 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
3419 };
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003420 INetd* netdService = mDnsClient.netdService();
Sehee Park2c118782019-05-07 13:02:45 +09003421
3422 test::DNSResponder dns1(listen_addr1);
3423 test::DNSResponder dns2(listen_addr2);
3424 StartDns(dns1, records);
3425 StartDns(dns2, records);
3426
3427 std::vector<std::string> servers = {listen_addr1, listen_addr2};
3428 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
3429 dns1.clearQueries();
3430 dns2.clearQueries();
3431
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003432 // Add drop rule for TEST_UID. Also enable the standby chain because it might not be enabled.
3433 // Unfortunately we cannot use FIREWALL_CHAIN_NONE, or custom iptables rules, for this purpose
3434 // because netd calls fchown() on the DNS query sockets, and "iptables -m owner" matches the
3435 // UID of the socket creator, not the UID set by fchown().
3436 //
3437 // TODO: migrate FIREWALL_CHAIN_NONE to eBPF as well.
3438 EXPECT_TRUE(netdService->firewallEnableChildChain(INetd::FIREWALL_CHAIN_STANDBY, true).isOk());
3439 EXPECT_TRUE(netdService
Sehee Park2c118782019-05-07 13:02:45 +09003440 ->firewallSetUidRule(INetd::FIREWALL_CHAIN_STANDBY, TEST_UID,
3441 INetd::FIREWALL_RULE_DENY)
3442 .isOk());
3443
3444 // Save uid
3445 int suid = getuid();
3446
3447 // Switch to TEST_UID
3448 EXPECT_TRUE(seteuid(TEST_UID) == 0);
3449
3450 // Dns Query
3451 int fd1 = resNetworkQuery(TEST_NETID, host_name, ns_c_in, ns_t_a, 0);
3452 int fd2 = resNetworkQuery(TEST_NETID, host_name, ns_c_in, ns_t_aaaa, 0);
3453 EXPECT_TRUE(fd1 != -1);
3454 EXPECT_TRUE(fd2 != -1);
3455
3456 uint8_t buf[MAXPACKET] = {};
3457 int rcode;
3458 int res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
3459 EXPECT_EQ(-ECONNREFUSED, res);
3460
3461 memset(buf, 0, MAXPACKET);
3462 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
3463 EXPECT_EQ(-ECONNREFUSED, res);
3464
3465 // Restore uid
3466 EXPECT_TRUE(seteuid(suid) == 0);
3467
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003468 // Remove drop rule for TEST_UID, and disable the standby chain.
3469 EXPECT_TRUE(netdService
Sehee Park2c118782019-05-07 13:02:45 +09003470 ->firewallSetUidRule(INetd::FIREWALL_CHAIN_STANDBY, TEST_UID,
3471 INetd::FIREWALL_RULE_ALLOW)
3472 .isOk());
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003473 EXPECT_TRUE(netdService->firewallEnableChildChain(INetd::FIREWALL_CHAIN_STANDBY, false).isOk());
Sehee Park2c118782019-05-07 13:02:45 +09003474}
Mike Yua772c202019-09-23 17:47:21 +08003475
Mike Yu40e67072019-10-09 21:14:09 +08003476namespace {
3477
3478const std::string kDotConnectTimeoutMsFlag(
3479 "persist.device_config.netd_native.dot_connect_timeout_ms");
3480
3481class ScopedSystemProperties {
3482 public:
3483 explicit ScopedSystemProperties(const std::string& key, const std::string& value)
3484 : mStoredKey(key) {
3485 mStoredValue = android::base::GetProperty(key, "");
3486 android::base::SetProperty(key, value);
3487 }
3488 ~ScopedSystemProperties() { android::base::SetProperty(mStoredKey, mStoredValue); }
3489
3490 private:
3491 std::string mStoredKey;
3492 std::string mStoredValue;
3493};
3494
3495} // namespace
3496
Mike Yua772c202019-09-23 17:47:21 +08003497TEST_F(ResolverTest, ConnectTlsServerTimeout) {
Mike Yu40e67072019-10-09 21:14:09 +08003498 constexpr int expectedTimeout = 1000;
3499 constexpr char hostname1[] = "query1.example.com.";
3500 constexpr char hostname2[] = "query2.example.com.";
Mike Yua772c202019-09-23 17:47:21 +08003501 const std::vector<DnsRecord> records = {
Mike Yu40e67072019-10-09 21:14:09 +08003502 {hostname1, ns_type::ns_t_a, "1.2.3.4"},
3503 {hostname2, ns_type::ns_t_a, "1.2.3.5"},
Mike Yua772c202019-09-23 17:47:21 +08003504 };
3505
3506 test::DNSResponder dns;
3507 StartDns(dns, records);
Mike Yu40e67072019-10-09 21:14:09 +08003508 test::DnsTlsFrontend tls;
Mike Yua772c202019-09-23 17:47:21 +08003509 ASSERT_TRUE(tls.startServer());
3510
Mike Yu40e67072019-10-09 21:14:09 +08003511 // The resolver will adjust the timeout value to 1000ms since the value is too small.
3512 ScopedSystemProperties scopedSystemProperties(kDotConnectTimeoutMsFlag, "100");
Mike Yua772c202019-09-23 17:47:21 +08003513
Mike Yu40e67072019-10-09 21:14:09 +08003514 // Set up resolver to opportunistic mode with the default configuration.
Luke Huangf8215372019-11-22 11:53:41 +08003515 const aidl::android::net::ResolverParamsParcel parcel =
3516 DnsResponderClient::GetDefaultResolverParamsParcel();
Mike Yu40e67072019-10-09 21:14:09 +08003517 ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
Mike Yua772c202019-09-23 17:47:21 +08003518 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
3519 dns.clearQueries();
3520 tls.clearQueries();
3521
3522 // The server becomes unresponsive to the handshake request.
3523 tls.setHangOnHandshakeForTesting(true);
3524
3525 // Expect the things happening in getaddrinfo():
3526 // 1. Connect to the private DNS server.
3527 // 2. SSL handshake times out.
3528 // 3. Fallback to UDP transport, and then get the answer.
Mike Yu40e67072019-10-09 21:14:09 +08003529 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
3530 auto [result, timeTakenMs] = safe_getaddrinfo_time_taken(hostname1, nullptr, hints);
Mike Yua772c202019-09-23 17:47:21 +08003531
Mike Yu40e67072019-10-09 21:14:09 +08003532 EXPECT_NE(nullptr, result);
Mike Yua772c202019-09-23 17:47:21 +08003533 EXPECT_EQ(0, tls.queries());
Mike Yu40e67072019-10-09 21:14:09 +08003534 EXPECT_EQ(1U, GetNumQueries(dns, hostname1));
3535 EXPECT_EQ(records.at(0).addr, ToString(result));
Mike Yua772c202019-09-23 17:47:21 +08003536
Mike Yu40e67072019-10-09 21:14:09 +08003537 // A loose upper bound is set by adding 2000ms buffer time. Theoretically, getaddrinfo()
3538 // should just take a bit more than expetTimeout milliseconds.
3539 EXPECT_GE(timeTakenMs, expectedTimeout);
3540 EXPECT_LE(timeTakenMs, expectedTimeout + 2000);
3541
3542 // Set the server to be responsive. Verify that the resolver will attempt to reconnect
3543 // to the server and then get the result within the timeout.
3544 tls.setHangOnHandshakeForTesting(false);
3545 std::tie(result, timeTakenMs) = safe_getaddrinfo_time_taken(hostname2, nullptr, hints);
3546
3547 EXPECT_NE(nullptr, result);
3548 EXPECT_EQ(1, tls.queries());
3549 EXPECT_EQ(1U, GetNumQueries(dns, hostname2));
3550 EXPECT_EQ(records.at(1).addr, ToString(result));
3551
3552 EXPECT_LE(timeTakenMs, expectedTimeout);
Mike Yua772c202019-09-23 17:47:21 +08003553}
Hungming Chenbb90ab32019-10-28 18:20:31 +08003554
Ken Chen766feae2019-10-30 15:13:44 +08003555TEST_F(ResolverTest, FlushNetworkCache) {
3556 test::DNSResponder dns;
3557 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3558 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3559
3560 const hostent* result = gethostbyname("hello");
3561 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
3562
3563 // get result from cache
3564 result = gethostbyname("hello");
3565 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
3566
3567 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
3568
3569 result = gethostbyname("hello");
3570 EXPECT_EQ(2U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
3571}
3572
3573TEST_F(ResolverTest, FlushNetworkCache_random) {
3574 constexpr int num_flush = 10;
3575 constexpr int num_queries = 20;
3576 test::DNSResponder dns;
3577 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3578 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3579 const addrinfo hints = {.ai_family = AF_INET};
3580
3581 std::thread t([this]() {
3582 for (int i = 0; i < num_flush; ++i) {
3583 unsigned delay = arc4random_uniform(10 * 1000); // 10ms
3584 usleep(delay);
3585 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
3586 }
3587 });
3588
3589 for (int i = 0; i < num_queries; ++i) {
3590 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3591 EXPECT_TRUE(result != nullptr);
3592 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3593 }
3594 t.join();
3595}
3596
3597// flush cache while one query is wait-for-response, another is pending.
3598TEST_F(ResolverTest, FlushNetworkCache_concurrent) {
3599 const char* listen_addr1 = "127.0.0.9";
3600 const char* listen_addr2 = "127.0.0.10";
3601 test::DNSResponder dns1(listen_addr1);
3602 test::DNSResponder dns2(listen_addr2);
3603 StartDns(dns1, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3604 StartDns(dns2, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3605 addrinfo hints = {.ai_family = AF_INET};
3606
3607 // step 1: set server#1 into deferred responding mode
3608 dns1.setDeferredResp(true);
3609 std::thread t1([&listen_addr1, &hints, this]() {
3610 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr1}));
3611 // step 3: query
3612 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3613 // step 9: check result
3614 EXPECT_TRUE(result != nullptr);
3615 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3616 });
3617
3618 // step 2: wait for the query to reach the server
3619 while (GetNumQueries(dns1, kHelloExampleCom) == 0) {
3620 usleep(1000); // 1ms
3621 }
3622
3623 std::thread t2([&listen_addr2, &hints, &dns2, this]() {
3624 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr2}));
3625 // step 5: query (should be blocked in resolver)
3626 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3627 // step 7: check result
3628 EXPECT_TRUE(result != nullptr);
3629 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3630 EXPECT_EQ(1U, GetNumQueriesForType(dns2, ns_type::ns_t_a, kHelloExampleCom));
3631 });
3632
3633 // step 4: wait a bit for the 2nd query to enter pending state
3634 usleep(100 * 1000); // 100ms
3635 // step 6: flush cache (will unblock pending queries)
3636 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
3637 t2.join();
3638
3639 // step 8: resume server#1
3640 dns1.setDeferredResp(false);
3641 t1.join();
3642
3643 // step 10: verify if result is correctly cached
3644 dns2.clearQueries();
3645 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3646 EXPECT_EQ(0U, GetNumQueries(dns2, kHelloExampleCom));
3647 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3648}
3649
Hungming Chenbb90ab32019-10-28 18:20:31 +08003650// Parameterized tests.
3651// TODO: Merge the existing tests as parameterized test if possible.
3652// TODO: Perhaps move parameterized tests to an independent file.
3653enum class CallType { GETADDRINFO, GETHOSTBYNAME };
3654class ResolverParameterizedTest : public ResolverTest,
Hungming Chen63779052019-10-30 15:06:13 +08003655 public testing::WithParamInterface<CallType> {
3656 protected:
3657 void VerifyQueryHelloExampleComV4(const test::DNSResponder& dns, const CallType calltype) {
3658 if (calltype == CallType::GETADDRINFO) {
3659 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
3660 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3661 ASSERT_TRUE(result != nullptr);
3662 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3663 } else if (calltype == CallType::GETHOSTBYNAME) {
3664 const hostent* result = gethostbyname("hello");
3665 ASSERT_TRUE(result != nullptr);
3666 ASSERT_EQ(4, result->h_length);
3667 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
3668 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3669 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
3670 } else {
3671 FAIL() << "Unsupported call type: " << static_cast<uint32_t>(calltype);
3672 }
3673 EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
3674 }
3675};
Hungming Chenbb90ab32019-10-28 18:20:31 +08003676
Hungming Chen63779052019-10-30 15:06:13 +08003677INSTANTIATE_TEST_SUITE_P(QueryCallTest, ResolverParameterizedTest,
Hungming Chenbb90ab32019-10-28 18:20:31 +08003678 testing::Values(CallType::GETADDRINFO, CallType::GETHOSTBYNAME),
3679 [](const testing::TestParamInfo<CallType>& info) {
Hungming Chenbb90ab32019-10-28 18:20:31 +08003680 switch (info.param) {
3681 case CallType::GETADDRINFO:
Hungming Chen63779052019-10-30 15:06:13 +08003682 return "GetAddrInfo";
Hungming Chenbb90ab32019-10-28 18:20:31 +08003683 case CallType::GETHOSTBYNAME:
Hungming Chen63779052019-10-30 15:06:13 +08003684 return "GetHostByName";
Hungming Chenbb90ab32019-10-28 18:20:31 +08003685 default:
Hungming Chen63779052019-10-30 15:06:13 +08003686 return "InvalidParameter"; // Should not happen.
Hungming Chenbb90ab32019-10-28 18:20:31 +08003687 }
Hungming Chenbb90ab32019-10-28 18:20:31 +08003688 });
3689
3690TEST_P(ResolverParameterizedTest, AuthoritySectionAndAdditionalSection) {
3691 // DNS response may have more information in authority section and additional section.
3692 // Currently, getanswer() of packages/modules/DnsResolver/getaddrinfo.cpp doesn't parse the
3693 // content of authority section and additional section. Test these sections if they crash
3694 // the resolver, just in case. See also RFC 1035 section 4.1.
3695 const auto& calltype = GetParam();
3696 test::DNSHeader header(kDefaultDnsHeader);
3697
3698 // Create a DNS response which has a authoritative nameserver record in authority
3699 // section and its relevant address record in additional section.
3700 //
3701 // Question
3702 // hello.example.com. IN A
3703 // Answer
3704 // hello.example.com. IN A 1.2.3.4
3705 // Authority:
3706 // hello.example.com. IN NS ns1.example.com.
3707 // Additional:
3708 // ns1.example.com. IN A 5.6.7.8
3709 //
3710 // A response may have only question, answer, and authority section. Current testing response
3711 // should be able to cover this condition.
3712
3713 // Question section.
3714 test::DNSQuestion question{
3715 .qname = {.name = kHelloExampleCom},
3716 .qtype = ns_type::ns_t_a,
3717 .qclass = ns_c_in,
3718 };
3719 header.questions.push_back(std::move(question));
3720
3721 // Answer section.
3722 test::DNSRecord recordAnswer{
3723 .name = {.name = kHelloExampleCom},
3724 .rtype = ns_type::ns_t_a,
3725 .rclass = ns_c_in,
3726 .ttl = 0, // no cache
3727 };
Hungming Chen63779052019-10-30 15:06:13 +08003728 EXPECT_TRUE(test::DNSResponder::fillRdata(kHelloExampleComAddrV4, recordAnswer));
Hungming Chenbb90ab32019-10-28 18:20:31 +08003729 header.answers.push_back(std::move(recordAnswer));
3730
3731 // Authority section.
3732 test::DNSRecord recordAuthority{
3733 .name = {.name = kHelloExampleCom},
3734 .rtype = ns_type::ns_t_ns,
3735 .rclass = ns_c_in,
3736 .ttl = 0, // no cache
3737 };
3738 EXPECT_TRUE(test::DNSResponder::fillRdata("ns1.example.com.", recordAuthority));
3739 header.authorities.push_back(std::move(recordAuthority));
3740
3741 // Additional section.
3742 test::DNSRecord recordAdditional{
3743 .name = {.name = "ns1.example.com."},
3744 .rtype = ns_type::ns_t_a,
3745 .rclass = ns_c_in,
3746 .ttl = 0, // no cache
3747 };
3748 EXPECT_TRUE(test::DNSResponder::fillRdata("5.6.7.8", recordAdditional));
3749 header.additionals.push_back(std::move(recordAdditional));
3750
3751 // Start DNS server.
3752 test::DNSResponder dns(test::DNSResponder::MappingType::DNS_HEADER);
3753 dns.addMappingDnsHeader(kHelloExampleCom, ns_type::ns_t_a, header);
3754 ASSERT_TRUE(dns.startServer());
3755 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3756 dns.clearQueries();
3757
3758 // Expect that get the address and the resolver doesn't crash.
Hungming Chen63779052019-10-30 15:06:13 +08003759 VerifyQueryHelloExampleComV4(dns, calltype);
3760}
3761
3762TEST_P(ResolverParameterizedTest, MessageCompression) {
3763 const auto& calltype = GetParam();
3764
3765 // The response with compressed domain name by a pointer. See RFC 1035 section 4.1.4.
3766 //
3767 // Ignoring the other fields of the message, the domain name of question section and answer
3768 // section are presented as:
3769 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3770 // 12 | 5 | h |
3771 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3772 // 14 | e | l |
3773 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3774 // 16 | l | o |
3775 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3776 // 18 | 7 | e |
3777 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3778 // 20 | x | a |
3779 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3780 // 22 | m | p |
3781 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3782 // 24 | l | e |
3783 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3784 // 26 | 3 | c |
3785 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3786 // 28 | o | m |
3787 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3788 // 30 | 0 | ... |
3789 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3790 //
3791 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3792 // 35 | 1 1| 12 |
3793 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3794 const std::vector<uint8_t> kResponseAPointer = {
3795 /* Header */
3796 0x00, 0x00, /* Transaction ID: 0x0000 */
3797 0x81, 0x80, /* Flags: qr rd ra */
3798 0x00, 0x01, /* Questions: 1 */
3799 0x00, 0x01, /* Answer RRs: 1 */
3800 0x00, 0x00, /* Authority RRs: 0 */
3801 0x00, 0x00, /* Additional RRs: 0 */
3802 /* Queries */
3803 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
3804 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
3805 0x00, 0x01, /* Type: A */
3806 0x00, 0x01, /* Class: IN */
3807 /* Answers */
3808 0xc0, 0x0c, /* Name: hello.example.com (a pointer) */
3809 0x00, 0x01, /* Type: A */
3810 0x00, 0x01, /* Class: IN */
3811 0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */
3812 0x00, 0x04, /* Data length: 4 */
3813 0x01, 0x02, 0x03, 0x04 /* Address: 1.2.3.4 */
3814 };
3815
3816 // The response with compressed domain name by a sequence of labels ending with a pointer. See
3817 // RFC 1035 section 4.1.4.
3818 //
3819 // Ignoring the other fields of the message, the domain name of question section and answer
3820 // section are presented as:
3821 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3822 // 12 | 5 | h |
3823 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3824 // 14 | e | l |
3825 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3826 // 16 | l | o |
3827 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3828 // 18 | 7 | e |
3829 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3830 // 20 | x | a |
3831 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3832 // 22 | m | p |
3833 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3834 // 24 | l | e |
3835 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3836 // 26 | 3 | c |
3837 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3838 // 28 | o | m |
3839 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3840 // 30 | 0 | ... |
3841 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3842 //
3843 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3844 // 35 | 5 | h |
3845 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3846 // 37 | e | l |
3847 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3848 // 39 | l | o |
3849 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3850 // 41 | 1 1| 18 |
3851 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3852 const std::vector<uint8_t> kResponseLabelEndingWithAPointer = {
3853 /* Header */
3854 0x00, 0x00, /* Transaction ID: 0x0000 */
3855 0x81, 0x80, /* Flags: qr rd ra */
3856 0x00, 0x01, /* Questions: 1 */
3857 0x00, 0x01, /* Answer RRs: 1 */
3858 0x00, 0x00, /* Authority RRs: 0 */
3859 0x00, 0x00, /* Additional RRs: 0 */
3860 /* Queries */
3861 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
3862 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
3863 0x00, 0x01, /* Type: A */
3864 0x00, 0x01, /* Class: IN */
3865 /* Answers */
3866 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0xc0,
3867 0x12, /* Name: hello.example.com (a label ending with a pointer) */
3868 0x00, 0x01, /* Type: A */
3869 0x00, 0x01, /* Class: IN */
3870 0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */
3871 0x00, 0x04, /* Data length: 4 */
3872 0x01, 0x02, 0x03, 0x04 /* Address: 1.2.3.4 */
3873 };
3874
3875 for (const auto& response : {kResponseAPointer, kResponseLabelEndingWithAPointer}) {
3876 SCOPED_TRACE(StringPrintf("Hex dump: %s", toHex(makeSlice(response)).c_str()));
3877
3878 test::DNSResponder dns(test::DNSResponder::MappingType::BINARY_PACKET);
3879 dns.addMappingBinaryPacket(kHelloExampleComQueryV4, response);
3880 StartDns(dns, {});
3881 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3882
3883 // Expect no cache because the TTL of testing responses are 0.
3884 VerifyQueryHelloExampleComV4(dns, calltype);
Hungming Chenbb90ab32019-10-28 18:20:31 +08003885 }
Mike Yu40e67072019-10-09 21:14:09 +08003886}