blob: 4f8f976fab5ed4a0b0767d788430915899c9e4ee [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>
41#include <poll.h> /* poll */
Bernie Innocenti41b82c42019-06-05 22:38:25 +090042#include <private/android_filesystem_config.h>
Luke Huang94b10b92018-11-21 20:13:38 +080043#include <resolv.h>
Ken Chenb9fa2062018-11-13 21:51:13 +080044#include <stdarg.h>
Ken Chenb9fa2062018-11-13 21:51:13 +080045#include <stdlib.h>
Luke Huang94b10b92018-11-21 20:13:38 +080046#include <sys/socket.h>
47#include <sys/un.h>
Ken Chenb9fa2062018-11-13 21:51:13 +080048#include <unistd.h>
49
50#include <algorithm>
51#include <chrono>
52#include <iterator>
53#include <numeric>
54#include <thread>
55
Luke Huangf8215372019-11-22 11:53:41 +080056#include <aidl/android/net/IDnsResolver.h>
57#include <android/binder_manager.h>
58#include <android/binder_process.h>
Bernie Innocenti41b82c42019-06-05 22:38:25 +090059#include "NetdClient.h"
Bernie Innocenti41b82c42019-06-05 22:38:25 +090060#include "ResolverStats.h"
Luke Huangf8215372019-11-22 11:53:41 +080061#include "netid_client.h" // NETID_UNSET
62#include "params.h" // MAXNS
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +090063#include "test_utils.h"
Hungming Chene8f970c2019-04-10 17:34:06 +080064#include "tests/dns_metrics_listener/dns_metrics_listener.h"
chenbruceb43ec752019-07-24 20:19:41 +080065#include "tests/dns_responder/dns_responder.h"
Luke Huangf8215372019-11-22 11:53:41 +080066#include "tests/dns_responder/dns_responder_client_ndk.h"
Hungming Chenc6556622019-10-02 16:01:07 +080067#include "tests/dns_responder/dns_tls_certificate.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
Ken Chenb9fa2062018-11-13 21:51:13 +080078// Semi-public Bionic hook used by the NDK (frameworks/base/native/android/net.c)
79// Tested here for convenience.
80extern "C" int android_getaddrinfofornet(const char* hostname, const char* servname,
81 const addrinfo* hints, unsigned netid, unsigned mark,
82 struct addrinfo** result);
83
Luke Huang70070852019-11-25 18:25:50 +080084using aidl::android::net::IDnsResolver;
Luke Huangf8215372019-11-22 11:53:41 +080085using aidl::android::net::INetd;
Mike Yu8ac63402019-12-02 15:28:38 +080086using aidl::android::net::ResolverParamsParcel;
Luke Huang9807e6b2019-05-20 16:17:12 +080087using android::base::ParseInt;
Ken Chenb9fa2062018-11-13 21:51:13 +080088using android::base::StringPrintf;
Luke Huang9807e6b2019-05-20 16:17:12 +080089using android::base::unique_fd;
Ken Chenb9fa2062018-11-13 21:51:13 +080090using android::net::ResolverStats;
Hungming Chene8f970c2019-04-10 17:34:06 +080091using android::net::metrics::DnsMetricsListener;
Ken Chenb9fa2062018-11-13 21:51:13 +080092using android::netdutils::enableSockopt;
Hungming Chen63779052019-10-30 15:06:13 +080093using android::netdutils::makeSlice;
Luke Huang9807e6b2019-05-20 16:17:12 +080094using android::netdutils::ResponseCode;
Luke Huang9d2d25b2019-06-14 00:34:05 +080095using android::netdutils::ScopedAddrinfo;
Mike Yu40e67072019-10-09 21:14:09 +080096using android::netdutils::Stopwatch;
Hungming Chen63779052019-10-30 15:06:13 +080097using android::netdutils::toHex;
Ken Chenb9fa2062018-11-13 21:51:13 +080098
99// TODO: move into libnetdutils?
100namespace {
Luke Huangfde82482019-06-04 01:04:53 +0800101
Ken Chenb9fa2062018-11-13 21:51:13 +0800102ScopedAddrinfo safe_getaddrinfo(const char* node, const char* service,
103 const struct addrinfo* hints) {
104 addrinfo* result = nullptr;
105 if (getaddrinfo(node, service, hints, &result) != 0) {
106 result = nullptr; // Should already be the case, but...
107 }
108 return ScopedAddrinfo(result);
109}
Luke Huangfde82482019-06-04 01:04:53 +0800110
Mike Yu40e67072019-10-09 21:14:09 +0800111std::pair<ScopedAddrinfo, int> safe_getaddrinfo_time_taken(const char* node, const char* service,
112 const addrinfo& hints) {
113 Stopwatch s;
114 ScopedAddrinfo result = safe_getaddrinfo(node, service, &hints);
115 return {std::move(result), s.timeTakenUs() / 1000};
116}
117
Ken Chenb9fa2062018-11-13 21:51:13 +0800118} // namespace
119
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900120class ResolverTest : public ::testing::Test {
Hungming Chene8f970c2019-04-10 17:34:06 +0800121 public:
Hungming Chen5bf09772019-04-25 11:16:13 +0800122 static void SetUpTestCase() {
123 // Get binder service.
124 // Note that |mDnsClient| is not used for getting binder service in this static function.
125 // The reason is that wants to keep |mDnsClient| as a non-static data member. |mDnsClient|
126 // which sets up device network configuration could be independent from every test.
Luke Huangf8215372019-11-22 11:53:41 +0800127 // TODO: Perhaps add a static function in resolv_test_binder_utils.{cpp,h} to get binder
128 // service.
129
130 AIBinder* binder = AServiceManager_getService("dnsresolver");
131 ndk::SpAIBinder resolvBinder = ndk::SpAIBinder(binder);
132 auto resolvService = aidl::android::net::IDnsResolver::fromBinder(resolvBinder);
Hungming Chen5bf09772019-04-25 11:16:13 +0800133 ASSERT_NE(nullptr, resolvService.get());
134
135 // Subscribe the death recipient to the service IDnsResolver for detecting Netd death.
Luke Huang70070852019-11-25 18:25:50 +0800136 // GTEST assertion macros are not invoked for generating a test failure in the death
137 // recipient because the macros can't indicate failed test if Netd died between tests.
138 // Moreover, continuing testing may have no meaningful after Netd death. Therefore, the
139 // death recipient aborts process by GTEST_LOG_(FATAL) once Netd died.
Luke Huangf8215372019-11-22 11:53:41 +0800140 sResolvDeathRecipient = AIBinder_DeathRecipient_new([](void*) {
141 constexpr char errorMessage[] = "Netd died";
142 LOG(ERROR) << errorMessage;
143 GTEST_LOG_(FATAL) << errorMessage;
144 });
145 ASSERT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, sResolvDeathRecipient, nullptr));
Hungming Chen5bf09772019-04-25 11:16:13 +0800146
147 // Subscribe the DNS listener for verifying DNS metrics event contents.
Luke Huangf8215372019-11-22 11:53:41 +0800148 sDnsMetricsListener = ndk::SharedRefBase::make<DnsMetricsListener>(
149 TEST_NETID /*monitor specific network*/);
Hungming Chen5bf09772019-04-25 11:16:13 +0800150 ASSERT_TRUE(resolvService->registerEventListener(sDnsMetricsListener).isOk());
151
152 // Start the binder thread pool for listening DNS metrics events and receiving death
153 // recipient.
Luke Huangf8215372019-11-22 11:53:41 +0800154 ABinderProcess_startThreadPool();
Hungming Chene8f970c2019-04-10 17:34:06 +0800155 }
Luke Huangf8215372019-11-22 11:53:41 +0800156 static void TearDownTestCase() { AIBinder_DeathRecipient_delete(sResolvDeathRecipient); }
Hungming Chene8f970c2019-04-10 17:34:06 +0800157
Ken Chenb9fa2062018-11-13 21:51:13 +0800158 protected:
Xiao Ma09b71022018-12-11 17:56:32 +0900159 struct DnsRecord {
160 std::string host_name; // host name
161 ns_type type; // record type
162 std::string addr; // ipv4/v6 address
163 };
164
Hungming Chen5bf09772019-04-25 11:16:13 +0800165 void SetUp() { mDnsClient.SetUp(); }
Hungming Chene8f970c2019-04-10 17:34:06 +0800166 void TearDown() { mDnsClient.TearDown(); }
nuccachena26cc2a2018-07-17 18:07:23 +0800167
Xiao Ma09b71022018-12-11 17:56:32 +0900168 void StartDns(test::DNSResponder& dns, const std::vector<DnsRecord>& records) {
169 for (const auto& r : records) {
170 dns.addMapping(r.host_name, r.type, r.addr);
171 }
172
173 ASSERT_TRUE(dns.startServer());
174 dns.clearQueries();
175 }
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900176
Hungming Chene8f970c2019-04-10 17:34:06 +0800177 bool WaitForNat64Prefix(ExpectNat64PrefixStatus status,
178 std::chrono::milliseconds timeout = std::chrono::milliseconds(1000)) {
Hungming Chen5bf09772019-04-25 11:16:13 +0800179 return sDnsMetricsListener->waitForNat64Prefix(status, timeout);
Hungming Chene8f970c2019-04-10 17:34:06 +0800180 }
181
Mike Yu724f77d2019-08-16 11:14:50 +0800182 bool WaitForPrivateDnsValidation(std::string serverAddr, bool validated) {
183 return sDnsMetricsListener->waitForPrivateDnsValidation(serverAddr, validated);
184 }
185
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900186 DnsResponderClient mDnsClient;
Xiao Ma09b71022018-12-11 17:56:32 +0900187
Hungming Chen5bf09772019-04-25 11:16:13 +0800188 // Use a shared static DNS listener for all tests to avoid registering lots of listeners
189 // which may be released late until process terminated. Currently, registered DNS listener
190 // is removed by binder death notification which is fired when the process hosting an
191 // IBinder has gone away. If every test in ResolverTest registers its DNS listener, Netd
192 // may temporarily hold lots of dead listeners until the unit test process terminates.
193 // TODO: Perhaps add an unregistering listener binder call or fork a listener process which
194 // could be terminated earlier.
Luke Huangf8215372019-11-22 11:53:41 +0800195 static std::shared_ptr<DnsMetricsListener>
196 sDnsMetricsListener; // Initialized in SetUpTestCase.
Hungming Chen5bf09772019-04-25 11:16:13 +0800197
198 // Use a shared static death recipient to monitor the service death. The static death
199 // recipient could monitor the death not only during the test but also between tests.
Luke Huangf8215372019-11-22 11:53:41 +0800200 static AIBinder_DeathRecipient* sResolvDeathRecipient; // Initialized in SetUpTestCase.
Ken Chenb9fa2062018-11-13 21:51:13 +0800201};
202
Hungming Chen5bf09772019-04-25 11:16:13 +0800203// Initialize static member of class.
Luke Huangf8215372019-11-22 11:53:41 +0800204std::shared_ptr<DnsMetricsListener> ResolverTest::sDnsMetricsListener;
205AIBinder_DeathRecipient* ResolverTest::sResolvDeathRecipient;
Hungming Chen5bf09772019-04-25 11:16:13 +0800206
Ken Chenb9fa2062018-11-13 21:51:13 +0800207TEST_F(ResolverTest, GetHostByName) {
Xiao Ma09b71022018-12-11 17:56:32 +0900208 constexpr char nonexistent_host_name[] = "nonexistent.example.com.";
209
210 test::DNSResponder dns;
211 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.3"}});
212 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800213
214 const hostent* result;
Ken Chenb9fa2062018-11-13 21:51:13 +0800215 result = gethostbyname("nonexistent");
216 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, nonexistent_host_name));
217 ASSERT_TRUE(result == nullptr);
218 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
219
220 dns.clearQueries();
221 result = gethostbyname("hello");
Xiao Ma09b71022018-12-11 17:56:32 +0900222 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
Ken Chenb9fa2062018-11-13 21:51:13 +0800223 ASSERT_FALSE(result == nullptr);
224 ASSERT_EQ(4, result->h_length);
225 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
226 EXPECT_EQ("1.2.3.3", ToString(result));
227 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800228}
229
lifr4e4a2e02019-01-29 16:53:51 +0800230TEST_F(ResolverTest, GetHostByName_cnames) {
231 constexpr char host_name[] = "host.example.com.";
232 size_t cnamecount = 0;
233 test::DNSResponder dns;
234
235 const std::vector<DnsRecord> records = {
236 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
237 {"a.example.com.", ns_type::ns_t_cname, "b.example.com."},
238 {"b.example.com.", ns_type::ns_t_cname, "c.example.com."},
239 {"c.example.com.", ns_type::ns_t_cname, "d.example.com."},
240 {"d.example.com.", ns_type::ns_t_cname, "e.example.com."},
241 {"e.example.com.", ns_type::ns_t_cname, host_name},
242 {host_name, ns_type::ns_t_a, "1.2.3.3"},
243 {host_name, ns_type::ns_t_aaaa, "2001:db8::42"},
244 };
245 StartDns(dns, records);
246 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
247
248 // using gethostbyname2() to resolve ipv4 hello.example.com. to 1.2.3.3
249 // Ensure the v4 address and cnames are correct
250 const hostent* result;
251 result = gethostbyname2("hello", AF_INET);
252 ASSERT_FALSE(result == nullptr);
253
254 for (int i = 0; result != nullptr && result->h_aliases[i] != nullptr; i++) {
255 std::string domain_name = records[i].host_name.substr(0, records[i].host_name.size() - 1);
256 EXPECT_EQ(result->h_aliases[i], domain_name);
257 cnamecount++;
258 }
259 // The size of "Non-cname type" record in DNS records is 2
260 ASSERT_EQ(cnamecount, records.size() - 2);
261 ASSERT_EQ(4, result->h_length);
262 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
263 EXPECT_EQ("1.2.3.3", ToString(result));
264 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
265 EXPECT_EQ(1U, dns.queries().size()) << dns.dumpQueries();
266
267 // using gethostbyname2() to resolve ipv6 hello.example.com. to 2001:db8::42
268 // Ensure the v6 address and cnames are correct
269 cnamecount = 0;
270 dns.clearQueries();
271 result = gethostbyname2("hello", AF_INET6);
272 for (unsigned i = 0; result != nullptr && result->h_aliases[i] != nullptr; i++) {
273 std::string domain_name = records[i].host_name.substr(0, records[i].host_name.size() - 1);
274 EXPECT_EQ(result->h_aliases[i], domain_name);
275 cnamecount++;
276 }
277 // The size of "Non-cname type" DNS record in records is 2
278 ASSERT_EQ(cnamecount, records.size() - 2);
279 ASSERT_FALSE(result == nullptr);
280 ASSERT_EQ(16, result->h_length);
281 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
282 EXPECT_EQ("2001:db8::42", ToString(result));
283 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
284}
285
286TEST_F(ResolverTest, GetHostByName_cnamesInfiniteLoop) {
287 test::DNSResponder dns;
288 const std::vector<DnsRecord> records = {
289 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
290 {"a.example.com.", ns_type::ns_t_cname, kHelloExampleCom},
291 };
292 StartDns(dns, records);
293 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
294
295 const hostent* result;
296 result = gethostbyname2("hello", AF_INET);
297 ASSERT_TRUE(result == nullptr);
298
299 dns.clearQueries();
300 result = gethostbyname2("hello", AF_INET6);
301 ASSERT_TRUE(result == nullptr);
302}
303
Ken Chenb9fa2062018-11-13 21:51:13 +0800304TEST_F(ResolverTest, GetHostByName_localhost) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800305 constexpr char name_camelcase[] = "LocalHost";
Ken Chenb9fa2062018-11-13 21:51:13 +0800306 constexpr char name_ip6_dot[] = "ip6-localhost.";
307 constexpr char name_ip6_fqdn[] = "ip6-localhost.example.com.";
308
309 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma09b71022018-12-11 17:56:32 +0900310 test::DNSResponder dns;
311 StartDns(dns, {});
312 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800313
314 // Expect no DNS queries; localhost is resolved via /etc/hosts
Xiao Ma09b71022018-12-11 17:56:32 +0900315 const hostent* result = gethostbyname(kLocalHost);
Ken Chenb9fa2062018-11-13 21:51:13 +0800316 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
317 ASSERT_FALSE(result == nullptr);
318 ASSERT_EQ(4, result->h_length);
319 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900320 EXPECT_EQ(kLocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800321 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
322
323 // Ensure the hosts file resolver ignores case of hostnames
324 result = gethostbyname(name_camelcase);
325 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
326 ASSERT_FALSE(result == nullptr);
327 ASSERT_EQ(4, result->h_length);
328 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900329 EXPECT_EQ(kLocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800330 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
331
332 // The hosts file also contains ip6-localhost, but gethostbyname() won't
chenbruce018fdb22019-06-12 18:08:04 +0800333 // return it. This would be easy to
Ken Chenb9fa2062018-11-13 21:51:13 +0800334 // change, but there's no point in changing the legacy behavior; new code
335 // should be calling getaddrinfo() anyway.
336 // So we check the legacy behavior, which results in amusing A-record
337 // lookups for ip6-localhost, with and without search domains appended.
338 dns.clearQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900339 result = gethostbyname(kIp6LocalHost);
Sehee Parkbbca0202018-11-16 10:53:16 +0900340 EXPECT_EQ(2U, dns.queries().size()) << dns.dumpQueries();
341 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, name_ip6_dot)) << dns.dumpQueries();
342 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, name_ip6_fqdn)) << dns.dumpQueries();
Ken Chenb9fa2062018-11-13 21:51:13 +0800343 ASSERT_TRUE(result == nullptr);
344
345 // Finally, use gethostbyname2() to resolve ip6-localhost to ::1 from
346 // the hosts file.
347 dns.clearQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900348 result = gethostbyname2(kIp6LocalHost, AF_INET6);
Ken Chenb9fa2062018-11-13 21:51:13 +0800349 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
350 ASSERT_FALSE(result == nullptr);
351 ASSERT_EQ(16, result->h_length);
352 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900353 EXPECT_EQ(kIp6LocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800354 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800355}
356
357TEST_F(ResolverTest, GetHostByName_numeric) {
358 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma09b71022018-12-11 17:56:32 +0900359 test::DNSResponder dns;
360 StartDns(dns, {});
361 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800362
363 // Numeric v4 address: expect no DNS queries
364 constexpr char numeric_v4[] = "192.168.0.1";
Ken Chenb9fa2062018-11-13 21:51:13 +0800365 const hostent* result = gethostbyname(numeric_v4);
Sehee Parkbbca0202018-11-16 10:53:16 +0900366 EXPECT_EQ(0U, dns.queries().size());
Ken Chenb9fa2062018-11-13 21:51:13 +0800367 ASSERT_FALSE(result == nullptr);
368 ASSERT_EQ(4, result->h_length); // v4
369 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
370 EXPECT_EQ(numeric_v4, ToString(result));
371 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
372
373 // gethostbyname() recognizes a v6 address, and fails with no DNS queries
374 constexpr char numeric_v6[] = "2001:db8::42";
375 dns.clearQueries();
376 result = gethostbyname(numeric_v6);
Sehee Parkbbca0202018-11-16 10:53:16 +0900377 EXPECT_EQ(0U, dns.queries().size());
Ken Chenb9fa2062018-11-13 21:51:13 +0800378 EXPECT_TRUE(result == nullptr);
379
380 // Numeric v6 address with gethostbyname2(): succeeds with no DNS queries
381 dns.clearQueries();
382 result = gethostbyname2(numeric_v6, AF_INET6);
Sehee Parkbbca0202018-11-16 10:53:16 +0900383 EXPECT_EQ(0U, dns.queries().size());
Ken Chenb9fa2062018-11-13 21:51:13 +0800384 ASSERT_FALSE(result == nullptr);
385 ASSERT_EQ(16, result->h_length); // v6
386 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
387 EXPECT_EQ(numeric_v6, ToString(result));
388 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
389
390 // Numeric v6 address with scope work with getaddrinfo(),
391 // but gethostbyname2() does not understand them; it issues two dns
392 // queries, then fails. This hardly ever happens, there's no point
393 // in fixing this. This test simply verifies the current (bogus)
394 // behavior to avoid further regressions (like crashes, or leaks).
395 constexpr char numeric_v6_scope[] = "fe80::1%lo";
396 dns.clearQueries();
397 result = gethostbyname2(numeric_v6_scope, AF_INET6);
Sehee Parkbbca0202018-11-16 10:53:16 +0900398 EXPECT_EQ(2U, dns.queries().size()); // OUCH!
Ken Chenb9fa2062018-11-13 21:51:13 +0800399 ASSERT_TRUE(result == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800400}
401
402TEST_F(ResolverTest, BinderSerialization) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800403 std::vector<int> params_offsets = {
Luke Huang5bd827c2019-03-14 16:10:04 +0800404 IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY,
405 IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD,
406 IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES,
407 IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES,
408 IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC,
409 IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT,
Ken Chenb9fa2062018-11-13 21:51:13 +0800410 };
Bernie Innocentib102dd22018-12-04 14:57:48 +0900411 const int size = static_cast<int>(params_offsets.size());
Luke Huang5bd827c2019-03-14 16:10:04 +0800412 EXPECT_EQ(size, IDnsResolver::RESOLVER_PARAMS_COUNT);
Ken Chenb9fa2062018-11-13 21:51:13 +0800413 std::sort(params_offsets.begin(), params_offsets.end());
Bernie Innocentib102dd22018-12-04 14:57:48 +0900414 for (int i = 0; i < size; ++i) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800415 EXPECT_EQ(params_offsets[i], i);
416 }
417}
418
419TEST_F(ResolverTest, GetHostByName_Binder) {
Luke Huangf8215372019-11-22 11:53:41 +0800420 std::vector<std::string> domains = {"example.com"};
Ken Chenb9fa2062018-11-13 21:51:13 +0800421 std::vector<std::unique_ptr<test::DNSResponder>> dns;
422 std::vector<std::string> servers;
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900423 std::vector<DnsResponderClient::Mapping> mappings;
424 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupMappings(1, domains, &mappings));
425 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupDNSServers(4, mappings, &dns, &servers));
Ken Chenb9fa2062018-11-13 21:51:13 +0800426 ASSERT_EQ(1U, mappings.size());
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900427 const DnsResponderClient::Mapping& mapping = mappings[0];
Ken Chenb9fa2062018-11-13 21:51:13 +0800428
Xiao Ma09b71022018-12-11 17:56:32 +0900429 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains, kDefaultParams));
Ken Chenb9fa2062018-11-13 21:51:13 +0800430
431 const hostent* result = gethostbyname(mapping.host.c_str());
Bernie Innocentib102dd22018-12-04 14:57:48 +0900432 const size_t total_queries =
Luke Huangfde82482019-06-04 01:04:53 +0800433 std::accumulate(dns.begin(), dns.end(), 0, [&mapping](size_t total, auto& d) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800434 return total + GetNumQueriesForType(*d, ns_type::ns_t_a, mapping.entry.c_str());
435 });
436
437 EXPECT_LE(1U, total_queries);
438 ASSERT_FALSE(result == nullptr);
439 ASSERT_EQ(4, result->h_length);
440 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
441 EXPECT_EQ(mapping.ip4, ToString(result));
442 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
443
444 std::vector<std::string> res_servers;
445 std::vector<std::string> res_domains;
Mike Yu0a1c53d2018-11-26 13:26:21 +0900446 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900447 res_params res_params;
Ken Chenb9fa2062018-11-13 21:51:13 +0800448 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +0800449 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800450 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
451 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
452 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chenb9fa2062018-11-13 21:51:13 +0800453 EXPECT_EQ(servers.size(), res_servers.size());
454 EXPECT_EQ(domains.size(), res_domains.size());
Mike Yu0a1c53d2018-11-26 13:26:21 +0900455 EXPECT_EQ(0U, res_tls_servers.size());
Luke Huang5bd827c2019-03-14 16:10:04 +0800456 ASSERT_EQ(static_cast<size_t>(IDnsResolver::RESOLVER_PARAMS_COUNT), kDefaultParams.size());
457 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY],
458 res_params.sample_validity);
459 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD],
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900460 res_params.success_threshold);
Luke Huang5bd827c2019-03-14 16:10:04 +0800461 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
462 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
463 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
Ken Chenb9fa2062018-11-13 21:51:13 +0800464 res_params.base_timeout_msec);
465 EXPECT_EQ(servers.size(), res_stats.size());
466
Bernie Innocenti0c067e42019-04-01 15:33:16 +0900467 EXPECT_THAT(res_servers, testing::UnorderedElementsAreArray(servers));
468 EXPECT_THAT(res_domains, testing::UnorderedElementsAreArray(domains));
Ken Chenb9fa2062018-11-13 21:51:13 +0800469}
470
471TEST_F(ResolverTest, GetAddrInfo) {
Xiao Ma09b71022018-12-11 17:56:32 +0900472 constexpr char listen_addr[] = "127.0.0.4";
473 constexpr char listen_addr2[] = "127.0.0.5";
474 constexpr char host_name[] = "howdy.example.com.";
Ken Chenb9fa2062018-11-13 21:51:13 +0800475
Xiao Ma09b71022018-12-11 17:56:32 +0900476 const std::vector<DnsRecord> records = {
477 {host_name, ns_type::ns_t_a, "1.2.3.4"},
478 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
479 };
480 test::DNSResponder dns(listen_addr);
481 test::DNSResponder dns2(listen_addr2);
482 StartDns(dns, records);
483 StartDns(dns2, records);
Ken Chenb9fa2062018-11-13 21:51:13 +0800484
Xiao Ma09b71022018-12-11 17:56:32 +0900485 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr}));
Ken Chenb9fa2062018-11-13 21:51:13 +0800486 dns.clearQueries();
487 dns2.clearQueries();
488
489 ScopedAddrinfo result = safe_getaddrinfo("howdy", nullptr, nullptr);
490 EXPECT_TRUE(result != nullptr);
491 size_t found = GetNumQueries(dns, host_name);
492 EXPECT_LE(1U, found);
493 // Could be A or AAAA
494 std::string result_str = ToString(result);
495 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
Luke Huangf8215372019-11-22 11:53:41 +0800496 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +0800497
498 // Verify that the name is cached.
499 size_t old_found = found;
500 result = safe_getaddrinfo("howdy", nullptr, nullptr);
501 EXPECT_TRUE(result != nullptr);
502 found = GetNumQueries(dns, host_name);
503 EXPECT_LE(1U, found);
504 EXPECT_EQ(old_found, found);
505 result_str = ToString(result);
Luke Huangf8215372019-11-22 11:53:41 +0800506 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4") << result_str;
Ken Chenb9fa2062018-11-13 21:51:13 +0800507
508 // Change the DNS resolver, ensure that queries are still cached.
Xiao Ma09b71022018-12-11 17:56:32 +0900509 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr2}));
Ken Chenb9fa2062018-11-13 21:51:13 +0800510 dns.clearQueries();
511 dns2.clearQueries();
512
513 result = safe_getaddrinfo("howdy", nullptr, nullptr);
514 EXPECT_TRUE(result != nullptr);
515 found = GetNumQueries(dns, host_name);
516 size_t found2 = GetNumQueries(dns2, host_name);
517 EXPECT_EQ(0U, found);
518 EXPECT_LE(0U, found2);
519
520 // Could be A or AAAA
521 result_str = ToString(result);
522 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
Luke Huangf8215372019-11-22 11:53:41 +0800523 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +0800524}
525
526TEST_F(ResolverTest, GetAddrInfoV4) {
Xiao Ma09b71022018-12-11 17:56:32 +0900527 test::DNSResponder dns;
528 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.5"}});
529 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800530
Xiao Ma09b71022018-12-11 17:56:32 +0900531 const addrinfo hints = {.ai_family = AF_INET};
532 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
Ken Chenb9fa2062018-11-13 21:51:13 +0800533 EXPECT_TRUE(result != nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900534 EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
Ken Chenb9fa2062018-11-13 21:51:13 +0800535 EXPECT_EQ("1.2.3.5", ToString(result));
536}
537
538TEST_F(ResolverTest, GetAddrInfo_localhost) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800539 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma09b71022018-12-11 17:56:32 +0900540 test::DNSResponder dns;
541 StartDns(dns, {});
542 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800543
Xiao Ma09b71022018-12-11 17:56:32 +0900544 ScopedAddrinfo result = safe_getaddrinfo(kLocalHost, nullptr, nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800545 EXPECT_TRUE(result != nullptr);
546 // Expect no DNS queries; localhost is resolved via /etc/hosts
547 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900548 EXPECT_EQ(kLocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800549
Xiao Ma09b71022018-12-11 17:56:32 +0900550 result = safe_getaddrinfo(kIp6LocalHost, nullptr, nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800551 EXPECT_TRUE(result != nullptr);
552 // Expect no DNS queries; ip6-localhost is resolved via /etc/hosts
553 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900554 EXPECT_EQ(kIp6LocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800555}
556
Luke Huangd8ac4752019-06-18 17:05:47 +0800557TEST_F(ResolverTest, GetAddrInfo_InvalidSocketType) {
558 test::DNSResponder dns;
559 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.5"}});
560 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
561
562 // TODO: Test other invalid socket types.
563 const addrinfo hints = {
564 .ai_family = AF_UNSPEC,
Luke Huangd8ac4752019-06-18 17:05:47 +0800565 .ai_socktype = SOCK_PACKET,
Nick Desaulnierscd6395a2019-10-11 09:15:24 -0700566 .ai_protocol = ANY,
Luke Huangd8ac4752019-06-18 17:05:47 +0800567 };
568 addrinfo* result = nullptr;
569 // This is a valid hint, but the query won't be sent because the socket type is
570 // not supported.
571 EXPECT_EQ(EAI_NODATA, getaddrinfo("hello", nullptr, &hints, &result));
572 ScopedAddrinfo result_cleanup(result);
573 EXPECT_EQ(nullptr, result);
574}
575
Ken Chen92bed612018-12-22 21:46:55 +0800576// Verify if the resolver correctly handle multiple queries simultaneously
577// step 1: set dns server#1 into deferred responding mode.
578// step 2: thread#1 query "hello.example.com." --> resolver send query to server#1.
579// step 3: thread#2 query "hello.example.com." --> resolver hold the request and wait for
580// response of previous pending query sent by thread#1.
581// step 4: thread#3 query "konbanha.example.com." --> resolver send query to server#3. Server
582// respond to resolver immediately.
583// step 5: check if server#1 get 1 query by thread#1, server#2 get 0 query, server#3 get 1 query.
584// step 6: resume dns server#1 to respond dns query in step#2.
585// step 7: thread#1 and #2 should get returned from DNS query after step#6. Also, check the
586// number of queries in server#2 is 0 to ensure thread#2 does not wake up unexpectedly
587// before signaled by thread#1.
588TEST_F(ResolverTest, GetAddrInfoV4_deferred_resp) {
589 const char* listen_addr1 = "127.0.0.9";
590 const char* listen_addr2 = "127.0.0.10";
591 const char* listen_addr3 = "127.0.0.11";
592 const char* listen_srv = "53";
593 const char* host_name_deferred = "hello.example.com.";
594 const char* host_name_normal = "konbanha.example.com.";
Mike Yufc125e42019-05-15 20:41:28 +0800595 test::DNSResponder dns1(listen_addr1, listen_srv, ns_rcode::ns_r_servfail);
596 test::DNSResponder dns2(listen_addr2, listen_srv, ns_rcode::ns_r_servfail);
597 test::DNSResponder dns3(listen_addr3, listen_srv, ns_rcode::ns_r_servfail);
Ken Chen92bed612018-12-22 21:46:55 +0800598 dns1.addMapping(host_name_deferred, ns_type::ns_t_a, "1.2.3.4");
599 dns2.addMapping(host_name_deferred, ns_type::ns_t_a, "1.2.3.4");
600 dns3.addMapping(host_name_normal, ns_type::ns_t_a, "1.2.3.5");
601 ASSERT_TRUE(dns1.startServer());
602 ASSERT_TRUE(dns2.startServer());
603 ASSERT_TRUE(dns3.startServer());
604 const std::vector<std::string> servers_for_t1 = {listen_addr1};
605 const std::vector<std::string> servers_for_t2 = {listen_addr2};
606 const std::vector<std::string> servers_for_t3 = {listen_addr3};
607 addrinfo hints = {.ai_family = AF_INET};
608 const std::vector<int> params = {300, 25, 8, 8, 5000};
609 bool t3_task_done = false;
610
611 dns1.setDeferredResp(true);
612 std::thread t1([&, this]() {
613 ASSERT_TRUE(
614 mDnsClient.SetResolversForNetwork(servers_for_t1, kDefaultSearchDomains, params));
615 ScopedAddrinfo result = safe_getaddrinfo(host_name_deferred, nullptr, &hints);
616 // t3's dns query should got returned first
617 EXPECT_TRUE(t3_task_done);
618 EXPECT_EQ(1U, GetNumQueries(dns1, host_name_deferred));
619 EXPECT_TRUE(result != nullptr);
620 EXPECT_EQ("1.2.3.4", ToString(result));
621 });
622
623 // ensuring t1 and t2 handler functions are processed in order
624 usleep(100 * 1000);
625 std::thread t2([&, this]() {
626 ASSERT_TRUE(
627 mDnsClient.SetResolversForNetwork(servers_for_t2, kDefaultSearchDomains, params));
628 ScopedAddrinfo result = safe_getaddrinfo(host_name_deferred, nullptr, &hints);
629 EXPECT_TRUE(t3_task_done);
630 EXPECT_EQ(0U, GetNumQueries(dns2, host_name_deferred));
631 EXPECT_TRUE(result != nullptr);
632 EXPECT_EQ("1.2.3.4", ToString(result));
633
634 std::vector<std::string> res_servers;
635 std::vector<std::string> res_domains;
636 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900637 res_params res_params;
Ken Chen92bed612018-12-22 21:46:55 +0800638 std::vector<ResolverStats> res_stats;
639 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800640 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
641 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains,
642 &res_tls_servers, &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chen92bed612018-12-22 21:46:55 +0800643 EXPECT_EQ(0, wait_for_pending_req_timeout_count);
644 });
645
646 // ensuring t2 and t3 handler functions are processed in order
647 usleep(100 * 1000);
648 std::thread t3([&, this]() {
649 ASSERT_TRUE(
650 mDnsClient.SetResolversForNetwork(servers_for_t3, kDefaultSearchDomains, params));
651 ScopedAddrinfo result = safe_getaddrinfo(host_name_normal, nullptr, &hints);
652 EXPECT_EQ(1U, GetNumQueries(dns1, host_name_deferred));
653 EXPECT_EQ(0U, GetNumQueries(dns2, host_name_deferred));
654 EXPECT_EQ(1U, GetNumQueries(dns3, host_name_normal));
655 EXPECT_TRUE(result != nullptr);
656 EXPECT_EQ("1.2.3.5", ToString(result));
657
658 t3_task_done = true;
659 dns1.setDeferredResp(false);
660 });
661 t3.join();
662 t1.join();
663 t2.join();
664}
665
lifr4e4a2e02019-01-29 16:53:51 +0800666TEST_F(ResolverTest, GetAddrInfo_cnames) {
667 constexpr char host_name[] = "host.example.com.";
668 test::DNSResponder dns;
669 const std::vector<DnsRecord> records = {
670 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
671 {"a.example.com.", ns_type::ns_t_cname, "b.example.com."},
672 {"b.example.com.", ns_type::ns_t_cname, "c.example.com."},
673 {"c.example.com.", ns_type::ns_t_cname, "d.example.com."},
674 {"d.example.com.", ns_type::ns_t_cname, "e.example.com."},
675 {"e.example.com.", ns_type::ns_t_cname, host_name},
676 {host_name, ns_type::ns_t_a, "1.2.3.3"},
677 {host_name, ns_type::ns_t_aaaa, "2001:db8::42"},
678 };
679 StartDns(dns, records);
680 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
681
682 addrinfo hints = {.ai_family = AF_INET};
683 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
684 EXPECT_TRUE(result != nullptr);
685 EXPECT_EQ("1.2.3.3", ToString(result));
686
687 dns.clearQueries();
688 hints = {.ai_family = AF_INET6};
689 result = safe_getaddrinfo("hello", nullptr, &hints);
690 EXPECT_TRUE(result != nullptr);
691 EXPECT_EQ("2001:db8::42", ToString(result));
692}
693
694TEST_F(ResolverTest, GetAddrInfo_cnamesNoIpAddress) {
695 test::DNSResponder dns;
696 const std::vector<DnsRecord> records = {
697 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
698 };
699 StartDns(dns, records);
700 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
701
702 addrinfo hints = {.ai_family = AF_INET};
703 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
704 EXPECT_TRUE(result == nullptr);
705
706 dns.clearQueries();
707 hints = {.ai_family = AF_INET6};
708 result = safe_getaddrinfo("hello", nullptr, &hints);
709 EXPECT_TRUE(result == nullptr);
710}
711
712TEST_F(ResolverTest, GetAddrInfo_cnamesIllegalRdata) {
713 test::DNSResponder dns;
714 const std::vector<DnsRecord> records = {
715 {kHelloExampleCom, ns_type::ns_t_cname, ".!#?"},
716 };
717 StartDns(dns, records);
718 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
719
720 addrinfo hints = {.ai_family = AF_INET};
721 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
722 EXPECT_TRUE(result == nullptr);
723
724 dns.clearQueries();
725 hints = {.ai_family = AF_INET6};
726 result = safe_getaddrinfo("hello", nullptr, &hints);
727 EXPECT_TRUE(result == nullptr);
728}
729
Ken Chenb9fa2062018-11-13 21:51:13 +0800730TEST_F(ResolverTest, MultidomainResolution) {
Xiao Ma09b71022018-12-11 17:56:32 +0900731 constexpr char host_name[] = "nihao.example2.com.";
Luke Huangf8215372019-11-22 11:53:41 +0800732 std::vector<std::string> searchDomains = {"example1.com", "example2.com", "example3.com"};
Ken Chenb9fa2062018-11-13 21:51:13 +0800733
Xiao Ma09b71022018-12-11 17:56:32 +0900734 test::DNSResponder dns("127.0.0.6");
735 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.3"}});
736 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({"127.0.0.6"}, searchDomains));
737
Ken Chenb9fa2062018-11-13 21:51:13 +0800738 const hostent* result = gethostbyname("nihao");
Xiao Ma09b71022018-12-11 17:56:32 +0900739
Ken Chenb9fa2062018-11-13 21:51:13 +0800740 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
741 ASSERT_FALSE(result == nullptr);
742 ASSERT_EQ(4, result->h_length);
743 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
744 EXPECT_EQ("1.2.3.3", ToString(result));
745 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800746}
747
748TEST_F(ResolverTest, GetAddrInfoV6_numeric) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800749 constexpr char host_name[] = "ohayou.example.com.";
750 constexpr char numeric_addr[] = "fe80::1%lo";
751
Xiao Ma09b71022018-12-11 17:56:32 +0900752 test::DNSResponder dns;
Ken Chenb9fa2062018-11-13 21:51:13 +0800753 dns.setResponseProbability(0.0);
Xiao Ma09b71022018-12-11 17:56:32 +0900754 StartDns(dns, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
755 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800756
757 addrinfo hints = {.ai_family = AF_INET6};
758 ScopedAddrinfo result = safe_getaddrinfo(numeric_addr, nullptr, &hints);
759 EXPECT_TRUE(result != nullptr);
760 EXPECT_EQ(numeric_addr, ToString(result));
761 EXPECT_TRUE(dns.queries().empty()); // Ensure no DNS queries were sent out
762
763 // Now try a non-numeric hostname query with the AI_NUMERICHOST flag set.
764 // We should fail without sending out a DNS query.
765 hints.ai_flags |= AI_NUMERICHOST;
766 result = safe_getaddrinfo(host_name, nullptr, &hints);
767 EXPECT_TRUE(result == nullptr);
768 EXPECT_TRUE(dns.queries().empty()); // Ensure no DNS queries were sent out
769}
770
771TEST_F(ResolverTest, GetAddrInfoV6_failing) {
Xiao Ma09b71022018-12-11 17:56:32 +0900772 constexpr char listen_addr0[] = "127.0.0.7";
773 constexpr char listen_addr1[] = "127.0.0.8";
Ken Chenb9fa2062018-11-13 21:51:13 +0800774 const char* host_name = "ohayou.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +0900775
776 test::DNSResponder dns0(listen_addr0);
777 test::DNSResponder dns1(listen_addr1);
Ken Chenb9fa2062018-11-13 21:51:13 +0800778 dns0.setResponseProbability(0.0);
Xiao Ma09b71022018-12-11 17:56:32 +0900779 StartDns(dns0, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
780 StartDns(dns1, {{host_name, ns_type::ns_t_aaaa, "2001:db8::6"}});
781
Luke Huangf8215372019-11-22 11:53:41 +0800782 std::vector<std::string> servers = {listen_addr0, listen_addr1};
Ken Chenb9fa2062018-11-13 21:51:13 +0800783 // <sample validity in s> <success threshold in percent> <min samples> <max samples>
784 int sample_count = 8;
Luke Huangf8215372019-11-22 11:53:41 +0800785 const std::vector<int> params = {300, 25, sample_count, sample_count};
Xiao Ma09b71022018-12-11 17:56:32 +0900786 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, kDefaultSearchDomains, params));
Ken Chenb9fa2062018-11-13 21:51:13 +0800787
788 // Repeatedly perform resolutions for non-existing domains until MAXNSSAMPLES resolutions have
789 // reached the dns0, which is set to fail. No more requests should then arrive at that server
790 // for the next sample_lifetime seconds.
791 // TODO: This approach is implementation-dependent, change once metrics reporting is available.
Xiao Ma09b71022018-12-11 17:56:32 +0900792 const addrinfo hints = {.ai_family = AF_INET6};
Bernie Innocentib102dd22018-12-04 14:57:48 +0900793 for (int i = 0; i < sample_count; ++i) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800794 std::string domain = StringPrintf("nonexistent%d", i);
795 ScopedAddrinfo result = safe_getaddrinfo(domain.c_str(), nullptr, &hints);
796 }
797 // Due to 100% errors for all possible samples, the server should be ignored from now on and
798 // only the second one used for all following queries, until NSSAMPLE_VALIDITY is reached.
799 dns0.clearQueries();
800 dns1.clearQueries();
801 ScopedAddrinfo result = safe_getaddrinfo("ohayou", nullptr, &hints);
802 EXPECT_TRUE(result != nullptr);
803 EXPECT_EQ(0U, GetNumQueries(dns0, host_name));
804 EXPECT_EQ(1U, GetNumQueries(dns1, host_name));
805}
806
807TEST_F(ResolverTest, GetAddrInfoV6_nonresponsive) {
Xiao Ma09b71022018-12-11 17:56:32 +0900808 constexpr char listen_addr0[] = "127.0.0.7";
809 constexpr char listen_addr1[] = "127.0.0.8";
810 constexpr char listen_srv[] = "53";
811 constexpr char host_name1[] = "ohayou.example.com.";
812 constexpr char host_name2[] = "ciao.example.com.";
Luke Huang483cf332019-06-03 17:24:51 +0800813 const std::vector<std::string> defaultSearchDomain = {"example.com"};
814 // The minimal timeout is 1000ms, so we can't decrease timeout
815 // So reduce retry count.
816 const std::vector<int> reduceRetryParams = {
817 300, // sample validity in seconds
818 25, // success threshod in percent
819 8, 8, // {MIN,MAX}_SAMPLES
820 1000, // BASE_TIMEOUT_MSEC
821 1, // retry count
822 };
Xiao Ma09b71022018-12-11 17:56:32 +0900823 const std::vector<DnsRecord> records0 = {
824 {host_name1, ns_type::ns_t_aaaa, "2001:db8::5"},
825 {host_name2, ns_type::ns_t_aaaa, "2001:db8::5"},
826 };
827 const std::vector<DnsRecord> records1 = {
828 {host_name1, ns_type::ns_t_aaaa, "2001:db8::6"},
829 {host_name2, ns_type::ns_t_aaaa, "2001:db8::6"},
830 };
Ken Chenb9fa2062018-11-13 21:51:13 +0800831
832 // dns0 does not respond with 100% probability, while
833 // dns1 responds normally, at least initially.
Mike Yufc125e42019-05-15 20:41:28 +0800834 test::DNSResponder dns0(listen_addr0, listen_srv, static_cast<ns_rcode>(-1));
835 test::DNSResponder dns1(listen_addr1, listen_srv, static_cast<ns_rcode>(-1));
Ken Chenb9fa2062018-11-13 21:51:13 +0800836 dns0.setResponseProbability(0.0);
Xiao Ma09b71022018-12-11 17:56:32 +0900837 StartDns(dns0, records0);
838 StartDns(dns1, records1);
Luke Huang483cf332019-06-03 17:24:51 +0800839 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr0, listen_addr1}, defaultSearchDomain,
840 reduceRetryParams));
Ken Chenb9fa2062018-11-13 21:51:13 +0800841
Luke Huang483cf332019-06-03 17:24:51 +0800842 // Specify ai_socktype to make getaddrinfo will only query 1 time
843 const addrinfo hints = {.ai_family = AF_INET6, .ai_socktype = SOCK_STREAM};
Ken Chenb9fa2062018-11-13 21:51:13 +0800844
845 // dns0 will ignore the request, and we'll fallback to dns1 after the first
846 // retry.
847 ScopedAddrinfo result = safe_getaddrinfo(host_name1, nullptr, &hints);
848 EXPECT_TRUE(result != nullptr);
849 EXPECT_EQ(1U, GetNumQueries(dns0, host_name1));
850 EXPECT_EQ(1U, GetNumQueries(dns1, host_name1));
851
852 // Now make dns1 also ignore 100% requests... The resolve should alternate
Luke Huang483cf332019-06-03 17:24:51 +0800853 // queries between the nameservers and fail
Ken Chenb9fa2062018-11-13 21:51:13 +0800854 dns1.setResponseProbability(0.0);
855 addrinfo* result2 = nullptr;
856 EXPECT_EQ(EAI_NODATA, getaddrinfo(host_name2, nullptr, &hints, &result2));
857 EXPECT_EQ(nullptr, result2);
Luke Huang483cf332019-06-03 17:24:51 +0800858 EXPECT_EQ(1U, GetNumQueries(dns0, host_name2));
859 EXPECT_EQ(1U, GetNumQueries(dns1, host_name2));
Ken Chenb9fa2062018-11-13 21:51:13 +0800860}
861
862TEST_F(ResolverTest, GetAddrInfoV6_concurrent) {
Xiao Ma09b71022018-12-11 17:56:32 +0900863 constexpr char listen_addr0[] = "127.0.0.9";
864 constexpr char listen_addr1[] = "127.0.0.10";
865 constexpr char listen_addr2[] = "127.0.0.11";
866 constexpr char host_name[] = "konbanha.example.com.";
867
868 test::DNSResponder dns0(listen_addr0);
869 test::DNSResponder dns1(listen_addr1);
870 test::DNSResponder dns2(listen_addr2);
871 StartDns(dns0, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
872 StartDns(dns1, {{host_name, ns_type::ns_t_aaaa, "2001:db8::6"}});
873 StartDns(dns2, {{host_name, ns_type::ns_t_aaaa, "2001:db8::7"}});
874
Luke Huangf8215372019-11-22 11:53:41 +0800875 const std::vector<std::string> servers = {listen_addr0, listen_addr1, listen_addr2};
Ken Chenb9fa2062018-11-13 21:51:13 +0800876 std::vector<std::thread> threads(10);
877 for (std::thread& thread : threads) {
Luke Huangf8215372019-11-22 11:53:41 +0800878 thread = std::thread([this, &servers]() {
879 unsigned delay = arc4random_uniform(1 * 1000 * 1000); // <= 1s
Ken Chenb9fa2062018-11-13 21:51:13 +0800880 usleep(delay);
881 std::vector<std::string> serverSubset;
882 for (const auto& server : servers) {
883 if (arc4random_uniform(2)) {
884 serverSubset.push_back(server);
885 }
886 }
887 if (serverSubset.empty()) serverSubset = servers;
Xiao Ma09b71022018-12-11 17:56:32 +0900888 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(serverSubset));
889 const addrinfo hints = {.ai_family = AF_INET6};
Ken Chenb9fa2062018-11-13 21:51:13 +0800890 addrinfo* result = nullptr;
891 int rv = getaddrinfo("konbanha", nullptr, &hints, &result);
892 EXPECT_EQ(0, rv) << "error [" << rv << "] " << gai_strerror(rv);
893 if (result) {
894 freeaddrinfo(result);
895 result = nullptr;
896 }
897 });
898 }
899 for (std::thread& thread : threads) {
900 thread.join();
901 }
Ken Chen92bed612018-12-22 21:46:55 +0800902
903 std::vector<std::string> res_servers;
904 std::vector<std::string> res_domains;
905 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900906 res_params res_params;
Ken Chen92bed612018-12-22 21:46:55 +0800907 std::vector<ResolverStats> res_stats;
908 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800909 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
910 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
911 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chen92bed612018-12-22 21:46:55 +0800912 EXPECT_EQ(0, wait_for_pending_req_timeout_count);
Ken Chenb9fa2062018-11-13 21:51:13 +0800913}
914
Mike Yu8ac63402019-12-02 15:28:38 +0800915TEST_F(ResolverTest, SkipBadServersDueToInternalError) {
916 constexpr char listen_addr1[] = "fe80::1";
917 constexpr char listen_addr2[] = "255.255.255.255";
918 constexpr char listen_addr3[] = "127.0.0.3";
919
920 test::DNSResponder dns(listen_addr3);
921 ASSERT_TRUE(dns.startServer());
922
923 ResolverParamsParcel parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
924 parcel.servers = {listen_addr1, listen_addr2, listen_addr3};
925
926 // Bad servers can be distinguished after two attempts.
927 parcel.minSamples = 2;
928 ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
929
930 // Start querying five times.
931 for (int i = 0; i < 5; i++) {
932 std::string hostName = StringPrintf("hello%d.com.", i);
933 dns.addMapping(hostName, ns_type::ns_t_a, "1.2.3.4");
934 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
935 EXPECT_TRUE(safe_getaddrinfo(hostName.c_str(), nullptr, &hints) != nullptr);
936 }
937
938 std::vector<std::string> res_servers;
939 std::vector<std::string> res_domains;
940 std::vector<std::string> res_tls_servers;
941 res_params res_params;
942 std::vector<ResolverStats> res_stats;
943 int wait_for_pending_req_timeout_count;
944 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
945 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
946 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
947
948 // Verify the result by means of the statistics.
949 EXPECT_EQ(res_stats[0].successes, 0);
950 EXPECT_EQ(res_stats[1].successes, 0);
951 EXPECT_EQ(res_stats[2].successes, 5);
952 EXPECT_EQ(res_stats[0].internal_errors, 2);
953 EXPECT_EQ(res_stats[1].internal_errors, 2);
954 EXPECT_EQ(res_stats[2].internal_errors, 0);
955}
956
957TEST_F(ResolverTest, SkipBadServersDueToTimeout) {
958 constexpr char listen_addr1[] = "127.0.0.3";
959 constexpr char listen_addr2[] = "127.0.0.4";
960
961 // Set dns1 non-responsive and dns2 workable.
962 test::DNSResponder dns1(listen_addr1, test::kDefaultListenService, static_cast<ns_rcode>(-1));
963 test::DNSResponder dns2(listen_addr2);
964 dns1.setResponseProbability(0.0);
965 ASSERT_TRUE(dns1.startServer());
966 ASSERT_TRUE(dns2.startServer());
967
968 ResolverParamsParcel parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
969 parcel.servers = {listen_addr1, listen_addr2};
970
971 // Bad servers can be distinguished after two attempts.
972 parcel.minSamples = 2;
973 ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
974
975 // Start querying five times.
976 for (int i = 0; i < 5; i++) {
977 std::string hostName = StringPrintf("hello%d.com.", i);
978 dns1.addMapping(hostName, ns_type::ns_t_a, "1.2.3.4");
979 dns2.addMapping(hostName, ns_type::ns_t_a, "1.2.3.5");
980 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
981 EXPECT_TRUE(safe_getaddrinfo(hostName.c_str(), nullptr, &hints) != nullptr);
982 }
983
984 std::vector<std::string> res_servers;
985 std::vector<std::string> res_domains;
986 std::vector<std::string> res_tls_servers;
987 res_params res_params;
988 std::vector<ResolverStats> res_stats;
989 int wait_for_pending_req_timeout_count;
990 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
991 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
992 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
993
994 // Verify the result by means of the statistics as well as the query counts.
995 EXPECT_EQ(res_stats[0].successes, 0);
996 EXPECT_EQ(res_stats[1].successes, 5);
997 EXPECT_EQ(res_stats[0].timeouts, 2);
998 EXPECT_EQ(res_stats[1].timeouts, 0);
999 EXPECT_EQ(dns1.queries().size(), 2U);
1000 EXPECT_EQ(dns2.queries().size(), 5U);
1001}
1002
Ken Chenb9fa2062018-11-13 21:51:13 +08001003TEST_F(ResolverTest, EmptySetup) {
Ken Chenb9fa2062018-11-13 21:51:13 +08001004 std::vector<std::string> servers;
1005 std::vector<std::string> domains;
Xiao Ma09b71022018-12-11 17:56:32 +09001006 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Ken Chenb9fa2062018-11-13 21:51:13 +08001007 std::vector<std::string> res_servers;
1008 std::vector<std::string> res_domains;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001009 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +09001010 res_params res_params;
Ken Chenb9fa2062018-11-13 21:51:13 +08001011 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +08001012 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +08001013 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
1014 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
1015 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chenb9fa2062018-11-13 21:51:13 +08001016 EXPECT_EQ(0U, res_servers.size());
1017 EXPECT_EQ(0U, res_domains.size());
Mike Yu0a1c53d2018-11-26 13:26:21 +09001018 EXPECT_EQ(0U, res_tls_servers.size());
Luke Huang5bd827c2019-03-14 16:10:04 +08001019 ASSERT_EQ(static_cast<size_t>(IDnsResolver::RESOLVER_PARAMS_COUNT), kDefaultParams.size());
1020 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY],
1021 res_params.sample_validity);
1022 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD],
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +09001023 res_params.success_threshold);
Luke Huang5bd827c2019-03-14 16:10:04 +08001024 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
1025 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
1026 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
Ken Chenb9fa2062018-11-13 21:51:13 +08001027 res_params.base_timeout_msec);
Luke Huang5bd827c2019-03-14 16:10:04 +08001028 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT], res_params.retry_count);
Ken Chenb9fa2062018-11-13 21:51:13 +08001029}
1030
1031TEST_F(ResolverTest, SearchPathChange) {
Xiao Ma09b71022018-12-11 17:56:32 +09001032 constexpr char listen_addr[] = "127.0.0.13";
1033 constexpr char host_name1[] = "test13.domain1.org.";
1034 constexpr char host_name2[] = "test13.domain2.org.";
Luke Huangf8215372019-11-22 11:53:41 +08001035 std::vector<std::string> servers = {listen_addr};
1036 std::vector<std::string> domains = {"domain1.org"};
Xiao Ma09b71022018-12-11 17:56:32 +09001037
1038 const std::vector<DnsRecord> records = {
1039 {host_name1, ns_type::ns_t_aaaa, "2001:db8::13"},
1040 {host_name2, ns_type::ns_t_aaaa, "2001:db8::1:13"},
1041 };
1042 test::DNSResponder dns(listen_addr);
1043 StartDns(dns, records);
1044 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Ken Chenb9fa2062018-11-13 21:51:13 +08001045
1046 const addrinfo hints = {.ai_family = AF_INET6};
1047 ScopedAddrinfo result = safe_getaddrinfo("test13", nullptr, &hints);
1048 EXPECT_TRUE(result != nullptr);
1049 EXPECT_EQ(1U, dns.queries().size());
1050 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
1051 EXPECT_EQ("2001:db8::13", ToString(result));
1052
1053 // Test that changing the domain search path on its own works.
Luke Huangf8215372019-11-22 11:53:41 +08001054 domains = {"domain2.org"};
Xiao Ma09b71022018-12-11 17:56:32 +09001055 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Ken Chenb9fa2062018-11-13 21:51:13 +08001056 dns.clearQueries();
1057
1058 result = safe_getaddrinfo("test13", nullptr, &hints);
1059 EXPECT_TRUE(result != nullptr);
1060 EXPECT_EQ(1U, dns.queries().size());
1061 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
1062 EXPECT_EQ("2001:db8::1:13", ToString(result));
1063}
1064
Luke Huang2dac4382019-06-24 13:28:44 +08001065namespace {
1066
Luke Huangf8215372019-11-22 11:53:41 +08001067std::vector<std::string> getResolverDomains(aidl::android::net::IDnsResolver* dnsResolverService,
Luke Huang2dac4382019-06-24 13:28:44 +08001068 unsigned netId) {
1069 std::vector<std::string> res_servers;
1070 std::vector<std::string> res_domains;
1071 std::vector<std::string> res_tls_servers;
1072 res_params res_params;
1073 std::vector<ResolverStats> res_stats;
1074 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +08001075 DnsResponderClient::GetResolverInfo(dnsResolverService, netId, &res_servers, &res_domains,
1076 &res_tls_servers, &res_params, &res_stats,
1077 &wait_for_pending_req_timeout_count);
Luke Huang2dac4382019-06-24 13:28:44 +08001078 return res_domains;
1079}
1080
1081} // namespace
1082
1083TEST_F(ResolverTest, SearchPathPrune) {
1084 constexpr size_t DUPLICATED_DOMAIN_NUM = 3;
1085 constexpr char listen_addr[] = "127.0.0.13";
1086 constexpr char domian_name1[] = "domain13.org.";
1087 constexpr char domian_name2[] = "domain14.org.";
1088 constexpr char host_name1[] = "test13.domain13.org.";
1089 constexpr char host_name2[] = "test14.domain14.org.";
1090 std::vector<std::string> servers = {listen_addr};
1091
1092 std::vector<std::string> testDomains1;
1093 std::vector<std::string> testDomains2;
1094 // Domain length should be <= 255
1095 // Max number of domains in search path is 6
1096 for (size_t i = 0; i < MAXDNSRCH + 1; i++) {
1097 // Fill up with invalid domain
1098 testDomains1.push_back(std::string(300, i + '0'));
1099 // Fill up with valid but duplicated domain
1100 testDomains2.push_back(StringPrintf("domain%zu.org", i % DUPLICATED_DOMAIN_NUM));
1101 }
1102
1103 // Add valid domain used for query.
1104 testDomains1.push_back(domian_name1);
1105
1106 // Add valid domain twice used for query.
1107 testDomains2.push_back(domian_name2);
1108 testDomains2.push_back(domian_name2);
1109
1110 const std::vector<DnsRecord> records = {
1111 {host_name1, ns_type::ns_t_aaaa, "2001:db8::13"},
1112 {host_name2, ns_type::ns_t_aaaa, "2001:db8::1:13"},
1113 };
1114 test::DNSResponder dns(listen_addr);
1115 StartDns(dns, records);
1116 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, testDomains1));
1117
1118 const addrinfo hints = {.ai_family = AF_INET6};
1119 ScopedAddrinfo result = safe_getaddrinfo("test13", nullptr, &hints);
1120
1121 EXPECT_TRUE(result != nullptr);
1122
1123 EXPECT_EQ(1U, dns.queries().size());
1124 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
1125 EXPECT_EQ("2001:db8::13", ToString(result));
1126
1127 const auto& res_domains1 = getResolverDomains(mDnsClient.resolvService(), TEST_NETID);
1128 // Expect 1 valid domain, invalid domains are removed.
1129 ASSERT_EQ(1U, res_domains1.size());
1130 EXPECT_EQ(domian_name1, res_domains1[0]);
1131
1132 dns.clearQueries();
1133
1134 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, testDomains2));
1135
1136 result = safe_getaddrinfo("test14", nullptr, &hints);
1137 EXPECT_TRUE(result != nullptr);
1138
1139 // (3 domains * 2 retries) + 1 success query = 7
1140 EXPECT_EQ(7U, dns.queries().size());
1141 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
1142 EXPECT_EQ("2001:db8::1:13", ToString(result));
1143
1144 const auto& res_domains2 = getResolverDomains(mDnsClient.resolvService(), TEST_NETID);
1145 // Expect 4 valid domain, duplicate domains are removed.
1146 EXPECT_EQ(DUPLICATED_DOMAIN_NUM + 1U, res_domains2.size());
1147 EXPECT_THAT(
1148 std::vector<std::string>({"domain0.org", "domain1.org", "domain2.org", domian_name2}),
1149 testing::ElementsAreArray(res_domains2));
1150}
1151
Mike Yu0a1c53d2018-11-26 13:26:21 +09001152// If we move this function to dns_responder_client, it will complicate the dependency need of
1153// dns_tls_frontend.h.
1154static void setupTlsServers(const std::vector<std::string>& servers,
waynema0e73c2e2019-07-31 15:04:08 +08001155 std::vector<std::unique_ptr<test::DnsTlsFrontend>>* tls) {
Xiao Ma09b71022018-12-11 17:56:32 +09001156 constexpr char listen_udp[] = "53";
1157 constexpr char listen_tls[] = "853";
Mike Yu0a1c53d2018-11-26 13:26:21 +09001158
1159 for (const auto& server : servers) {
1160 auto t = std::make_unique<test::DnsTlsFrontend>(server, listen_tls, server, listen_udp);
1161 t = std::make_unique<test::DnsTlsFrontend>(server, listen_tls, server, listen_udp);
1162 t->startServer();
Mike Yu0a1c53d2018-11-26 13:26:21 +09001163 tls->push_back(std::move(t));
1164 }
1165}
1166
Mike Yu0a1c53d2018-11-26 13:26:21 +09001167TEST_F(ResolverTest, MaxServerPrune_Binder) {
Mike Yu0a1c53d2018-11-26 13:26:21 +09001168 std::vector<std::string> domains;
1169 std::vector<std::unique_ptr<test::DNSResponder>> dns;
1170 std::vector<std::unique_ptr<test::DnsTlsFrontend>> tls;
1171 std::vector<std::string> servers;
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +09001172 std::vector<DnsResponderClient::Mapping> mappings;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001173
1174 for (unsigned i = 0; i < MAXDNSRCH + 1; i++) {
1175 domains.push_back(StringPrintf("example%u.com", i));
1176 }
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +09001177 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupMappings(1, domains, &mappings));
1178 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupDNSServers(MAXNS + 1, mappings, &dns, &servers));
waynema0e73c2e2019-07-31 15:04:08 +08001179 ASSERT_NO_FATAL_FAILURE(setupTlsServers(servers, &tls));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001180
waynema0e73c2e2019-07-31 15:04:08 +08001181 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, domains, kDefaultParams,
1182 kDefaultPrivateDnsHostName));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001183
Mike Yu383855b2019-01-15 17:53:27 +08001184 // If the private DNS validation hasn't completed yet before backend DNS servers stop,
1185 // TLS servers will get stuck in handleOneRequest(), which causes this test stuck in
1186 // ~DnsTlsFrontend() because the TLS server loop threads can't be terminated.
1187 // So, wait for private DNS validation done before stopping backend DNS servers.
1188 for (int i = 0; i < MAXNS; i++) {
chenbruceaff85842019-05-31 15:46:42 +08001189 LOG(INFO) << "Waiting for private DNS validation on " << tls[i]->listen_address() << ".";
Mike Yu724f77d2019-08-16 11:14:50 +08001190 EXPECT_TRUE(WaitForPrivateDnsValidation(tls[i]->listen_address(), true));
chenbruceaff85842019-05-31 15:46:42 +08001191 LOG(INFO) << "private DNS validation on " << tls[i]->listen_address() << " done.";
Mike Yu383855b2019-01-15 17:53:27 +08001192 }
1193
Mike Yu0a1c53d2018-11-26 13:26:21 +09001194 std::vector<std::string> res_servers;
1195 std::vector<std::string> res_domains;
1196 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +09001197 res_params res_params;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001198 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +08001199 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +08001200 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
1201 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
1202 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001203
1204 // Check the size of the stats and its contents.
1205 EXPECT_EQ(static_cast<size_t>(MAXNS), res_servers.size());
1206 EXPECT_EQ(static_cast<size_t>(MAXNS), res_tls_servers.size());
1207 EXPECT_EQ(static_cast<size_t>(MAXDNSRCH), res_domains.size());
1208 EXPECT_TRUE(std::equal(servers.begin(), servers.begin() + MAXNS, res_servers.begin()));
1209 EXPECT_TRUE(std::equal(servers.begin(), servers.begin() + MAXNS, res_tls_servers.begin()));
1210 EXPECT_TRUE(std::equal(domains.begin(), domains.begin() + MAXDNSRCH, res_domains.begin()));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001211}
1212
1213TEST_F(ResolverTest, ResolverStats) {
Xiao Ma09b71022018-12-11 17:56:32 +09001214 constexpr char listen_addr1[] = "127.0.0.4";
1215 constexpr char listen_addr2[] = "127.0.0.5";
1216 constexpr char listen_addr3[] = "127.0.0.6";
Mike Yu0a1c53d2018-11-26 13:26:21 +09001217
1218 // Set server 1 timeout.
Mike Yufc125e42019-05-15 20:41:28 +08001219 test::DNSResponder dns1(listen_addr1, "53", static_cast<ns_rcode>(-1));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001220 dns1.setResponseProbability(0.0);
1221 ASSERT_TRUE(dns1.startServer());
1222
1223 // Set server 2 responding server failure.
Xiao Ma09b71022018-12-11 17:56:32 +09001224 test::DNSResponder dns2(listen_addr2);
Mike Yu0a1c53d2018-11-26 13:26:21 +09001225 dns2.setResponseProbability(0.0);
1226 ASSERT_TRUE(dns2.startServer());
1227
1228 // Set server 3 workable.
Xiao Ma09b71022018-12-11 17:56:32 +09001229 test::DNSResponder dns3(listen_addr3);
1230 dns3.addMapping(kHelloExampleCom, ns_type::ns_t_a, "1.2.3.4");
Mike Yu0a1c53d2018-11-26 13:26:21 +09001231 ASSERT_TRUE(dns3.startServer());
1232
1233 std::vector<std::string> servers = {listen_addr1, listen_addr2, listen_addr3};
Xiao Ma09b71022018-12-11 17:56:32 +09001234 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001235
1236 dns3.clearQueries();
Xiao Ma09b71022018-12-11 17:56:32 +09001237 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
Mike Yu0a1c53d2018-11-26 13:26:21 +09001238 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
Xiao Ma09b71022018-12-11 17:56:32 +09001239 size_t found = GetNumQueries(dns3, kHelloExampleCom);
Mike Yu0a1c53d2018-11-26 13:26:21 +09001240 EXPECT_LE(1U, found);
1241 std::string result_str = ToString(result);
1242 EXPECT_TRUE(result_str == "1.2.3.4") << ", result_str='" << result_str << "'";
1243
1244 std::vector<std::string> res_servers;
1245 std::vector<std::string> res_domains;
1246 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +09001247 res_params res_params;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001248 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +08001249 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +08001250 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
1251 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
1252 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001253
1254 EXPECT_EQ(1, res_stats[0].timeouts);
1255 EXPECT_EQ(1, res_stats[1].errors);
1256 EXPECT_EQ(1, res_stats[2].successes);
Mike Yu0a1c53d2018-11-26 13:26:21 +09001257}
1258
Ken Chenb9fa2062018-11-13 21:51:13 +08001259// Test what happens if the specified TLS server is nonexistent.
1260TEST_F(ResolverTest, GetHostByName_TlsMissing) {
Xiao Ma09b71022018-12-11 17:56:32 +09001261 constexpr char listen_addr[] = "127.0.0.3";
1262 constexpr char host_name[] = "tlsmissing.example.com.";
1263
1264 test::DNSResponder dns;
1265 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.3"}});
Luke Huangf8215372019-11-22 11:53:41 +08001266 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001267
1268 // There's nothing listening on this address, so validation will either fail or
1269 /// hang. Either way, queries will continue to flow to the DNSResponder.
waynema0e73c2e2019-07-31 15:04:08 +08001270 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Ken Chenb9fa2062018-11-13 21:51:13 +08001271
1272 const hostent* result;
1273
1274 result = gethostbyname("tlsmissing");
1275 ASSERT_FALSE(result == nullptr);
1276 EXPECT_EQ("1.2.3.3", ToString(result));
1277
1278 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001279 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001280}
1281
1282// Test what happens if the specified TLS server replies with garbage.
1283TEST_F(ResolverTest, GetHostByName_TlsBroken) {
Xiao Ma09b71022018-12-11 17:56:32 +09001284 constexpr char listen_addr[] = "127.0.0.3";
1285 constexpr char host_name1[] = "tlsbroken1.example.com.";
1286 constexpr char host_name2[] = "tlsbroken2.example.com.";
1287 const std::vector<DnsRecord> records = {
1288 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1289 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1290 };
1291
1292 test::DNSResponder dns;
1293 StartDns(dns, records);
Luke Huangf8215372019-11-22 11:53:41 +08001294 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001295
1296 // Bind the specified private DNS socket but don't respond to any client sockets yet.
1297 int s = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
1298 ASSERT_TRUE(s >= 0);
1299 struct sockaddr_in tlsServer = {
Luke Huangf8215372019-11-22 11:53:41 +08001300 .sin_family = AF_INET,
1301 .sin_port = htons(853),
Ken Chenb9fa2062018-11-13 21:51:13 +08001302 };
1303 ASSERT_TRUE(inet_pton(AF_INET, listen_addr, &tlsServer.sin_addr));
1304 ASSERT_TRUE(enableSockopt(s, SOL_SOCKET, SO_REUSEPORT).ok());
1305 ASSERT_TRUE(enableSockopt(s, SOL_SOCKET, SO_REUSEADDR).ok());
1306 ASSERT_FALSE(bind(s, reinterpret_cast<struct sockaddr*>(&tlsServer), sizeof(tlsServer)));
1307 ASSERT_FALSE(listen(s, 1));
1308
1309 // Trigger TLS validation.
waynema0e73c2e2019-07-31 15:04:08 +08001310 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Ken Chenb9fa2062018-11-13 21:51:13 +08001311
1312 struct sockaddr_storage cliaddr;
1313 socklen_t sin_size = sizeof(cliaddr);
Luke Huangf8215372019-11-22 11:53:41 +08001314 int new_fd = accept4(s, reinterpret_cast<struct sockaddr*>(&cliaddr), &sin_size, SOCK_CLOEXEC);
Ken Chenb9fa2062018-11-13 21:51:13 +08001315 ASSERT_TRUE(new_fd > 0);
1316
1317 // We've received the new file descriptor but not written to it or closed, so the
1318 // validation is still pending. Queries should still flow correctly because the
1319 // server is not used until validation succeeds.
1320 const hostent* result;
1321 result = gethostbyname("tlsbroken1");
1322 ASSERT_FALSE(result == nullptr);
1323 EXPECT_EQ("1.2.3.1", ToString(result));
1324
1325 // Now we cause the validation to fail.
1326 std::string garbage = "definitely not a valid TLS ServerHello";
1327 write(new_fd, garbage.data(), garbage.size());
1328 close(new_fd);
1329
1330 // Validation failure shouldn't interfere with lookups, because lookups won't be sent
1331 // to the TLS server unless validation succeeds.
1332 result = gethostbyname("tlsbroken2");
1333 ASSERT_FALSE(result == nullptr);
1334 EXPECT_EQ("1.2.3.2", ToString(result));
1335
1336 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001337 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001338 close(s);
1339}
1340
1341TEST_F(ResolverTest, GetHostByName_Tls) {
Xiao Ma09b71022018-12-11 17:56:32 +09001342 constexpr char listen_addr[] = "127.0.0.3";
1343 constexpr char listen_udp[] = "53";
1344 constexpr char listen_tls[] = "853";
1345 constexpr char host_name1[] = "tls1.example.com.";
1346 constexpr char host_name2[] = "tls2.example.com.";
1347 constexpr char host_name3[] = "tls3.example.com.";
1348 const std::vector<DnsRecord> records = {
1349 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1350 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1351 {host_name3, ns_type::ns_t_a, "1.2.3.3"},
1352 };
1353
1354 test::DNSResponder dns;
1355 StartDns(dns, records);
Luke Huangf8215372019-11-22 11:53:41 +08001356 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001357
1358 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1359 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08001360 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08001361 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Ken Chenb9fa2062018-11-13 21:51:13 +08001362
Mike Yu724f77d2019-08-16 11:14:50 +08001363 const hostent* result = gethostbyname("tls1");
Ken Chenb9fa2062018-11-13 21:51:13 +08001364 ASSERT_FALSE(result == nullptr);
1365 EXPECT_EQ("1.2.3.1", ToString(result));
1366
1367 // Wait for query to get counted.
1368 EXPECT_TRUE(tls.waitForQueries(2, 5000));
1369
1370 // Stop the TLS server. Since we're in opportunistic mode, queries will
1371 // fall back to the locally-assigned (clear text) nameservers.
1372 tls.stopServer();
1373
1374 dns.clearQueries();
1375 result = gethostbyname("tls2");
1376 EXPECT_FALSE(result == nullptr);
1377 EXPECT_EQ("1.2.3.2", ToString(result));
1378 const auto queries = dns.queries();
1379 EXPECT_EQ(1U, queries.size());
1380 EXPECT_EQ("tls2.example.com.", queries[0].first);
1381 EXPECT_EQ(ns_t_a, queries[0].second);
1382
1383 // Reset the resolvers without enabling TLS. Queries should still be routed
1384 // to the UDP endpoint.
Xiao Ma09b71022018-12-11 17:56:32 +09001385 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001386
1387 result = gethostbyname("tls3");
1388 ASSERT_FALSE(result == nullptr);
1389 EXPECT_EQ("1.2.3.3", ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +08001390}
1391
Ken Chenb9fa2062018-11-13 21:51:13 +08001392TEST_F(ResolverTest, GetHostByName_TlsFailover) {
Xiao Ma09b71022018-12-11 17:56:32 +09001393 constexpr char listen_addr1[] = "127.0.0.3";
1394 constexpr char listen_addr2[] = "127.0.0.4";
1395 constexpr char listen_udp[] = "53";
1396 constexpr char listen_tls[] = "853";
1397 constexpr char host_name1[] = "tlsfailover1.example.com.";
1398 constexpr char host_name2[] = "tlsfailover2.example.com.";
1399 const std::vector<DnsRecord> records1 = {
1400 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1401 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1402 };
1403 const std::vector<DnsRecord> records2 = {
1404 {host_name1, ns_type::ns_t_a, "1.2.3.3"},
1405 {host_name2, ns_type::ns_t_a, "1.2.3.4"},
1406 };
1407
1408 test::DNSResponder dns1(listen_addr1);
1409 test::DNSResponder dns2(listen_addr2);
1410 StartDns(dns1, records1);
1411 StartDns(dns2, records2);
1412
Luke Huangf8215372019-11-22 11:53:41 +08001413 std::vector<std::string> servers = {listen_addr1, listen_addr2};
Ken Chenb9fa2062018-11-13 21:51:13 +08001414
1415 test::DnsTlsFrontend tls1(listen_addr1, listen_tls, listen_addr1, listen_udp);
1416 test::DnsTlsFrontend tls2(listen_addr2, listen_tls, listen_addr2, listen_udp);
1417 ASSERT_TRUE(tls1.startServer());
1418 ASSERT_TRUE(tls2.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08001419 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
1420 kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08001421 EXPECT_TRUE(WaitForPrivateDnsValidation(tls1.listen_address(), true));
1422 EXPECT_TRUE(WaitForPrivateDnsValidation(tls2.listen_address(), true));
Ken Chenb9fa2062018-11-13 21:51:13 +08001423
Mike Yu724f77d2019-08-16 11:14:50 +08001424 const hostent* result = gethostbyname("tlsfailover1");
Ken Chenb9fa2062018-11-13 21:51:13 +08001425 ASSERT_FALSE(result == nullptr);
1426 EXPECT_EQ("1.2.3.1", ToString(result));
1427
1428 // Wait for query to get counted.
1429 EXPECT_TRUE(tls1.waitForQueries(2, 5000));
1430 // No new queries should have reached tls2.
1431 EXPECT_EQ(1, tls2.queries());
1432
1433 // Stop tls1. Subsequent queries should attempt to reach tls1, fail, and retry to tls2.
1434 tls1.stopServer();
1435
1436 result = gethostbyname("tlsfailover2");
1437 EXPECT_EQ("1.2.3.4", ToString(result));
1438
1439 // Wait for query to get counted.
1440 EXPECT_TRUE(tls2.waitForQueries(2, 5000));
1441
1442 // No additional queries should have reached the insecure servers.
1443 EXPECT_EQ(2U, dns1.queries().size());
1444 EXPECT_EQ(2U, dns2.queries().size());
1445
1446 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001447 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Ken Chenb9fa2062018-11-13 21:51:13 +08001448}
1449
1450TEST_F(ResolverTest, GetHostByName_BadTlsName) {
Xiao Ma09b71022018-12-11 17:56:32 +09001451 constexpr char listen_addr[] = "127.0.0.3";
1452 constexpr char listen_udp[] = "53";
1453 constexpr char listen_tls[] = "853";
1454 constexpr char host_name[] = "badtlsname.example.com.";
1455
1456 test::DNSResponder dns;
1457 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.1"}});
Luke Huangf8215372019-11-22 11:53:41 +08001458 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001459
1460 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1461 ASSERT_TRUE(tls.startServer());
Xiao Ma09b71022018-12-11 17:56:32 +09001462 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
waynema0e73c2e2019-07-31 15:04:08 +08001463 kDefaultIncorrectPrivateDnsHostName));
Ken Chenb9fa2062018-11-13 21:51:13 +08001464
waynema0e73c2e2019-07-31 15:04:08 +08001465 // The TLS handshake would fail because the name of TLS server doesn't
1466 // match with TLS server's certificate.
Mike Yu724f77d2019-08-16 11:14:50 +08001467 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), false));
Ken Chenb9fa2062018-11-13 21:51:13 +08001468
1469 // The query should fail hard, because a name was specified.
1470 EXPECT_EQ(nullptr, gethostbyname("badtlsname"));
1471
1472 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001473 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001474}
1475
1476TEST_F(ResolverTest, GetAddrInfo_Tls) {
Xiao Ma09b71022018-12-11 17:56:32 +09001477 constexpr char listen_addr[] = "127.0.0.3";
1478 constexpr char listen_udp[] = "53";
1479 constexpr char listen_tls[] = "853";
1480 constexpr char host_name[] = "addrinfotls.example.com.";
1481 const std::vector<DnsRecord> records = {
1482 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1483 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1484 };
1485
1486 test::DNSResponder dns;
1487 StartDns(dns, records);
Luke Huangf8215372019-11-22 11:53:41 +08001488 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001489
1490 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1491 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08001492 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
1493 kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08001494 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Ken Chenb9fa2062018-11-13 21:51:13 +08001495
1496 dns.clearQueries();
1497 ScopedAddrinfo result = safe_getaddrinfo("addrinfotls", nullptr, nullptr);
1498 EXPECT_TRUE(result != nullptr);
1499 size_t found = GetNumQueries(dns, host_name);
1500 EXPECT_LE(1U, found);
1501 // Could be A or AAAA
1502 std::string result_str = ToString(result);
1503 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
Luke Huangf8215372019-11-22 11:53:41 +08001504 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +08001505 // Wait for both A and AAAA queries to get counted.
1506 EXPECT_TRUE(tls.waitForQueries(3, 5000));
1507
1508 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001509 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001510}
1511
1512TEST_F(ResolverTest, TlsBypass) {
1513 const char OFF[] = "off";
1514 const char OPPORTUNISTIC[] = "opportunistic";
1515 const char STRICT[] = "strict";
1516
1517 const char GETHOSTBYNAME[] = "gethostbyname";
1518 const char GETADDRINFO[] = "getaddrinfo";
1519 const char GETADDRINFOFORNET[] = "getaddrinfofornet";
1520
1521 const unsigned BYPASS_NETID = NETID_USE_LOCAL_NAMESERVERS | TEST_NETID;
1522
Ken Chenb9fa2062018-11-13 21:51:13 +08001523 const char ADDR4[] = "192.0.2.1";
1524 const char ADDR6[] = "2001:db8::1";
1525
1526 const char cleartext_addr[] = "127.0.0.53";
1527 const char cleartext_port[] = "53";
1528 const char tls_port[] = "853";
Luke Huangf8215372019-11-22 11:53:41 +08001529 const std::vector<std::string> servers = {cleartext_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001530
Xiao Ma09b71022018-12-11 17:56:32 +09001531 test::DNSResponder dns(cleartext_addr);
Ken Chenb9fa2062018-11-13 21:51:13 +08001532 ASSERT_TRUE(dns.startServer());
1533
1534 test::DnsTlsFrontend tls(cleartext_addr, tls_port, cleartext_addr, cleartext_port);
Mike Yudd4ac2d2019-05-31 16:52:11 +08001535 ASSERT_TRUE(tls.startServer());
Ken Chenb9fa2062018-11-13 21:51:13 +08001536
Luke Huangf8215372019-11-22 11:53:41 +08001537 // clang-format off
Ken Chenb9fa2062018-11-13 21:51:13 +08001538 struct TestConfig {
1539 const std::string mode;
1540 const bool withWorkingTLS;
1541 const std::string method;
1542
1543 std::string asHostName() const {
Luke Huangf8215372019-11-22 11:53:41 +08001544 return StringPrintf("%s.%s.%s.", mode.c_str(), withWorkingTLS ? "tlsOn" : "tlsOff",
Ken Chenb9fa2062018-11-13 21:51:13 +08001545 method.c_str());
1546 }
1547 } testConfigs[]{
Ken Chenb9fa2062018-11-13 21:51:13 +08001548 {OFF, true, GETHOSTBYNAME},
1549 {OPPORTUNISTIC, true, GETHOSTBYNAME},
1550 {STRICT, true, GETHOSTBYNAME},
Ken Chenb9fa2062018-11-13 21:51:13 +08001551 {OFF, true, GETADDRINFO},
1552 {OPPORTUNISTIC, true, GETADDRINFO},
1553 {STRICT, true, GETADDRINFO},
Ken Chenb9fa2062018-11-13 21:51:13 +08001554 {OFF, true, GETADDRINFOFORNET},
1555 {OPPORTUNISTIC, true, GETADDRINFOFORNET},
1556 {STRICT, true, GETADDRINFOFORNET},
Mike Yudd4ac2d2019-05-31 16:52:11 +08001557 {OFF, false, GETHOSTBYNAME},
1558 {OPPORTUNISTIC, false, GETHOSTBYNAME},
1559 {STRICT, false, GETHOSTBYNAME},
1560 {OFF, false, GETADDRINFO},
1561 {OPPORTUNISTIC, false, GETADDRINFO},
1562 {STRICT, false, GETADDRINFO},
1563 {OFF, false, GETADDRINFOFORNET},
1564 {OPPORTUNISTIC, false, GETADDRINFOFORNET},
1565 {STRICT, false, GETADDRINFOFORNET},
Ken Chenb9fa2062018-11-13 21:51:13 +08001566 };
Luke Huangf8215372019-11-22 11:53:41 +08001567 // clang-format on
Ken Chenb9fa2062018-11-13 21:51:13 +08001568
1569 for (const auto& config : testConfigs) {
1570 const std::string testHostName = config.asHostName();
1571 SCOPED_TRACE(testHostName);
1572
1573 // Don't tempt test bugs due to caching.
1574 const char* host_name = testHostName.c_str();
1575 dns.addMapping(host_name, ns_type::ns_t_a, ADDR4);
1576 dns.addMapping(host_name, ns_type::ns_t_aaaa, ADDR6);
1577
Mike Yudd4ac2d2019-05-31 16:52:11 +08001578 if (config.withWorkingTLS) {
1579 if (!tls.running()) {
1580 ASSERT_TRUE(tls.startServer());
1581 }
1582 } else {
1583 if (tls.running()) {
1584 ASSERT_TRUE(tls.stopServer());
1585 }
1586 }
Ken Chenb9fa2062018-11-13 21:51:13 +08001587
1588 if (config.mode == OFF) {
Xiao Ma09b71022018-12-11 17:56:32 +09001589 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, kDefaultSearchDomains,
1590 kDefaultParams));
Ken Chenb9fa2062018-11-13 21:51:13 +08001591 } else if (config.mode == OPPORTUNISTIC) {
Xiao Ma09b71022018-12-11 17:56:32 +09001592 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08001593 kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08001594
1595 // Wait for the validation event. If the server is running, the validation should
1596 // be successful; otherwise, the validation should be failed.
1597 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), config.withWorkingTLS));
Ken Chenb9fa2062018-11-13 21:51:13 +08001598 } else if (config.mode == STRICT) {
Xiao Ma09b71022018-12-11 17:56:32 +09001599 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08001600 kDefaultParams, kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08001601
1602 // Wait for the validation event.
1603 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), config.withWorkingTLS));
Ken Chenb9fa2062018-11-13 21:51:13 +08001604 }
Mike Yudd4ac2d2019-05-31 16:52:11 +08001605 tls.clearQueries();
Ken Chenb9fa2062018-11-13 21:51:13 +08001606
1607 const hostent* h_result = nullptr;
1608 ScopedAddrinfo ai_result;
1609
1610 if (config.method == GETHOSTBYNAME) {
1611 ASSERT_EQ(0, setNetworkForResolv(BYPASS_NETID));
1612 h_result = gethostbyname(host_name);
1613
1614 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
1615 ASSERT_FALSE(h_result == nullptr);
1616 ASSERT_EQ(4, h_result->h_length);
1617 ASSERT_FALSE(h_result->h_addr_list[0] == nullptr);
1618 EXPECT_EQ(ADDR4, ToString(h_result));
1619 EXPECT_TRUE(h_result->h_addr_list[1] == nullptr);
1620 } else if (config.method == GETADDRINFO) {
1621 ASSERT_EQ(0, setNetworkForResolv(BYPASS_NETID));
1622 ai_result = safe_getaddrinfo(host_name, nullptr, nullptr);
1623 EXPECT_TRUE(ai_result != nullptr);
1624
1625 EXPECT_LE(1U, GetNumQueries(dns, host_name));
1626 // Could be A or AAAA
1627 const std::string result_str = ToString(ai_result);
1628 EXPECT_TRUE(result_str == ADDR4 || result_str == ADDR6)
Luke Huangf8215372019-11-22 11:53:41 +08001629 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +08001630 } else if (config.method == GETADDRINFOFORNET) {
1631 addrinfo* raw_ai_result = nullptr;
1632 EXPECT_EQ(0, android_getaddrinfofornet(host_name, /*servname=*/nullptr,
1633 /*hints=*/nullptr, BYPASS_NETID, MARK_UNSET,
1634 &raw_ai_result));
1635 ai_result.reset(raw_ai_result);
1636
1637 EXPECT_LE(1U, GetNumQueries(dns, host_name));
1638 // Could be A or AAAA
1639 const std::string result_str = ToString(ai_result);
1640 EXPECT_TRUE(result_str == ADDR4 || result_str == ADDR6)
Luke Huangf8215372019-11-22 11:53:41 +08001641 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +08001642 }
1643
Mike Yudd4ac2d2019-05-31 16:52:11 +08001644 EXPECT_EQ(0, tls.queries());
Ken Chenb9fa2062018-11-13 21:51:13 +08001645
1646 // Clear per-process resolv netid.
1647 ASSERT_EQ(0, setNetworkForResolv(NETID_UNSET));
Ken Chenb9fa2062018-11-13 21:51:13 +08001648 dns.clearQueries();
1649 }
Ken Chenb9fa2062018-11-13 21:51:13 +08001650}
1651
1652TEST_F(ResolverTest, StrictMode_NoTlsServers) {
Xiao Ma09b71022018-12-11 17:56:32 +09001653 constexpr char cleartext_addr[] = "127.0.0.53";
Luke Huangf8215372019-11-22 11:53:41 +08001654 const std::vector<std::string> servers = {cleartext_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001655 constexpr char host_name[] = "strictmode.notlsips.example.com.";
1656 const std::vector<DnsRecord> records = {
1657 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1658 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1659 };
Ken Chenb9fa2062018-11-13 21:51:13 +08001660
Xiao Ma09b71022018-12-11 17:56:32 +09001661 test::DNSResponder dns(cleartext_addr);
1662 StartDns(dns, records);
Ken Chenb9fa2062018-11-13 21:51:13 +08001663
waynema0e73c2e2019-07-31 15:04:08 +08001664 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
1665 kDefaultIncorrectPrivateDnsHostName));
Ken Chenb9fa2062018-11-13 21:51:13 +08001666
1667 addrinfo* ai_result = nullptr;
1668 EXPECT_NE(0, getaddrinfo(host_name, nullptr, nullptr, &ai_result));
1669 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
1670}
Luke Huang94b10b92018-11-21 20:13:38 +08001671
1672namespace {
1673
Luke Huang70931aa2019-01-31 11:57:41 +08001674int getAsyncResponse(int fd, int* rcode, uint8_t* buf, int bufLen) {
Luke Huang94b10b92018-11-21 20:13:38 +08001675 struct pollfd wait_fd[1];
1676 wait_fd[0].fd = fd;
1677 wait_fd[0].events = POLLIN;
1678 short revents;
1679 int ret;
1680
1681 ret = poll(wait_fd, 1, -1);
1682 revents = wait_fd[0].revents;
1683 if (revents & POLLIN) {
1684 int n = resNetworkResult(fd, rcode, buf, bufLen);
Luke Huangba7bef92018-12-26 16:53:03 +08001685 // Verify that resNetworkResult() closed the fd
1686 char dummy;
1687 EXPECT_EQ(-1, read(fd, &dummy, sizeof dummy));
1688 EXPECT_EQ(EBADF, errno);
Luke Huang94b10b92018-11-21 20:13:38 +08001689 return n;
1690 }
1691 return -1;
1692}
1693
Luke Huang70931aa2019-01-31 11:57:41 +08001694std::string toString(uint8_t* buf, int bufLen, int ipType) {
Luke Huang94b10b92018-11-21 20:13:38 +08001695 ns_msg handle;
1696 int ancount, n = 0;
1697 ns_rr rr;
1698
Luke Huangf8215372019-11-22 11:53:41 +08001699 if (ns_initparse((const uint8_t*)buf, bufLen, &handle) >= 0) {
Luke Huang94b10b92018-11-21 20:13:38 +08001700 ancount = ns_msg_count(handle, ns_s_an);
1701 if (ns_parserr(&handle, ns_s_an, n, &rr) == 0) {
Luke Huang70931aa2019-01-31 11:57:41 +08001702 const uint8_t* rdata = ns_rr_rdata(rr);
Luke Huang94b10b92018-11-21 20:13:38 +08001703 char buffer[INET6_ADDRSTRLEN];
Luke Huangf8215372019-11-22 11:53:41 +08001704 if (inet_ntop(ipType, (const char*)rdata, buffer, sizeof(buffer))) {
Luke Huang94b10b92018-11-21 20:13:38 +08001705 return buffer;
1706 }
1707 }
1708 }
1709 return "";
1710}
1711
1712int dns_open_proxy() {
1713 int s = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
1714 if (s == -1) {
1715 return -1;
1716 }
1717 const int one = 1;
1718 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1719
1720 static const struct sockaddr_un proxy_addr = {
1721 .sun_family = AF_UNIX,
1722 .sun_path = "/dev/socket/dnsproxyd",
1723 };
1724
Luke Huangf8215372019-11-22 11:53:41 +08001725 if (TEMP_FAILURE_RETRY(connect(s, (const struct sockaddr*)&proxy_addr, sizeof(proxy_addr))) !=
Luke Huang94b10b92018-11-21 20:13:38 +08001726 0) {
1727 close(s);
1728 return -1;
1729 }
1730
1731 return s;
1732}
1733
Luke Huangba7bef92018-12-26 16:53:03 +08001734void expectAnswersValid(int fd, int ipType, const std::string& expectedAnswer) {
1735 int rcode = -1;
1736 uint8_t buf[MAXPACKET] = {};
1737
1738 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
1739 EXPECT_GT(res, 0);
1740 EXPECT_EQ(expectedAnswer, toString(buf, res, ipType));
1741}
1742
1743void expectAnswersNotValid(int fd, int expectedErrno) {
1744 int rcode = -1;
1745 uint8_t buf[MAXPACKET] = {};
1746
1747 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
1748 EXPECT_EQ(expectedErrno, res);
1749}
1750
Luke Huang94b10b92018-11-21 20:13:38 +08001751} // namespace
1752
1753TEST_F(ResolverTest, Async_NormalQueryV4V6) {
Xiao Ma09b71022018-12-11 17:56:32 +09001754 constexpr char listen_addr[] = "127.0.0.4";
1755 constexpr char host_name[] = "howdy.example.com.";
1756 const std::vector<DnsRecord> records = {
1757 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1758 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1759 };
1760
1761 test::DNSResponder dns(listen_addr);
1762 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001763 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001764 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001765
Luke Huangba7bef92018-12-26 16:53:03 +08001766 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
1767 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001768 EXPECT_TRUE(fd1 != -1);
1769 EXPECT_TRUE(fd2 != -1);
1770
Luke Huang70931aa2019-01-31 11:57:41 +08001771 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001772 int rcode;
1773 int res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
1774 EXPECT_GT(res, 0);
1775 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
1776
1777 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
1778 EXPECT_GT(res, 0);
1779 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
1780
1781 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
1782
1783 // Re-query verify cache works
Luke Huangba7bef92018-12-26 16:53:03 +08001784 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
1785 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001786
1787 EXPECT_TRUE(fd1 != -1);
1788 EXPECT_TRUE(fd2 != -1);
1789
1790 res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
1791 EXPECT_GT(res, 0);
1792 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
1793
1794 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
1795 EXPECT_GT(res, 0);
1796 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
1797
1798 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
1799}
1800
1801TEST_F(ResolverTest, Async_BadQuery) {
Xiao Ma09b71022018-12-11 17:56:32 +09001802 constexpr char listen_addr[] = "127.0.0.4";
1803 constexpr char host_name[] = "howdy.example.com.";
1804 const std::vector<DnsRecord> records = {
1805 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1806 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1807 };
1808
1809 test::DNSResponder dns(listen_addr);
1810 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001811 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001812 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001813
1814 static struct {
1815 int fd;
1816 const char* dname;
1817 const int queryType;
1818 const int expectRcode;
1819 } kTestData[] = {
Luke Huangba7bef92018-12-26 16:53:03 +08001820 {-1, "", ns_t_aaaa, 0},
1821 {-1, "as65ass46", ns_t_aaaa, 0},
1822 {-1, "454564564564", ns_t_aaaa, 0},
1823 {-1, "h645235", ns_t_a, 0},
1824 {-1, "www.google.com", ns_t_a, 0},
Luke Huang94b10b92018-11-21 20:13:38 +08001825 };
1826
1827 for (auto& td : kTestData) {
1828 SCOPED_TRACE(td.dname);
Luke Huangba7bef92018-12-26 16:53:03 +08001829 td.fd = resNetworkQuery(TEST_NETID, td.dname, ns_c_in, td.queryType, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001830 EXPECT_TRUE(td.fd != -1);
1831 }
1832
1833 // dns_responder return empty resp(packet only contains query part) with no error currently
1834 for (const auto& td : kTestData) {
Luke Huang70931aa2019-01-31 11:57:41 +08001835 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001836 int rcode;
1837 SCOPED_TRACE(td.dname);
1838 int res = getAsyncResponse(td.fd, &rcode, buf, MAXPACKET);
1839 EXPECT_GT(res, 0);
1840 EXPECT_EQ(rcode, td.expectRcode);
1841 }
1842}
1843
1844TEST_F(ResolverTest, Async_EmptyAnswer) {
Xiao Ma09b71022018-12-11 17:56:32 +09001845 constexpr char listen_addr[] = "127.0.0.4";
1846 constexpr char host_name[] = "howdy.example.com.";
1847 const std::vector<DnsRecord> records = {
1848 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1849 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1850 };
1851
1852 test::DNSResponder dns(listen_addr);
1853 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001854 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001855 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001856
Luke Huang9c264bb2018-12-18 16:44:41 +08001857 // TODO: Disable retry to make this test explicit.
1858 auto& cv = dns.getCv();
1859 auto& cvMutex = dns.getCvMutex();
1860 int fd1;
1861 // Wait on the condition variable to ensure that the DNS server has handled our first query.
1862 {
1863 std::unique_lock lk(cvMutex);
Luke Huangba7bef92018-12-26 16:53:03 +08001864 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huang9c264bb2018-12-18 16:44:41 +08001865 EXPECT_TRUE(fd1 != -1);
1866 EXPECT_EQ(std::cv_status::no_timeout, cv.wait_for(lk, std::chrono::seconds(1)));
1867 }
Luke Huang94b10b92018-11-21 20:13:38 +08001868
Luke Huang94b10b92018-11-21 20:13:38 +08001869 dns.setResponseProbability(0.0);
Luke Huang94b10b92018-11-21 20:13:38 +08001870
Luke Huangba7bef92018-12-26 16:53:03 +08001871 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001872 EXPECT_TRUE(fd2 != -1);
1873
Luke Huangba7bef92018-12-26 16:53:03 +08001874 int fd3 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001875 EXPECT_TRUE(fd3 != -1);
1876
Luke Huang9c264bb2018-12-18 16:44:41 +08001877 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001878 int rcode;
1879
Luke Huang9c264bb2018-12-18 16:44:41 +08001880 // expect no response
1881 int res = getAsyncResponse(fd3, &rcode, buf, MAXPACKET);
1882 EXPECT_EQ(-ETIMEDOUT, res);
Luke Huang94b10b92018-11-21 20:13:38 +08001883
Luke Huang9c264bb2018-12-18 16:44:41 +08001884 // expect no response
Luke Huang94b10b92018-11-21 20:13:38 +08001885 memset(buf, 0, MAXPACKET);
Luke Huang9c264bb2018-12-18 16:44:41 +08001886 res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
1887 EXPECT_EQ(-ETIMEDOUT, res);
Luke Huang94b10b92018-11-21 20:13:38 +08001888
Luke Huang94b10b92018-11-21 20:13:38 +08001889 dns.setResponseProbability(1.0);
Luke Huang94b10b92018-11-21 20:13:38 +08001890
Luke Huangba7bef92018-12-26 16:53:03 +08001891 int fd4 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001892 EXPECT_TRUE(fd4 != -1);
1893
1894 memset(buf, 0, MAXPACKET);
1895 res = getAsyncResponse(fd4, &rcode, buf, MAXPACKET);
1896 EXPECT_GT(res, 0);
1897 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
1898
1899 memset(buf, 0, MAXPACKET);
1900 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
1901 EXPECT_GT(res, 0);
1902 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
1903}
1904
1905TEST_F(ResolverTest, Async_MalformedQuery) {
Xiao Ma09b71022018-12-11 17:56:32 +09001906 constexpr char listen_addr[] = "127.0.0.4";
1907 constexpr char host_name[] = "howdy.example.com.";
1908 const std::vector<DnsRecord> records = {
1909 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1910 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1911 };
1912
1913 test::DNSResponder dns(listen_addr);
1914 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001915 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001916 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001917
1918 int fd = dns_open_proxy();
1919 EXPECT_TRUE(fd > 0);
1920
1921 const std::string badMsg = "16-52512#";
Xiao Ma09b71022018-12-11 17:56:32 +09001922 static const struct {
Luke Huang94b10b92018-11-21 20:13:38 +08001923 const std::string cmd;
1924 const int expectErr;
1925 } kTestData[] = {
Luke Huangba7bef92018-12-26 16:53:03 +08001926 // Too few arguments
Luke Huang94b10b92018-11-21 20:13:38 +08001927 {"resnsend " + badMsg + '\0', -EINVAL},
1928 // Bad netId
Luke Huangba7bef92018-12-26 16:53:03 +08001929 {"resnsend badnetId 0 " + badMsg + '\0', -EINVAL},
Luke Huang94b10b92018-11-21 20:13:38 +08001930 // Bad raw data
Luke Huangba7bef92018-12-26 16:53:03 +08001931 {"resnsend " + std::to_string(TEST_NETID) + " 0 " + badMsg + '\0', -EILSEQ},
Luke Huang94b10b92018-11-21 20:13:38 +08001932 };
1933
1934 for (unsigned int i = 0; i < std::size(kTestData); i++) {
1935 auto& td = kTestData[i];
1936 SCOPED_TRACE(td.cmd);
1937 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, td.cmd.c_str(), td.cmd.size()));
1938 EXPECT_EQ(rc, static_cast<ssize_t>(td.cmd.size()));
1939
1940 int32_t tmp;
1941 rc = TEMP_FAILURE_RETRY(read(fd, &tmp, sizeof(tmp)));
1942 EXPECT_TRUE(rc > 0);
1943 EXPECT_EQ(static_cast<int>(ntohl(tmp)), td.expectErr);
1944 }
1945 // Normal query with answer buffer
1946 // This is raw data of query "howdy.example.com" type 1 class 1
1947 std::string query = "81sBAAABAAAAAAAABWhvd2R5B2V4YW1wbGUDY29tAAABAAE=";
Luke Huangba7bef92018-12-26 16:53:03 +08001948 std::string cmd = "resnsend " + std::to_string(TEST_NETID) + " 0 " + query + '\0';
Luke Huang94b10b92018-11-21 20:13:38 +08001949 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size()));
1950 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size()));
1951
Luke Huang70931aa2019-01-31 11:57:41 +08001952 uint8_t smallBuf[1] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001953 int rcode;
1954 rc = getAsyncResponse(fd, &rcode, smallBuf, 1);
Luke Huangba7bef92018-12-26 16:53:03 +08001955 EXPECT_EQ(-EMSGSIZE, rc);
Luke Huang94b10b92018-11-21 20:13:38 +08001956
1957 // Do the normal test with large buffer again
1958 fd = dns_open_proxy();
1959 EXPECT_TRUE(fd > 0);
1960 rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size()));
1961 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size()));
Luke Huang70931aa2019-01-31 11:57:41 +08001962 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001963 rc = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
1964 EXPECT_EQ("1.2.3.4", toString(buf, rc, AF_INET));
Mike Yu4f3747b2018-12-02 17:54:29 +09001965}
1966
Luke Huangba7bef92018-12-26 16:53:03 +08001967TEST_F(ResolverTest, Async_CacheFlags) {
Xiao Ma09b71022018-12-11 17:56:32 +09001968 constexpr char listen_addr[] = "127.0.0.4";
1969 constexpr char host_name[] = "howdy.example.com.";
Luke Huang40f5f492019-05-09 19:37:35 +08001970 constexpr char another_host_name[] = "howdy.example2.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09001971 const std::vector<DnsRecord> records = {
1972 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1973 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
Luke Huang40f5f492019-05-09 19:37:35 +08001974 {another_host_name, ns_type::ns_t_a, "1.2.3.5"},
1975 {another_host_name, ns_type::ns_t_aaaa, "::1.2.3.5"},
Xiao Ma09b71022018-12-11 17:56:32 +09001976 };
1977
1978 test::DNSResponder dns(listen_addr);
1979 StartDns(dns, records);
Luke Huangba7bef92018-12-26 16:53:03 +08001980 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001981 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huangba7bef92018-12-26 16:53:03 +08001982
1983 // ANDROID_RESOLV_NO_CACHE_STORE
1984 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1985 ANDROID_RESOLV_NO_CACHE_STORE);
1986 EXPECT_TRUE(fd1 != -1);
1987 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1988 ANDROID_RESOLV_NO_CACHE_STORE);
1989 EXPECT_TRUE(fd2 != -1);
1990 int fd3 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1991 ANDROID_RESOLV_NO_CACHE_STORE);
1992 EXPECT_TRUE(fd3 != -1);
1993
1994 expectAnswersValid(fd3, AF_INET, "1.2.3.4");
1995 expectAnswersValid(fd2, AF_INET, "1.2.3.4");
1996 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
1997
1998 // No cache exists, expect 3 queries
1999 EXPECT_EQ(3U, GetNumQueries(dns, host_name));
2000
2001 // Re-query and cache
2002 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
2003
2004 EXPECT_TRUE(fd1 != -1);
2005
2006 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
2007
2008 // Now we have cache, expect 4 queries
2009 EXPECT_EQ(4U, GetNumQueries(dns, host_name));
2010
2011 // ANDROID_RESOLV_NO_CACHE_LOOKUP
2012 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2013 ANDROID_RESOLV_NO_CACHE_LOOKUP);
2014 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2015 ANDROID_RESOLV_NO_CACHE_LOOKUP);
2016
2017 EXPECT_TRUE(fd1 != -1);
2018 EXPECT_TRUE(fd2 != -1);
2019
2020 expectAnswersValid(fd2, AF_INET, "1.2.3.4");
2021 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
2022
2023 // Skip cache, expect 6 queries
2024 EXPECT_EQ(6U, GetNumQueries(dns, host_name));
2025
2026 // Re-query verify cache works
2027 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2028 ANDROID_RESOLV_NO_CACHE_STORE);
2029 EXPECT_TRUE(fd1 != -1);
2030 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
2031
2032 // Cache hits, expect still 6 queries
2033 EXPECT_EQ(6U, GetNumQueries(dns, host_name));
Luke Huanga1d74182019-03-19 17:30:36 +08002034
2035 // Start to verify if ANDROID_RESOLV_NO_CACHE_LOOKUP does write response into cache
2036 dns.clearQueries();
2037
2038 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
2039 ANDROID_RESOLV_NO_CACHE_LOOKUP);
2040 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
2041 ANDROID_RESOLV_NO_CACHE_LOOKUP);
2042
2043 EXPECT_TRUE(fd1 != -1);
2044 EXPECT_TRUE(fd2 != -1);
2045
2046 expectAnswersValid(fd2, AF_INET6, "::1.2.3.4");
2047 expectAnswersValid(fd1, AF_INET6, "::1.2.3.4");
2048
2049 // Skip cache, expect 2 queries
2050 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
2051
2052 // Re-query without flags
2053 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
2054 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
2055
2056 EXPECT_TRUE(fd1 != -1);
2057 EXPECT_TRUE(fd2 != -1);
2058
2059 expectAnswersValid(fd2, AF_INET6, "::1.2.3.4");
2060 expectAnswersValid(fd1, AF_INET6, "::1.2.3.4");
2061
2062 // Cache hits, expect still 2 queries
2063 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
Luke Huang40f5f492019-05-09 19:37:35 +08002064
2065 // Test both ANDROID_RESOLV_NO_CACHE_STORE and ANDROID_RESOLV_NO_CACHE_LOOKUP are set
2066 dns.clearQueries();
2067
2068 // Make sure that the cache of "howdy.example2.com" exists.
2069 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_aaaa, 0);
2070 EXPECT_TRUE(fd1 != -1);
2071 expectAnswersValid(fd1, AF_INET6, "::1.2.3.5");
2072 EXPECT_EQ(1U, GetNumQueries(dns, another_host_name));
2073
2074 // Re-query with testFlags
2075 const int testFlag = ANDROID_RESOLV_NO_CACHE_STORE | ANDROID_RESOLV_NO_CACHE_LOOKUP;
2076 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_aaaa, testFlag);
2077 EXPECT_TRUE(fd1 != -1);
2078 expectAnswersValid(fd1, AF_INET6, "::1.2.3.5");
2079 // Expect cache lookup is skipped.
2080 EXPECT_EQ(2U, GetNumQueries(dns, another_host_name));
2081
2082 // Do another query with testFlags
2083 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_a, testFlag);
2084 EXPECT_TRUE(fd1 != -1);
2085 expectAnswersValid(fd1, AF_INET, "1.2.3.5");
2086 // Expect cache lookup is skipped.
2087 EXPECT_EQ(3U, GetNumQueries(dns, another_host_name));
2088
2089 // Re-query with no flags
2090 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_a, 0);
2091 EXPECT_TRUE(fd1 != -1);
2092 expectAnswersValid(fd1, AF_INET, "1.2.3.5");
2093 // Expect no cache hit because cache storing is also skipped in previous query.
2094 EXPECT_EQ(4U, GetNumQueries(dns, another_host_name));
Luke Huangba7bef92018-12-26 16:53:03 +08002095}
2096
2097TEST_F(ResolverTest, Async_NoRetryFlag) {
Luke Huang70931aa2019-01-31 11:57:41 +08002098 constexpr char listen_addr0[] = "127.0.0.4";
2099 constexpr char listen_addr1[] = "127.0.0.6";
Xiao Ma09b71022018-12-11 17:56:32 +09002100 constexpr char host_name[] = "howdy.example.com.";
2101 const std::vector<DnsRecord> records = {
2102 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2103 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
2104 };
2105
Luke Huang70931aa2019-01-31 11:57:41 +08002106 test::DNSResponder dns0(listen_addr0);
2107 test::DNSResponder dns1(listen_addr1);
2108 StartDns(dns0, records);
2109 StartDns(dns1, records);
2110 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr0, listen_addr1}));
Luke Huangba7bef92018-12-26 16:53:03 +08002111
Luke Huang70931aa2019-01-31 11:57:41 +08002112 dns0.clearQueries();
2113 dns1.clearQueries();
2114
2115 dns0.setResponseProbability(0.0);
2116 dns1.setResponseProbability(0.0);
Luke Huangba7bef92018-12-26 16:53:03 +08002117
2118 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2119 ANDROID_RESOLV_NO_RETRY);
2120 EXPECT_TRUE(fd1 != -1);
2121
2122 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
2123 ANDROID_RESOLV_NO_RETRY);
2124 EXPECT_TRUE(fd2 != -1);
2125
2126 // expect no response
2127 expectAnswersNotValid(fd1, -ETIMEDOUT);
2128 expectAnswersNotValid(fd2, -ETIMEDOUT);
2129
Luke Huang70931aa2019-01-31 11:57:41 +08002130 // No retry case, expect total 2 queries. The server is selected randomly.
2131 EXPECT_EQ(2U, GetNumQueries(dns0, host_name) + GetNumQueries(dns1, host_name));
Luke Huangba7bef92018-12-26 16:53:03 +08002132
Luke Huang70931aa2019-01-31 11:57:41 +08002133 dns0.clearQueries();
2134 dns1.clearQueries();
Luke Huangba7bef92018-12-26 16:53:03 +08002135
2136 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
2137 EXPECT_TRUE(fd1 != -1);
2138
2139 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
2140 EXPECT_TRUE(fd2 != -1);
2141
2142 // expect no response
2143 expectAnswersNotValid(fd1, -ETIMEDOUT);
2144 expectAnswersNotValid(fd2, -ETIMEDOUT);
2145
2146 // Retry case, expect 4 queries
Luke Huang70931aa2019-01-31 11:57:41 +08002147 EXPECT_EQ(4U, GetNumQueries(dns0, host_name));
2148 EXPECT_EQ(4U, GetNumQueries(dns1, host_name));
2149}
2150
2151TEST_F(ResolverTest, Async_VerifyQueryID) {
2152 constexpr char listen_addr[] = "127.0.0.4";
2153 constexpr char host_name[] = "howdy.example.com.";
2154 const std::vector<DnsRecord> records = {
2155 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2156 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
2157 };
2158
2159 test::DNSResponder dns(listen_addr);
2160 StartDns(dns, records);
2161 std::vector<std::string> servers = {listen_addr};
2162 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
2163
2164 const uint8_t queryBuf1[] = {
2165 /* Header */
2166 0x55, 0x66, /* Transaction ID */
2167 0x01, 0x00, /* Flags */
2168 0x00, 0x01, /* Questions */
2169 0x00, 0x00, /* Answer RRs */
2170 0x00, 0x00, /* Authority RRs */
2171 0x00, 0x00, /* Additional RRs */
2172 /* Queries */
2173 0x05, 0x68, 0x6f, 0x77, 0x64, 0x79, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
2174 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
2175 0x00, 0x01, /* Type */
2176 0x00, 0x01 /* Class */
2177 };
2178
2179 int fd = resNetworkSend(TEST_NETID, queryBuf1, sizeof(queryBuf1), 0);
2180 EXPECT_TRUE(fd != -1);
2181
2182 uint8_t buf[MAXPACKET] = {};
2183 int rcode;
2184
2185 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
2186 EXPECT_GT(res, 0);
2187 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
2188
2189 auto hp = reinterpret_cast<HEADER*>(buf);
2190 EXPECT_EQ(21862U, htons(hp->id));
2191
2192 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
2193
2194 const uint8_t queryBuf2[] = {
2195 /* Header */
2196 0x00, 0x53, /* Transaction ID */
2197 0x01, 0x00, /* Flags */
2198 0x00, 0x01, /* Questions */
2199 0x00, 0x00, /* Answer RRs */
2200 0x00, 0x00, /* Authority RRs */
2201 0x00, 0x00, /* Additional RRs */
2202 /* Queries */
2203 0x05, 0x68, 0x6f, 0x77, 0x64, 0x79, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
2204 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
2205 0x00, 0x01, /* Type */
2206 0x00, 0x01 /* Class */
2207 };
2208
2209 // Re-query verify cache works and query id is correct
2210 fd = resNetworkSend(TEST_NETID, queryBuf2, sizeof(queryBuf2), 0);
2211
2212 EXPECT_TRUE(fd != -1);
2213
2214 res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
2215 EXPECT_GT(res, 0);
2216 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
2217
2218 EXPECT_EQ(0x0053U, htons(hp->id));
2219
2220 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
Luke Huangba7bef92018-12-26 16:53:03 +08002221}
2222
Mike Yu4f3747b2018-12-02 17:54:29 +09002223// This test checks that the resolver should not generate the request containing OPT RR when using
Ken Chen0a015532019-01-02 14:59:38 +08002224// cleartext DNS. If we query the DNS server not supporting EDNS0 and it reponds with
2225// FORMERR_ON_EDNS, we will fallback to no EDNS0 and try again. If the server does no response, we
2226// won't retry so that we get no answer.
Mike Yu4f3747b2018-12-02 17:54:29 +09002227TEST_F(ResolverTest, BrokenEdns) {
2228 typedef test::DNSResponder::Edns Edns;
2229 enum ExpectResult { EXPECT_FAILURE, EXPECT_SUCCESS };
2230
2231 const char OFF[] = "off";
2232 const char OPPORTUNISTIC_UDP[] = "opportunistic_udp";
2233 const char OPPORTUNISTIC_TLS[] = "opportunistic_tls";
2234 const char STRICT[] = "strict";
2235 const char GETHOSTBYNAME[] = "gethostbyname";
2236 const char GETADDRINFO[] = "getaddrinfo";
Mike Yu4f3747b2018-12-02 17:54:29 +09002237 const char ADDR4[] = "192.0.2.1";
2238 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2239 const char CLEARTEXT_PORT[] = "53";
2240 const char TLS_PORT[] = "853";
Luke Huangf8215372019-11-22 11:53:41 +08002241 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
Mike Yu4f3747b2018-12-02 17:54:29 +09002242
Mike Yufc125e42019-05-15 20:41:28 +08002243 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, ns_rcode::ns_r_servfail);
Mike Yu4f3747b2018-12-02 17:54:29 +09002244 ASSERT_TRUE(dns.startServer());
2245
2246 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2247
Luke Huangf8215372019-11-22 11:53:41 +08002248 // clang-format off
Mike Yu4f3747b2018-12-02 17:54:29 +09002249 static const struct TestConfig {
2250 std::string mode;
2251 std::string method;
2252 Edns edns;
2253 ExpectResult expectResult;
2254
2255 std::string asHostName() const {
2256 const char* ednsString;
2257 switch (edns) {
2258 case Edns::ON:
2259 ednsString = "ednsOn";
2260 break;
Ken Chen0a015532019-01-02 14:59:38 +08002261 case Edns::FORMERR_ON_EDNS:
Mike Yu4f3747b2018-12-02 17:54:29 +09002262 ednsString = "ednsFormerr";
2263 break;
2264 case Edns::DROP:
2265 ednsString = "ednsDrop";
2266 break;
2267 default:
2268 ednsString = "";
2269 break;
2270 }
2271 return StringPrintf("%s.%s.%s.", mode.c_str(), method.c_str(), ednsString);
2272 }
2273 } testConfigs[] = {
2274 // In OPPORTUNISTIC_TLS, we get no answer if the DNS server supports TLS but not EDNS0.
2275 // Could such server exist? if so, we might need to fallback to query cleartext DNS.
2276 // Another thing is that {OPPORTUNISTIC_TLS, Edns::DROP} and {STRICT, Edns::DROP} are
2277 // commented out since TLS timeout is not configurable.
2278 // TODO: Uncomment them after TLS timeout is configurable.
2279 {OFF, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2280 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2281 {OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2282 {STRICT, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
Ken Chen0a015532019-01-02 14:59:38 +08002283 {OFF, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2284 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2285 {OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
2286 {STRICT, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
Mike Yu4f3747b2018-12-02 17:54:29 +09002287 {OFF, GETHOSTBYNAME, Edns::DROP, EXPECT_SUCCESS},
2288 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::DROP, EXPECT_SUCCESS},
2289 //{OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::DROP, EXPECT_FAILURE},
2290 //{STRICT, GETHOSTBYNAME, Edns::DROP, EXPECT_FAILURE},
2291 {OFF, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2292 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2293 {OPPORTUNISTIC_TLS, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2294 {STRICT, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
Ken Chen0a015532019-01-02 14:59:38 +08002295 {OFF, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2296 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2297 {OPPORTUNISTIC_TLS, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
2298 {STRICT, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
Mike Yu4f3747b2018-12-02 17:54:29 +09002299 {OFF, GETADDRINFO, Edns::DROP, EXPECT_SUCCESS},
2300 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::DROP, EXPECT_SUCCESS},
2301 //{OPPORTUNISTIC_TLS, GETADDRINFO, Edns::DROP, EXPECT_FAILURE},
2302 //{STRICT, GETADDRINFO, Edns::DROP, EXPECT_FAILURE},
2303 };
Luke Huangf8215372019-11-22 11:53:41 +08002304 // clang-format on
Mike Yu4f3747b2018-12-02 17:54:29 +09002305
2306 for (const auto& config : testConfigs) {
2307 const std::string testHostName = config.asHostName();
2308 SCOPED_TRACE(testHostName);
2309
2310 const char* host_name = testHostName.c_str();
2311 dns.addMapping(host_name, ns_type::ns_t_a, ADDR4);
2312 dns.setEdns(config.edns);
2313
2314 if (config.mode == OFF) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002315 if (tls.running()) {
2316 ASSERT_TRUE(tls.stopServer());
2317 }
Xiao Ma09b71022018-12-11 17:56:32 +09002318 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Mike Yu4f3747b2018-12-02 17:54:29 +09002319 } else if (config.mode == OPPORTUNISTIC_UDP) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002320 if (tls.running()) {
2321 ASSERT_TRUE(tls.stopServer());
2322 }
Xiao Ma09b71022018-12-11 17:56:32 +09002323 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08002324 kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002325 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), false));
Mike Yu4f3747b2018-12-02 17:54:29 +09002326 } else if (config.mode == OPPORTUNISTIC_TLS) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002327 if (!tls.running()) {
2328 ASSERT_TRUE(tls.startServer());
2329 }
Xiao Ma09b71022018-12-11 17:56:32 +09002330 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08002331 kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002332 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yu4f3747b2018-12-02 17:54:29 +09002333 } else if (config.mode == STRICT) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002334 if (!tls.running()) {
2335 ASSERT_TRUE(tls.startServer());
2336 }
Xiao Ma09b71022018-12-11 17:56:32 +09002337 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08002338 kDefaultParams, kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08002339 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yu4f3747b2018-12-02 17:54:29 +09002340 }
2341
2342 if (config.method == GETHOSTBYNAME) {
2343 const hostent* h_result = gethostbyname(host_name);
2344 if (config.expectResult == EXPECT_SUCCESS) {
2345 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2346 ASSERT_TRUE(h_result != nullptr);
2347 ASSERT_EQ(4, h_result->h_length);
2348 ASSERT_FALSE(h_result->h_addr_list[0] == nullptr);
2349 EXPECT_EQ(ADDR4, ToString(h_result));
2350 EXPECT_TRUE(h_result->h_addr_list[1] == nullptr);
2351 } else {
2352 EXPECT_EQ(0U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
2353 ASSERT_TRUE(h_result == nullptr);
2354 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2355 }
2356 } else if (config.method == GETADDRINFO) {
2357 ScopedAddrinfo ai_result;
2358 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2359 ai_result = safe_getaddrinfo(host_name, nullptr, &hints);
2360 if (config.expectResult == EXPECT_SUCCESS) {
2361 EXPECT_TRUE(ai_result != nullptr);
2362 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
2363 const std::string result_str = ToString(ai_result);
2364 EXPECT_EQ(ADDR4, result_str);
2365 } else {
2366 EXPECT_TRUE(ai_result == nullptr);
2367 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
2368 }
2369 } else {
2370 FAIL() << "Unsupported query method: " << config.method;
2371 }
2372
Mike Yudd4ac2d2019-05-31 16:52:11 +08002373 tls.clearQueries();
Mike Yu4f3747b2018-12-02 17:54:29 +09002374 dns.clearQueries();
2375 }
Mike Yu4f3747b2018-12-02 17:54:29 +09002376}
nuccachena26cc2a2018-07-17 18:07:23 +08002377
Ken Chen0a015532019-01-02 14:59:38 +08002378// DNS-over-TLS validation success, but server does not respond to TLS query after a while.
2379// Resolver should have a reasonable number of retries instead of spinning forever. We don't have
2380// an efficient way to know if resolver is stuck in an infinite loop. However, test case will be
2381// failed due to timeout.
2382TEST_F(ResolverTest, UnstableTls) {
2383 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2384 const char CLEARTEXT_PORT[] = "53";
2385 const char TLS_PORT[] = "853";
2386 const char* host_name1 = "nonexistent1.example.com.";
2387 const char* host_name2 = "nonexistent2.example.com.";
2388 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
2389
Mike Yufc125e42019-05-15 20:41:28 +08002390 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, ns_rcode::ns_r_servfail);
Ken Chen0a015532019-01-02 14:59:38 +08002391 ASSERT_TRUE(dns.startServer());
2392 dns.setEdns(test::DNSResponder::Edns::FORMERR_ON_EDNS);
2393 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2394 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08002395 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002396 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
2397
Ken Chen0a015532019-01-02 14:59:38 +08002398 // Shutdown TLS server to get an error. It's similar to no response case but without waiting.
2399 tls.stopServer();
2400
2401 const hostent* h_result = gethostbyname(host_name1);
2402 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
2403 ASSERT_TRUE(h_result == nullptr);
2404 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2405
2406 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2407 ScopedAddrinfo ai_result = safe_getaddrinfo(host_name2, nullptr, &hints);
2408 EXPECT_TRUE(ai_result == nullptr);
2409 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
2410}
2411
2412// DNS-over-TLS validation success, but server does not respond to TLS query after a while.
2413// Moreover, server responds RCODE=FORMERR even on non-EDNS query.
2414TEST_F(ResolverTest, BogusDnsServer) {
2415 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2416 const char CLEARTEXT_PORT[] = "53";
2417 const char TLS_PORT[] = "853";
2418 const char* host_name1 = "nonexistent1.example.com.";
2419 const char* host_name2 = "nonexistent2.example.com.";
2420 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
2421
Mike Yufc125e42019-05-15 20:41:28 +08002422 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, ns_rcode::ns_r_servfail);
Ken Chen0a015532019-01-02 14:59:38 +08002423 ASSERT_TRUE(dns.startServer());
2424 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2425 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08002426 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002427 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
2428
Ken Chen0a015532019-01-02 14:59:38 +08002429 // Shutdown TLS server to get an error. It's similar to no response case but without waiting.
2430 tls.stopServer();
2431 dns.setEdns(test::DNSResponder::Edns::FORMERR_UNCOND);
2432
2433 const hostent* h_result = gethostbyname(host_name1);
2434 EXPECT_EQ(0U, GetNumQueries(dns, host_name1));
2435 ASSERT_TRUE(h_result == nullptr);
2436 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2437
2438 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2439 ScopedAddrinfo ai_result = safe_getaddrinfo(host_name2, nullptr, &hints);
2440 EXPECT_TRUE(ai_result == nullptr);
2441 EXPECT_EQ(0U, GetNumQueries(dns, host_name2));
2442}
2443
nuccachena26cc2a2018-07-17 18:07:23 +08002444TEST_F(ResolverTest, GetAddrInfo_Dns64Synthesize) {
2445 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002446 constexpr char dns64_name[] = "ipv4only.arpa.";
2447 constexpr char host_name[] = "v4only.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002448 const std::vector<DnsRecord> records = {
2449 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2450 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2451 };
nuccachena26cc2a2018-07-17 18:07:23 +08002452
Xiao Ma09b71022018-12-11 17:56:32 +09002453 test::DNSResponder dns(listen_addr);
Xiao Ma09b71022018-12-11 17:56:32 +09002454 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002455
2456 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002457 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002458
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002459 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002460 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002461 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002462
2463 // hints are necessary in order to let netd know which type of addresses the caller is
2464 // interested in.
Xiao Ma09b71022018-12-11 17:56:32 +09002465 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachena26cc2a2018-07-17 18:07:23 +08002466 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, &hints);
2467 EXPECT_TRUE(result != nullptr);
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002468 // TODO: BUG: there should only be two queries, one AAAA (which returns no records) and one A
2469 // (which returns 1.2.3.4). But there is an extra AAAA.
2470 EXPECT_EQ(3U, GetNumQueries(dns, host_name));
nuccachena26cc2a2018-07-17 18:07:23 +08002471
2472 std::string result_str = ToString(result);
2473 EXPECT_EQ(result_str, "64:ff9b::102:304");
2474
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002475 // Stopping NAT64 prefix discovery disables synthesis.
Luke Huang5bd827c2019-03-14 16:10:04 +08002476 EXPECT_TRUE(mDnsClient.resolvService()->stopPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002477 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_NOT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002478
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002479 dns.clearQueries();
nuccachena26cc2a2018-07-17 18:07:23 +08002480
2481 result = safe_getaddrinfo("v4only", nullptr, &hints);
2482 EXPECT_TRUE(result != nullptr);
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002483 // TODO: BUG: there should only be one query, an AAAA (which returns no records), because the
2484 // A is already cached. But there is an extra AAAA.
2485 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
nuccachena26cc2a2018-07-17 18:07:23 +08002486
2487 result_str = ToString(result);
2488 EXPECT_EQ(result_str, "1.2.3.4");
2489}
2490
nuccachena26cc2a2018-07-17 18:07:23 +08002491TEST_F(ResolverTest, GetAddrInfo_Dns64QuerySpecified) {
2492 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002493 constexpr char dns64_name[] = "ipv4only.arpa.";
2494 constexpr char host_name[] = "v4only.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002495 const std::vector<DnsRecord> records = {
2496 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2497 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2498 };
nuccachena26cc2a2018-07-17 18:07:23 +08002499
Xiao Ma09b71022018-12-11 17:56:32 +09002500 test::DNSResponder dns(listen_addr);
2501 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002502 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002503 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002504
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002505 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002506 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002507 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002508
2509 // Ensure to synthesize AAAA if AF_INET6 is specified, and not to synthesize AAAA
2510 // in AF_INET case.
2511 addrinfo hints;
2512 memset(&hints, 0, sizeof(hints));
2513 hints.ai_family = AF_INET6;
2514 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, &hints);
2515 EXPECT_TRUE(result != nullptr);
2516 std::string result_str = ToString(result);
2517 EXPECT_EQ(result_str, "64:ff9b::102:304");
2518
2519 hints.ai_family = AF_INET;
2520 result = safe_getaddrinfo("v4only", nullptr, &hints);
2521 EXPECT_TRUE(result != nullptr);
2522 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2523 result_str = ToString(result);
2524 EXPECT_EQ(result_str, "1.2.3.4");
2525}
nuccachena26cc2a2018-07-17 18:07:23 +08002526
2527TEST_F(ResolverTest, GetAddrInfo_Dns64QueryUnspecifiedV6) {
2528 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002529 constexpr char dns64_name[] = "ipv4only.arpa.";
2530 constexpr char host_name[] = "v4v6.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002531 const std::vector<DnsRecord> records = {
2532 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2533 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2534 {host_name, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
2535 };
nuccachena26cc2a2018-07-17 18:07:23 +08002536
Xiao Ma09b71022018-12-11 17:56:32 +09002537 test::DNSResponder dns(listen_addr);
2538 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002539 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002540 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002541
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002542 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002543 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002544 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002545
Xiao Ma09b71022018-12-11 17:56:32 +09002546 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachena26cc2a2018-07-17 18:07:23 +08002547 ScopedAddrinfo result = safe_getaddrinfo("v4v6", nullptr, &hints);
2548 EXPECT_TRUE(result != nullptr);
2549 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2550
2551 // In AF_UNSPEC case, do not synthesize AAAA if there's at least one AAAA answer.
Xiao Ma09b71022018-12-11 17:56:32 +09002552 const std::vector<std::string> result_strs = ToStrings(result);
nuccachena26cc2a2018-07-17 18:07:23 +08002553 for (const auto& str : result_strs) {
2554 EXPECT_TRUE(str == "1.2.3.4" || str == "2001:db8::102:304")
2555 << ", result_str='" << str << "'";
2556 }
2557}
2558
2559TEST_F(ResolverTest, GetAddrInfo_Dns64QueryUnspecifiedNoV6) {
2560 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002561 constexpr char dns64_name[] = "ipv4only.arpa.";
2562 constexpr char host_name[] = "v4v6.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002563 const std::vector<DnsRecord> records = {
2564 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2565 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2566 };
nuccachena26cc2a2018-07-17 18:07:23 +08002567
Xiao Ma09b71022018-12-11 17:56:32 +09002568 test::DNSResponder dns(listen_addr);
2569 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002570 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002571 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002572
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002573 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002574 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002575 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002576
Xiao Ma09b71022018-12-11 17:56:32 +09002577 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachena26cc2a2018-07-17 18:07:23 +08002578 ScopedAddrinfo result = safe_getaddrinfo("v4v6", nullptr, &hints);
2579 EXPECT_TRUE(result != nullptr);
2580 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2581
2582 // In AF_UNSPEC case, synthesize AAAA if there's no AAAA answer.
2583 std::string result_str = ToString(result);
2584 EXPECT_EQ(result_str, "64:ff9b::102:304");
2585}
2586
2587TEST_F(ResolverTest, GetAddrInfo_Dns64QuerySpecialUseIPv4Addresses) {
2588 constexpr char THIS_NETWORK[] = "this_network";
2589 constexpr char LOOPBACK[] = "loopback";
2590 constexpr char LINK_LOCAL[] = "link_local";
2591 constexpr char MULTICAST[] = "multicast";
2592 constexpr char LIMITED_BROADCAST[] = "limited_broadcast";
2593
2594 constexpr char ADDR_THIS_NETWORK[] = "0.0.0.1";
2595 constexpr char ADDR_LOOPBACK[] = "127.0.0.1";
2596 constexpr char ADDR_LINK_LOCAL[] = "169.254.0.1";
2597 constexpr char ADDR_MULTICAST[] = "224.0.0.1";
2598 constexpr char ADDR_LIMITED_BROADCAST[] = "255.255.255.255";
2599
2600 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002601 constexpr char dns64_name[] = "ipv4only.arpa.";
2602
Xiao Ma09b71022018-12-11 17:56:32 +09002603 test::DNSResponder dns(listen_addr);
2604 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachena26cc2a2018-07-17 18:07:23 +08002605 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002606 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002607
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002608 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002609 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002610 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002611
Luke Huangf8215372019-11-22 11:53:41 +08002612 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08002613 static const struct TestConfig {
2614 std::string name;
2615 std::string addr;
2616
2617 std::string asHostName() const { return StringPrintf("%s.example.com.", name.c_str()); }
2618 } testConfigs[]{
2619 {THIS_NETWORK, ADDR_THIS_NETWORK},
2620 {LOOPBACK, ADDR_LOOPBACK},
2621 {LINK_LOCAL, ADDR_LINK_LOCAL},
2622 {MULTICAST, ADDR_MULTICAST},
2623 {LIMITED_BROADCAST, ADDR_LIMITED_BROADCAST}
2624 };
Luke Huangf8215372019-11-22 11:53:41 +08002625 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08002626
2627 for (const auto& config : testConfigs) {
2628 const std::string testHostName = config.asHostName();
2629 SCOPED_TRACE(testHostName);
2630
2631 const char* host_name = testHostName.c_str();
2632 dns.addMapping(host_name, ns_type::ns_t_a, config.addr.c_str());
2633
2634 addrinfo hints;
2635 memset(&hints, 0, sizeof(hints));
2636 hints.ai_family = AF_INET6;
2637 ScopedAddrinfo result = safe_getaddrinfo(config.name.c_str(), nullptr, &hints);
2638 // In AF_INET6 case, don't return IPv4 answers
2639 EXPECT_TRUE(result == nullptr);
2640 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2641 dns.clearQueries();
2642
2643 memset(&hints, 0, sizeof(hints));
2644 hints.ai_family = AF_UNSPEC;
2645 result = safe_getaddrinfo(config.name.c_str(), nullptr, &hints);
2646 EXPECT_TRUE(result != nullptr);
2647 // Expect IPv6 query only. IPv4 answer has been cached in previous query.
2648 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2649 // In AF_UNSPEC case, don't synthesize special use IPv4 address.
2650 std::string result_str = ToString(result);
2651 EXPECT_EQ(result_str, config.addr.c_str());
2652 dns.clearQueries();
2653 }
2654}
2655
2656TEST_F(ResolverTest, GetAddrInfo_Dns64QueryWithNullArgumentHints) {
2657 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002658 constexpr char dns64_name[] = "ipv4only.arpa.";
2659 constexpr char host_name[] = "v4only.example.com.";
2660 constexpr char host_name2[] = "v4v6.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002661 const std::vector<DnsRecord> records = {
2662 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2663 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2664 {host_name2, ns_type::ns_t_a, "1.2.3.4"},
2665 {host_name2, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
2666 };
nuccachena26cc2a2018-07-17 18:07:23 +08002667
Xiao Ma09b71022018-12-11 17:56:32 +09002668 test::DNSResponder dns(listen_addr);
2669 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002670 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002671 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002672
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002673 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002674 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002675 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002676
2677 // Assign argument hints of getaddrinfo() as null is equivalent to set ai_family AF_UNSPEC.
2678 // In AF_UNSPEC case, synthesize AAAA if there has A answer only.
2679 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, nullptr);
2680 EXPECT_TRUE(result != nullptr);
2681 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2682 std::string result_str = ToString(result);
2683 EXPECT_EQ(result_str, "64:ff9b::102:304");
2684 dns.clearQueries();
2685
2686 // In AF_UNSPEC case, do not synthesize AAAA if there's at least one AAAA answer.
2687 result = safe_getaddrinfo("v4v6", nullptr, nullptr);
2688 EXPECT_TRUE(result != nullptr);
2689 EXPECT_LE(2U, GetNumQueries(dns, host_name2));
2690 std::vector<std::string> result_strs = ToStrings(result);
2691 for (const auto& str : result_strs) {
2692 EXPECT_TRUE(str == "1.2.3.4" || str == "2001:db8::102:304")
2693 << ", result_str='" << str << "'";
2694 }
2695}
2696
2697TEST_F(ResolverTest, GetAddrInfo_Dns64QueryNullArgumentNode) {
2698 constexpr char ADDR_ANYADDR_V4[] = "0.0.0.0";
2699 constexpr char ADDR_ANYADDR_V6[] = "::";
2700 constexpr char ADDR_LOCALHOST_V4[] = "127.0.0.1";
2701 constexpr char ADDR_LOCALHOST_V6[] = "::1";
2702
2703 constexpr char PORT_NAME_HTTP[] = "http";
2704 constexpr char PORT_NUMBER_HTTP[] = "80";
2705
2706 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002707 constexpr char dns64_name[] = "ipv4only.arpa.";
2708
Xiao Ma09b71022018-12-11 17:56:32 +09002709 test::DNSResponder dns(listen_addr);
2710 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachena26cc2a2018-07-17 18:07:23 +08002711 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002712 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002713
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002714 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002715 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002716 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002717
Luke Huangf8215372019-11-22 11:53:41 +08002718 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08002719 // If node is null, return address is listed by libc/getaddrinfo.c as follows.
2720 // - passive socket -> anyaddr (0.0.0.0 or ::)
2721 // - non-passive socket -> localhost (127.0.0.1 or ::1)
2722 static const struct TestConfig {
2723 int flag;
2724 std::string addr_v4;
2725 std::string addr_v6;
2726
2727 std::string asParameters() const {
2728 return StringPrintf("flag=%d, addr_v4=%s, addr_v6=%s", flag, addr_v4.c_str(),
2729 addr_v6.c_str());
2730 }
2731 } testConfigs[]{
2732 {0 /* non-passive */, ADDR_LOCALHOST_V4, ADDR_LOCALHOST_V6},
2733 {AI_PASSIVE, ADDR_ANYADDR_V4, ADDR_ANYADDR_V6}
2734 };
Luke Huangf8215372019-11-22 11:53:41 +08002735 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08002736
2737 for (const auto& config : testConfigs) {
2738 SCOPED_TRACE(config.asParameters());
2739
Xiao Ma09b71022018-12-11 17:56:32 +09002740 addrinfo hints = {
Nick Desaulnierscd6395a2019-10-11 09:15:24 -07002741 .ai_flags = config.flag,
Xiao Ma09b71022018-12-11 17:56:32 +09002742 .ai_family = AF_UNSPEC, // any address family
2743 .ai_socktype = 0, // any type
2744 .ai_protocol = 0, // any protocol
Xiao Ma09b71022018-12-11 17:56:32 +09002745 };
nuccachena26cc2a2018-07-17 18:07:23 +08002746
2747 // Assign hostname as null and service as port name.
2748 ScopedAddrinfo result = safe_getaddrinfo(nullptr, PORT_NAME_HTTP, &hints);
2749 ASSERT_TRUE(result != nullptr);
2750
2751 // Can't be synthesized because it should not get into Netd.
2752 std::vector<std::string> result_strs = ToStrings(result);
2753 for (const auto& str : result_strs) {
2754 EXPECT_TRUE(str == config.addr_v4 || str == config.addr_v6)
2755 << ", result_str='" << str << "'";
2756 }
2757
2758 // Assign hostname as null and service as numeric port number.
2759 hints.ai_flags = config.flag | AI_NUMERICSERV;
2760 result = safe_getaddrinfo(nullptr, PORT_NUMBER_HTTP, &hints);
2761 ASSERT_TRUE(result != nullptr);
2762
2763 // Can't be synthesized because it should not get into Netd.
2764 result_strs = ToStrings(result);
2765 for (const auto& str : result_strs) {
2766 EXPECT_TRUE(str == config.addr_v4 || str == config.addr_v6)
2767 << ", result_str='" << str << "'";
2768 }
2769 }
2770}
2771
2772TEST_F(ResolverTest, GetHostByAddr_ReverseDnsQueryWithHavingNat64Prefix) {
2773 struct hostent* result = nullptr;
2774 struct in_addr v4addr;
2775 struct in6_addr v6addr;
2776
2777 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002778 constexpr char dns64_name[] = "ipv4only.arpa.";
2779 constexpr char ptr_name[] = "v4v6.example.com.";
2780 // PTR record for IPv4 address 1.2.3.4
2781 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2782 // PTR record for IPv6 address 2001:db8::102:304
2783 constexpr char ptr_addr_v6[] =
2784 "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 +09002785 const std::vector<DnsRecord> records = {
2786 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2787 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2788 {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name},
2789 };
nuccachena26cc2a2018-07-17 18:07:23 +08002790
Xiao Ma09b71022018-12-11 17:56:32 +09002791 test::DNSResponder dns(listen_addr);
2792 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002793 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002794 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002795
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002796 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002797 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002798 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002799
2800 // Reverse IPv4 DNS query. Prefix should have no effect on it.
2801 inet_pton(AF_INET, "1.2.3.4", &v4addr);
2802 result = gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET);
2803 ASSERT_TRUE(result != nullptr);
2804 std::string result_str = result->h_name ? result->h_name : "null";
2805 EXPECT_EQ(result_str, "v4v6.example.com");
2806
2807 // Reverse IPv6 DNS query. Prefix should have no effect on it.
2808 inet_pton(AF_INET6, "2001:db8::102:304", &v6addr);
2809 result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2810 ASSERT_TRUE(result != nullptr);
2811 result_str = result->h_name ? result->h_name : "null";
2812 EXPECT_EQ(result_str, "v4v6.example.com");
2813}
2814
2815TEST_F(ResolverTest, GetHostByAddr_ReverseDns64Query) {
2816 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002817 constexpr char dns64_name[] = "ipv4only.arpa.";
2818 constexpr char ptr_name[] = "v4only.example.com.";
2819 // PTR record for IPv4 address 1.2.3.4
2820 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2821 // PTR record for IPv6 address 64:ff9b::1.2.3.4
2822 constexpr char ptr_addr_v6_nomapping[] =
2823 "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.";
2824 constexpr char ptr_name_v6_synthesis[] = "v6synthesis.example.com.";
2825 // PTR record for IPv6 address 64:ff9b::5.6.7.8
2826 constexpr char ptr_addr_v6_synthesis[] =
2827 "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 +09002828 const std::vector<DnsRecord> records = {
2829 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2830 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2831 {ptr_addr_v6_synthesis, ns_type::ns_t_ptr, ptr_name_v6_synthesis},
2832 };
nuccachena26cc2a2018-07-17 18:07:23 +08002833
Xiao Ma09b71022018-12-11 17:56:32 +09002834 test::DNSResponder dns(listen_addr);
2835 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002836 // "ptr_addr_v6_nomapping" is not mapped in DNS server
nuccachena26cc2a2018-07-17 18:07:23 +08002837 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002838 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002839
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002840 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002841 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002842 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002843
2844 // Synthesized PTR record doesn't exist on DNS server
2845 // Reverse IPv6 DNS64 query while DNS server doesn't have an answer for synthesized address.
2846 // After querying synthesized address failed, expect that prefix is removed from IPv6
2847 // synthesized address and do reverse IPv4 query instead.
2848 struct in6_addr v6addr;
2849 inet_pton(AF_INET6, "64:ff9b::1.2.3.4", &v6addr);
2850 struct hostent* result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2851 ASSERT_TRUE(result != nullptr);
2852 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_nomapping)); // PTR record not exist
2853 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4)); // PTR record exist
2854 std::string result_str = result->h_name ? result->h_name : "null";
2855 EXPECT_EQ(result_str, "v4only.example.com");
2856 // Check that return address has been mapped from IPv4 to IPv6 address because Netd
2857 // removes NAT64 prefix and does IPv4 DNS reverse lookup in this case. Then, Netd
2858 // fakes the return IPv4 address as original queried IPv6 address.
2859 result_str = ToString(result);
2860 EXPECT_EQ(result_str, "64:ff9b::102:304");
2861 dns.clearQueries();
2862
2863 // Synthesized PTR record exists on DNS server
2864 // Reverse IPv6 DNS64 query while DNS server has an answer for synthesized address.
2865 // Expect to Netd pass through synthesized address for DNS queries.
2866 inet_pton(AF_INET6, "64:ff9b::5.6.7.8", &v6addr);
2867 result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2868 ASSERT_TRUE(result != nullptr);
2869 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_synthesis));
2870 result_str = result->h_name ? result->h_name : "null";
2871 EXPECT_EQ(result_str, "v6synthesis.example.com");
2872}
2873
2874TEST_F(ResolverTest, GetHostByAddr_ReverseDns64QueryFromHostFile) {
2875 constexpr char dns64_name[] = "ipv4only.arpa.";
2876 constexpr char host_name[] = "localhost";
2877 // The address is synthesized by prefix64:localhost.
2878 constexpr char host_addr[] = "64:ff9b::7f00:1";
nuccachena26cc2a2018-07-17 18:07:23 +08002879 constexpr char listen_addr[] = "::1";
Xiao Ma09b71022018-12-11 17:56:32 +09002880
2881 test::DNSResponder dns(listen_addr);
2882 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
nuccachena26cc2a2018-07-17 18:07:23 +08002883 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002884 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002885
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002886 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002887 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002888 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002889
2890 // Using synthesized "localhost" address to be a trick for resolving host name
2891 // from host file /etc/hosts and "localhost" is the only name in /etc/hosts. Note that this is
2892 // not realistic: the code never synthesizes AAAA records for addresses in 127.0.0.0/8.
2893 struct in6_addr v6addr;
2894 inet_pton(AF_INET6, host_addr, &v6addr);
2895 struct hostent* result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2896 ASSERT_TRUE(result != nullptr);
2897 // Expect no DNS queries; localhost is resolved via /etc/hosts.
2898 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
2899
Luke Huangf8215372019-11-22 11:53:41 +08002900 ASSERT_EQ(sizeof(in6_addr), (unsigned)result->h_length);
nuccachena26cc2a2018-07-17 18:07:23 +08002901 ASSERT_EQ(AF_INET6, result->h_addrtype);
2902 std::string result_str = ToString(result);
2903 EXPECT_EQ(result_str, host_addr);
2904 result_str = result->h_name ? result->h_name : "null";
2905 EXPECT_EQ(result_str, host_name);
2906}
2907
Hungming Chen9e6185a2019-06-04 16:09:19 +08002908TEST_F(ResolverTest, GetHostByAddr_cnamesClasslessReverseDelegation) {
2909 // IPv4 addresses in the subnet with notation '/' or '-'.
2910 constexpr char addr_slash[] = "192.0.2.1";
2911 constexpr char addr_hyphen[] = "192.0.3.1";
2912
2913 // Used to verify DNS reverse query for classless reverse lookup zone. See detail in RFC 2317
2914 // section 4.
2915 const static std::vector<DnsRecord> records = {
2916 // The records for reverse querying "192.0.2.1" in the subnet with notation '/'.
2917 {"1.2.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0/25.2.0.192.in-addr.arpa."},
2918 {"1.0/25.2.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
2919
2920 // The records for reverse querying "192.0.3.1" in the subnet with notation '-'.
2921 {"1.3.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0-127.3.0.192.in-addr.arpa."},
2922 {"1.0-127.3.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
2923 };
2924
2925 test::DNSResponder dns;
2926 StartDns(dns, records);
2927 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
2928
2929 for (const auto& address : {addr_slash, addr_hyphen}) {
2930 SCOPED_TRACE(address);
2931
2932 in_addr v4addr;
2933 ASSERT_TRUE(inet_pton(AF_INET, address, &v4addr));
2934 hostent* result = gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET);
2935 ASSERT_TRUE(result != nullptr);
2936 EXPECT_STREQ("hello.example.com", result->h_name);
2937 }
2938}
2939
nuccachena26cc2a2018-07-17 18:07:23 +08002940TEST_F(ResolverTest, GetNameInfo_ReverseDnsQueryWithHavingNat64Prefix) {
2941 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002942 constexpr char dns64_name[] = "ipv4only.arpa.";
2943 constexpr char ptr_name[] = "v4v6.example.com.";
2944 // PTR record for IPv4 address 1.2.3.4
2945 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2946 // PTR record for IPv6 address 2001:db8::102:304
2947 constexpr char ptr_addr_v6[] =
2948 "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 +09002949 const std::vector<DnsRecord> records = {
2950 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2951 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2952 {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name},
2953 };
nuccachena26cc2a2018-07-17 18:07:23 +08002954
Xiao Ma09b71022018-12-11 17:56:32 +09002955 test::DNSResponder dns(listen_addr);
2956 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002957 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002958 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002959
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002960 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002961 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002962 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002963
Luke Huangf8215372019-11-22 11:53:41 +08002964 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08002965 static const struct TestConfig {
2966 int flag;
2967 int family;
2968 std::string addr;
2969 std::string host;
2970
2971 std::string asParameters() const {
2972 return StringPrintf("flag=%d, family=%d, addr=%s, host=%s", flag, family, addr.c_str(),
2973 host.c_str());
2974 }
2975 } testConfigs[]{
2976 {NI_NAMEREQD, AF_INET, "1.2.3.4", "v4v6.example.com"},
2977 {NI_NUMERICHOST, AF_INET, "1.2.3.4", "1.2.3.4"},
2978 {0, AF_INET, "1.2.3.4", "v4v6.example.com"},
2979 {0, AF_INET, "5.6.7.8", "5.6.7.8"}, // unmapped
2980 {NI_NAMEREQD, AF_INET6, "2001:db8::102:304", "v4v6.example.com"},
2981 {NI_NUMERICHOST, AF_INET6, "2001:db8::102:304", "2001:db8::102:304"},
2982 {0, AF_INET6, "2001:db8::102:304", "v4v6.example.com"},
2983 {0, AF_INET6, "2001:db8::506:708", "2001:db8::506:708"}, // unmapped
2984 };
Luke Huangf8215372019-11-22 11:53:41 +08002985 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08002986
2987 // Reverse IPv4/IPv6 DNS query. Prefix should have no effect on it.
2988 for (const auto& config : testConfigs) {
2989 SCOPED_TRACE(config.asParameters());
2990
2991 int rv;
2992 char host[NI_MAXHOST];
2993 struct sockaddr_in sin;
2994 struct sockaddr_in6 sin6;
2995 if (config.family == AF_INET) {
2996 memset(&sin, 0, sizeof(sin));
2997 sin.sin_family = AF_INET;
2998 inet_pton(AF_INET, config.addr.c_str(), &sin.sin_addr);
Luke Huangf8215372019-11-22 11:53:41 +08002999 rv = getnameinfo((const struct sockaddr*)&sin, sizeof(sin), host, sizeof(host), nullptr,
3000 0, config.flag);
nuccachena26cc2a2018-07-17 18:07:23 +08003001 if (config.flag == NI_NAMEREQD) EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4));
3002 } else if (config.family == AF_INET6) {
3003 memset(&sin6, 0, sizeof(sin6));
3004 sin6.sin6_family = AF_INET6;
3005 inet_pton(AF_INET6, config.addr.c_str(), &sin6.sin6_addr);
Luke Huangf8215372019-11-22 11:53:41 +08003006 rv = getnameinfo((const struct sockaddr*)&sin6, sizeof(sin6), host, sizeof(host),
nuccachena26cc2a2018-07-17 18:07:23 +08003007 nullptr, 0, config.flag);
3008 if (config.flag == NI_NAMEREQD) EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6));
3009 }
3010 ASSERT_EQ(0, rv);
3011 std::string result_str = host;
3012 EXPECT_EQ(result_str, config.host);
3013 dns.clearQueries();
3014 }
3015}
3016
3017TEST_F(ResolverTest, GetNameInfo_ReverseDns64Query) {
3018 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08003019 constexpr char dns64_name[] = "ipv4only.arpa.";
3020 constexpr char ptr_name[] = "v4only.example.com.";
3021 // PTR record for IPv4 address 1.2.3.4
3022 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
3023 // PTR record for IPv6 address 64:ff9b::1.2.3.4
3024 constexpr char ptr_addr_v6_nomapping[] =
3025 "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.";
3026 constexpr char ptr_name_v6_synthesis[] = "v6synthesis.example.com.";
3027 // PTR record for IPv6 address 64:ff9b::5.6.7.8
3028 constexpr char ptr_addr_v6_synthesis[] =
3029 "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 +09003030 const std::vector<DnsRecord> records = {
3031 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
3032 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
3033 {ptr_addr_v6_synthesis, ns_type::ns_t_ptr, ptr_name_v6_synthesis},
3034 };
nuccachena26cc2a2018-07-17 18:07:23 +08003035
Xiao Ma09b71022018-12-11 17:56:32 +09003036 test::DNSResponder dns(listen_addr);
3037 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08003038 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003039 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003040
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003041 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003042 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003043 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003044
Luke Huangf8215372019-11-22 11:53:41 +08003045 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08003046 static const struct TestConfig {
3047 bool hasSynthesizedPtrRecord;
3048 int flag;
3049 std::string addr;
3050 std::string host;
3051
3052 std::string asParameters() const {
3053 return StringPrintf("hasSynthesizedPtrRecord=%d, flag=%d, addr=%s, host=%s",
3054 hasSynthesizedPtrRecord, flag, addr.c_str(), host.c_str());
3055 }
3056 } testConfigs[]{
3057 {false, NI_NAMEREQD, "64:ff9b::102:304", "v4only.example.com"},
3058 {false, NI_NUMERICHOST, "64:ff9b::102:304", "64:ff9b::102:304"},
3059 {false, 0, "64:ff9b::102:304", "v4only.example.com"},
3060 {true, NI_NAMEREQD, "64:ff9b::506:708", "v6synthesis.example.com"},
3061 {true, NI_NUMERICHOST, "64:ff9b::506:708", "64:ff9b::506:708"},
3062 {true, 0, "64:ff9b::506:708", "v6synthesis.example.com"}
3063 };
Luke Huangf8215372019-11-22 11:53:41 +08003064 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08003065
3066 // hasSynthesizedPtrRecord = false
3067 // Synthesized PTR record doesn't exist on DNS server
3068 // Reverse IPv6 DNS64 query while DNS server doesn't have an answer for synthesized address.
3069 // After querying synthesized address failed, expect that prefix is removed from IPv6
3070 // synthesized address and do reverse IPv4 query instead.
3071 //
3072 // hasSynthesizedPtrRecord = true
3073 // Synthesized PTR record exists on DNS server
3074 // Reverse IPv6 DNS64 query while DNS server has an answer for synthesized address.
3075 // Expect to just pass through synthesized address for DNS queries.
3076 for (const auto& config : testConfigs) {
3077 SCOPED_TRACE(config.asParameters());
3078
3079 char host[NI_MAXHOST];
3080 struct sockaddr_in6 sin6;
3081 memset(&sin6, 0, sizeof(sin6));
3082 sin6.sin6_family = AF_INET6;
3083 inet_pton(AF_INET6, config.addr.c_str(), &sin6.sin6_addr);
Luke Huangf8215372019-11-22 11:53:41 +08003084 int rv = getnameinfo((const struct sockaddr*)&sin6, sizeof(sin6), host, sizeof(host),
nuccachena26cc2a2018-07-17 18:07:23 +08003085 nullptr, 0, config.flag);
3086 ASSERT_EQ(0, rv);
3087 if (config.flag == NI_NAMEREQD) {
3088 if (config.hasSynthesizedPtrRecord) {
3089 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_synthesis));
3090 } else {
3091 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_nomapping)); // PTR record not exist.
3092 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4)); // PTR record exist.
3093 }
3094 }
3095 std::string result_str = host;
3096 EXPECT_EQ(result_str, config.host);
3097 dns.clearQueries();
3098 }
3099}
3100
3101TEST_F(ResolverTest, GetNameInfo_ReverseDns64QueryFromHostFile) {
3102 constexpr char dns64_name[] = "ipv4only.arpa.";
3103 constexpr char host_name[] = "localhost";
3104 // The address is synthesized by prefix64:localhost.
3105 constexpr char host_addr[] = "64:ff9b::7f00:1";
nuccachena26cc2a2018-07-17 18:07:23 +08003106 constexpr char listen_addr[] = "::1";
Xiao Ma09b71022018-12-11 17:56:32 +09003107
3108 test::DNSResponder dns(listen_addr);
3109 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
nuccachena26cc2a2018-07-17 18:07:23 +08003110 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003111 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003112
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003113 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003114 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003115 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003116
3117 // Using synthesized "localhost" address to be a trick for resolving host name
3118 // from host file /etc/hosts and "localhost" is the only name in /etc/hosts. Note that this is
3119 // not realistic: the code never synthesizes AAAA records for addresses in 127.0.0.0/8.
3120 char host[NI_MAXHOST];
Xiao Ma09b71022018-12-11 17:56:32 +09003121 struct sockaddr_in6 sin6 = {.sin6_family = AF_INET6};
nuccachena26cc2a2018-07-17 18:07:23 +08003122 inet_pton(AF_INET6, host_addr, &sin6.sin6_addr);
Luke Huangf8215372019-11-22 11:53:41 +08003123 int rv = getnameinfo((const struct sockaddr*)&sin6, sizeof(sin6), host, sizeof(host), nullptr,
nuccachena26cc2a2018-07-17 18:07:23 +08003124 0, NI_NAMEREQD);
3125 ASSERT_EQ(0, rv);
3126 // Expect no DNS queries; localhost is resolved via /etc/hosts.
3127 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
3128
3129 std::string result_str = host;
3130 EXPECT_EQ(result_str, host_name);
3131}
3132
Hungming Chen9e6185a2019-06-04 16:09:19 +08003133TEST_F(ResolverTest, GetNameInfo_cnamesClasslessReverseDelegation) {
3134 // IPv4 addresses in the subnet with notation '/' or '-'.
3135 constexpr char addr_slash[] = "192.0.2.1";
3136 constexpr char addr_hyphen[] = "192.0.3.1";
3137
3138 // Used to verify DNS reverse query for classless reverse lookup zone. See detail in RFC 2317
3139 // section 4.
3140 const static std::vector<DnsRecord> records = {
3141 // The records for reverse querying "192.0.2.1" in the subnet with notation '/'.
3142 {"1.2.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0/25.2.0.192.in-addr.arpa."},
3143 {"1.0/25.2.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
3144
3145 // The records for reverse querying "192.0.3.1" in the subnet with notation '-'.
3146 {"1.3.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0-127.3.0.192.in-addr.arpa."},
3147 {"1.0-127.3.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
3148 };
3149
3150 test::DNSResponder dns;
3151 StartDns(dns, records);
3152 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3153
3154 for (const auto& address : {addr_slash, addr_hyphen}) {
3155 SCOPED_TRACE(address);
3156
3157 char host[NI_MAXHOST];
3158 sockaddr_in sin = {.sin_family = AF_INET};
3159 ASSERT_TRUE(inet_pton(AF_INET, address, &sin.sin_addr));
3160 int rv = getnameinfo((const sockaddr*)&sin, sizeof(sin), host, sizeof(host), nullptr, 0,
3161 NI_NAMEREQD);
3162 ASSERT_EQ(0, rv);
3163 EXPECT_STREQ("hello.example.com", host);
3164 }
3165}
3166
nuccachena26cc2a2018-07-17 18:07:23 +08003167TEST_F(ResolverTest, GetHostByName2_Dns64Synthesize) {
Xiao Ma09b71022018-12-11 17:56:32 +09003168 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08003169 constexpr char dns64_name[] = "ipv4only.arpa.";
3170 constexpr char host_name[] = "ipv4only.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09003171 const std::vector<DnsRecord> records = {
3172 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
3173 {host_name, ns_type::ns_t_a, "1.2.3.4"},
3174 };
nuccachena26cc2a2018-07-17 18:07:23 +08003175
Xiao Ma09b71022018-12-11 17:56:32 +09003176 test::DNSResponder dns(listen_addr);
3177 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08003178 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003179 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003180
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003181 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003182 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003183 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003184
3185 // Query an IPv4-only hostname. Expect that gets a synthesized address.
3186 struct hostent* result = gethostbyname2("ipv4only", AF_INET6);
3187 ASSERT_TRUE(result != nullptr);
3188 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3189 std::string result_str = ToString(result);
3190 EXPECT_EQ(result_str, "64:ff9b::102:304");
3191}
nuccachena26cc2a2018-07-17 18:07:23 +08003192
3193TEST_F(ResolverTest, GetHostByName2_DnsQueryWithHavingNat64Prefix) {
3194 constexpr char dns64_name[] = "ipv4only.arpa.";
3195 constexpr char host_name[] = "v4v6.example.com.";
nuccachena26cc2a2018-07-17 18:07:23 +08003196 constexpr char listen_addr[] = "::1";
Xiao Ma09b71022018-12-11 17:56:32 +09003197 const std::vector<DnsRecord> records = {
3198 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
3199 {host_name, ns_type::ns_t_a, "1.2.3.4"},
3200 {host_name, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
3201 };
3202
3203 test::DNSResponder dns(listen_addr);
3204 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08003205 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003206 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003207
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003208 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003209 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003210 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003211
3212 // IPv4 DNS query. Prefix should have no effect on it.
3213 struct hostent* result = gethostbyname2("v4v6", AF_INET);
3214 ASSERT_TRUE(result != nullptr);
3215 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3216 std::string result_str = ToString(result);
3217 EXPECT_EQ(result_str, "1.2.3.4");
3218 dns.clearQueries();
3219
3220 // IPv6 DNS query. Prefix should have no effect on it.
3221 result = gethostbyname2("v4v6", AF_INET6);
3222 ASSERT_TRUE(result != nullptr);
3223 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3224 result_str = ToString(result);
3225 EXPECT_EQ(result_str, "2001:db8::102:304");
3226}
3227
3228TEST_F(ResolverTest, GetHostByName2_Dns64QuerySpecialUseIPv4Addresses) {
3229 constexpr char THIS_NETWORK[] = "this_network";
3230 constexpr char LOOPBACK[] = "loopback";
3231 constexpr char LINK_LOCAL[] = "link_local";
3232 constexpr char MULTICAST[] = "multicast";
3233 constexpr char LIMITED_BROADCAST[] = "limited_broadcast";
3234
3235 constexpr char ADDR_THIS_NETWORK[] = "0.0.0.1";
3236 constexpr char ADDR_LOOPBACK[] = "127.0.0.1";
3237 constexpr char ADDR_LINK_LOCAL[] = "169.254.0.1";
3238 constexpr char ADDR_MULTICAST[] = "224.0.0.1";
3239 constexpr char ADDR_LIMITED_BROADCAST[] = "255.255.255.255";
3240
3241 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08003242 constexpr char dns64_name[] = "ipv4only.arpa.";
3243
Xiao Ma09b71022018-12-11 17:56:32 +09003244 test::DNSResponder dns(listen_addr);
3245 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachena26cc2a2018-07-17 18:07:23 +08003246 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003247 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003248
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003249 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003250 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003251 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003252
Luke Huangf8215372019-11-22 11:53:41 +08003253 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08003254 static const struct TestConfig {
3255 std::string name;
3256 std::string addr;
3257
3258 std::string asHostName() const {
Luke Huangf8215372019-11-22 11:53:41 +08003259 return StringPrintf("%s.example.com.", name.c_str());
nuccachena26cc2a2018-07-17 18:07:23 +08003260 }
3261 } testConfigs[]{
3262 {THIS_NETWORK, ADDR_THIS_NETWORK},
3263 {LOOPBACK, ADDR_LOOPBACK},
3264 {LINK_LOCAL, ADDR_LINK_LOCAL},
3265 {MULTICAST, ADDR_MULTICAST},
3266 {LIMITED_BROADCAST, ADDR_LIMITED_BROADCAST}
3267 };
Luke Huangf8215372019-11-22 11:53:41 +08003268 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08003269
3270 for (const auto& config : testConfigs) {
3271 const std::string testHostName = config.asHostName();
3272 SCOPED_TRACE(testHostName);
3273
3274 const char* host_name = testHostName.c_str();
3275 dns.addMapping(host_name, ns_type::ns_t_a, config.addr.c_str());
3276
3277 struct hostent* result = gethostbyname2(config.name.c_str(), AF_INET6);
3278 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3279
3280 // In AF_INET6 case, don't synthesize special use IPv4 address.
3281 // Expect to have no answer
3282 EXPECT_EQ(nullptr, result);
3283
3284 dns.clearQueries();
3285 }
Bernie Innocenti2fef2b82018-12-20 15:56:40 +09003286}
Mike Yuf14e1a92019-05-10 13:54:58 +08003287
3288TEST_F(ResolverTest, PrefixDiscoveryBypassTls) {
3289 constexpr char listen_addr[] = "::1";
3290 constexpr char cleartext_port[] = "53";
3291 constexpr char tls_port[] = "853";
3292 constexpr char dns64_name[] = "ipv4only.arpa.";
3293 const std::vector<std::string> servers = {listen_addr};
3294
3295 test::DNSResponder dns(listen_addr);
3296 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
3297 test::DnsTlsFrontend tls(listen_addr, tls_port, listen_addr, cleartext_port);
3298 ASSERT_TRUE(tls.startServer());
3299
3300 // Setup OPPORTUNISTIC mode and wait for the validation complete.
waynema0e73c2e2019-07-31 15:04:08 +08003301 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08003302 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yuf14e1a92019-05-10 13:54:58 +08003303 tls.clearQueries();
3304
3305 // Start NAT64 prefix discovery and wait for it complete.
3306 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003307 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
Mike Yuf14e1a92019-05-10 13:54:58 +08003308
3309 // Verify it bypassed TLS even though there's a TLS server available.
3310 EXPECT_EQ(0, tls.queries());
3311 EXPECT_EQ(1U, GetNumQueries(dns, dns64_name));
3312
3313 // Restart the testing network to reset the cache.
3314 mDnsClient.TearDown();
3315 mDnsClient.SetUp();
3316 dns.clearQueries();
3317
3318 // Setup STRICT mode and wait for the validation complete.
waynema0e73c2e2019-07-31 15:04:08 +08003319 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
3320 kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08003321 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yuf14e1a92019-05-10 13:54:58 +08003322 tls.clearQueries();
3323
3324 // Start NAT64 prefix discovery and wait for it to complete.
3325 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003326 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
Mike Yuf14e1a92019-05-10 13:54:58 +08003327
3328 // Verify it bypassed TLS despite STRICT mode.
3329 EXPECT_EQ(0, tls.queries());
3330 EXPECT_EQ(1U, GetNumQueries(dns, dns64_name));
3331}
Luke Huang9807e6b2019-05-20 16:17:12 +08003332
3333namespace {
3334
Luke Huang0d592bc2019-05-25 18:24:03 +08003335class ScopedSetNetworkForProcess {
3336 public:
3337 explicit ScopedSetNetworkForProcess(unsigned netId) {
3338 mStoredNetId = getNetworkForProcess();
3339 if (netId == mStoredNetId) return;
3340 EXPECT_EQ(0, setNetworkForProcess(netId));
3341 }
3342 ~ScopedSetNetworkForProcess() { EXPECT_EQ(0, setNetworkForProcess(mStoredNetId)); }
3343
3344 private:
3345 unsigned mStoredNetId;
3346};
3347
3348class ScopedSetNetworkForResolv {
3349 public:
3350 explicit ScopedSetNetworkForResolv(unsigned netId) { EXPECT_EQ(0, setNetworkForResolv(netId)); }
3351 ~ScopedSetNetworkForResolv() { EXPECT_EQ(0, setNetworkForResolv(NETID_UNSET)); }
3352};
3353
Luke Huang9807e6b2019-05-20 16:17:12 +08003354void sendCommand(int fd, const std::string& cmd) {
3355 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size() + 1));
3356 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size() + 1));
3357}
3358
3359int32_t readBE32(int fd) {
3360 int32_t tmp;
3361 int n = TEMP_FAILURE_RETRY(read(fd, &tmp, sizeof(tmp)));
3362 EXPECT_TRUE(n > 0);
3363 return ntohl(tmp);
3364}
3365
Luke Huang0d592bc2019-05-25 18:24:03 +08003366int readResponseCode(int fd) {
Luke Huang9807e6b2019-05-20 16:17:12 +08003367 char buf[4];
3368 int n = TEMP_FAILURE_RETRY(read(fd, &buf, sizeof(buf)));
3369 EXPECT_TRUE(n > 0);
3370 // The format of response code is that 4 bytes for the code & null.
3371 buf[3] = '\0';
3372 int result;
3373 EXPECT_TRUE(ParseInt(buf, &result));
3374 return result;
3375}
3376
Luke Huang0d592bc2019-05-25 18:24:03 +08003377bool checkAndClearUseLocalNameserversFlag(unsigned* netid) {
3378 if (netid == nullptr || ((*netid) & NETID_USE_LOCAL_NAMESERVERS) == 0) {
3379 return false;
3380 }
3381 *netid = (*netid) & ~NETID_USE_LOCAL_NAMESERVERS;
3382 return true;
3383}
3384
Luke Huangf8215372019-11-22 11:53:41 +08003385aidl::android::net::UidRangeParcel makeUidRangeParcel(int start, int stop) {
3386 aidl::android::net::UidRangeParcel res;
Luke Huang0d592bc2019-05-25 18:24:03 +08003387 res.start = start;
3388 res.stop = stop;
3389
3390 return res;
3391}
3392
3393void expectNetIdWithLocalNameserversFlag(unsigned netId) {
3394 unsigned dnsNetId = 0;
3395 EXPECT_EQ(0, getNetworkForDns(&dnsNetId));
3396 EXPECT_TRUE(checkAndClearUseLocalNameserversFlag(&dnsNetId));
3397 EXPECT_EQ(netId, static_cast<unsigned>(dnsNetId));
3398}
3399
3400void expectDnsNetIdEquals(unsigned netId) {
3401 unsigned dnsNetId = 0;
3402 EXPECT_EQ(0, getNetworkForDns(&dnsNetId));
3403 EXPECT_EQ(netId, static_cast<unsigned>(dnsNetId));
3404}
3405
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003406void expectDnsNetIdIsDefaultNetwork(INetd* netdService) {
Luke Huang0d592bc2019-05-25 18:24:03 +08003407 int currentNetid;
3408 EXPECT_TRUE(netdService->networkGetDefault(&currentNetid).isOk());
3409 expectDnsNetIdEquals(currentNetid);
3410}
3411
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003412void expectDnsNetIdWithVpn(INetd* netdService, unsigned vpnNetId, unsigned expectedNetId) {
Luke Huang0d592bc2019-05-25 18:24:03 +08003413 EXPECT_TRUE(netdService->networkCreateVpn(vpnNetId, false /* secure */).isOk());
3414 uid_t uid = getuid();
3415 // Add uid to VPN
3416 EXPECT_TRUE(netdService->networkAddUidRanges(vpnNetId, {makeUidRangeParcel(uid, uid)}).isOk());
3417 expectDnsNetIdEquals(expectedNetId);
3418 EXPECT_TRUE(netdService->networkDestroy(vpnNetId).isOk());
3419}
3420
Luke Huang9807e6b2019-05-20 16:17:12 +08003421} // namespace
3422
3423TEST_F(ResolverTest, getDnsNetId) {
3424 // We've called setNetworkForProcess in SetupOemNetwork, so reset to default first.
3425 setNetworkForProcess(NETID_UNSET);
Luke Huang0d592bc2019-05-25 18:24:03 +08003426
3427 expectDnsNetIdIsDefaultNetwork(mDnsClient.netdService());
3428 expectDnsNetIdWithVpn(mDnsClient.netdService(), TEST_VPN_NETID, TEST_VPN_NETID);
Luke Huang9807e6b2019-05-20 16:17:12 +08003429
3430 // Test with setNetworkForProcess
Luke Huang0d592bc2019-05-25 18:24:03 +08003431 {
3432 ScopedSetNetworkForProcess scopedSetNetworkForProcess(TEST_NETID);
3433 expectDnsNetIdEquals(TEST_NETID);
3434 }
3435
3436 // Test with setNetworkForProcess with NETID_USE_LOCAL_NAMESERVERS
3437 {
3438 ScopedSetNetworkForProcess scopedSetNetworkForProcess(TEST_NETID |
3439 NETID_USE_LOCAL_NAMESERVERS);
3440 expectNetIdWithLocalNameserversFlag(TEST_NETID);
3441 }
Luke Huang9807e6b2019-05-20 16:17:12 +08003442
3443 // Test with setNetworkForResolv
Luke Huang0d592bc2019-05-25 18:24:03 +08003444 {
3445 ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID);
3446 expectDnsNetIdEquals(TEST_NETID);
3447 }
3448
3449 // Test with setNetworkForResolv with NETID_USE_LOCAL_NAMESERVERS
3450 {
3451 ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID |
3452 NETID_USE_LOCAL_NAMESERVERS);
3453 expectNetIdWithLocalNameserversFlag(TEST_NETID);
3454 }
3455
3456 // Test with setNetworkForResolv under bypassable vpn
3457 {
3458 ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID);
3459 expectDnsNetIdWithVpn(mDnsClient.netdService(), TEST_VPN_NETID, TEST_NETID);
3460 }
Luke Huang9807e6b2019-05-20 16:17:12 +08003461
3462 // Create socket connected to DnsProxyListener
3463 int fd = dns_open_proxy();
3464 EXPECT_TRUE(fd > 0);
3465 unique_fd ufd(fd);
3466
3467 // Test command with wrong netId
3468 sendCommand(fd, "getdnsnetid abc");
Luke Huang0d592bc2019-05-25 18:24:03 +08003469 EXPECT_EQ(ResponseCode::DnsProxyQueryResult, readResponseCode(fd));
Luke Huang9807e6b2019-05-20 16:17:12 +08003470 EXPECT_EQ(-EINVAL, readBE32(fd));
3471
3472 // Test unsupported command
3473 sendCommand(fd, "getdnsnetidNotSupported");
3474 // Keep in sync with FrameworkListener.cpp (500, "Command not recognized")
Luke Huang0d592bc2019-05-25 18:24:03 +08003475 EXPECT_EQ(500, readResponseCode(fd));
Luke Huang9807e6b2019-05-20 16:17:12 +08003476}
Sehee Park2c118782019-05-07 13:02:45 +09003477
3478TEST_F(ResolverTest, BlockDnsQueryWithUidRule) {
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003479 // This test relies on blocking traffic on loopback, which xt_qtaguid does not do.
3480 // See aosp/358413 and b/34444781 for why.
3481 SKIP_IF_BPF_NOT_SUPPORTED;
3482
Sehee Park2c118782019-05-07 13:02:45 +09003483 constexpr char listen_addr1[] = "127.0.0.4";
3484 constexpr char listen_addr2[] = "::1";
3485 constexpr char host_name[] = "howdy.example.com.";
3486 const std::vector<DnsRecord> records = {
3487 {host_name, ns_type::ns_t_a, "1.2.3.4"},
3488 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
3489 };
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003490 INetd* netdService = mDnsClient.netdService();
Sehee Park2c118782019-05-07 13:02:45 +09003491
3492 test::DNSResponder dns1(listen_addr1);
3493 test::DNSResponder dns2(listen_addr2);
3494 StartDns(dns1, records);
3495 StartDns(dns2, records);
3496
3497 std::vector<std::string> servers = {listen_addr1, listen_addr2};
3498 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
3499 dns1.clearQueries();
3500 dns2.clearQueries();
3501
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003502 // Add drop rule for TEST_UID. Also enable the standby chain because it might not be enabled.
3503 // Unfortunately we cannot use FIREWALL_CHAIN_NONE, or custom iptables rules, for this purpose
3504 // because netd calls fchown() on the DNS query sockets, and "iptables -m owner" matches the
3505 // UID of the socket creator, not the UID set by fchown().
3506 //
3507 // TODO: migrate FIREWALL_CHAIN_NONE to eBPF as well.
3508 EXPECT_TRUE(netdService->firewallEnableChildChain(INetd::FIREWALL_CHAIN_STANDBY, true).isOk());
3509 EXPECT_TRUE(netdService
Sehee Park2c118782019-05-07 13:02:45 +09003510 ->firewallSetUidRule(INetd::FIREWALL_CHAIN_STANDBY, TEST_UID,
3511 INetd::FIREWALL_RULE_DENY)
3512 .isOk());
3513
3514 // Save uid
3515 int suid = getuid();
3516
3517 // Switch to TEST_UID
3518 EXPECT_TRUE(seteuid(TEST_UID) == 0);
3519
3520 // Dns Query
3521 int fd1 = resNetworkQuery(TEST_NETID, host_name, ns_c_in, ns_t_a, 0);
3522 int fd2 = resNetworkQuery(TEST_NETID, host_name, ns_c_in, ns_t_aaaa, 0);
3523 EXPECT_TRUE(fd1 != -1);
3524 EXPECT_TRUE(fd2 != -1);
3525
3526 uint8_t buf[MAXPACKET] = {};
3527 int rcode;
3528 int res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
3529 EXPECT_EQ(-ECONNREFUSED, res);
3530
3531 memset(buf, 0, MAXPACKET);
3532 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
3533 EXPECT_EQ(-ECONNREFUSED, res);
3534
3535 // Restore uid
3536 EXPECT_TRUE(seteuid(suid) == 0);
3537
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003538 // Remove drop rule for TEST_UID, and disable the standby chain.
3539 EXPECT_TRUE(netdService
Sehee Park2c118782019-05-07 13:02:45 +09003540 ->firewallSetUidRule(INetd::FIREWALL_CHAIN_STANDBY, TEST_UID,
3541 INetd::FIREWALL_RULE_ALLOW)
3542 .isOk());
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003543 EXPECT_TRUE(netdService->firewallEnableChildChain(INetd::FIREWALL_CHAIN_STANDBY, false).isOk());
Sehee Park2c118782019-05-07 13:02:45 +09003544}
Mike Yua772c202019-09-23 17:47:21 +08003545
Mike Yu40e67072019-10-09 21:14:09 +08003546namespace {
3547
3548const std::string kDotConnectTimeoutMsFlag(
3549 "persist.device_config.netd_native.dot_connect_timeout_ms");
3550
3551class ScopedSystemProperties {
3552 public:
3553 explicit ScopedSystemProperties(const std::string& key, const std::string& value)
3554 : mStoredKey(key) {
3555 mStoredValue = android::base::GetProperty(key, "");
3556 android::base::SetProperty(key, value);
3557 }
3558 ~ScopedSystemProperties() { android::base::SetProperty(mStoredKey, mStoredValue); }
3559
3560 private:
3561 std::string mStoredKey;
3562 std::string mStoredValue;
3563};
3564
3565} // namespace
3566
Mike Yua772c202019-09-23 17:47:21 +08003567TEST_F(ResolverTest, ConnectTlsServerTimeout) {
Mike Yu40e67072019-10-09 21:14:09 +08003568 constexpr int expectedTimeout = 1000;
3569 constexpr char hostname1[] = "query1.example.com.";
3570 constexpr char hostname2[] = "query2.example.com.";
Mike Yua772c202019-09-23 17:47:21 +08003571 const std::vector<DnsRecord> records = {
Mike Yu40e67072019-10-09 21:14:09 +08003572 {hostname1, ns_type::ns_t_a, "1.2.3.4"},
3573 {hostname2, ns_type::ns_t_a, "1.2.3.5"},
Mike Yua772c202019-09-23 17:47:21 +08003574 };
3575
3576 test::DNSResponder dns;
3577 StartDns(dns, records);
Mike Yu40e67072019-10-09 21:14:09 +08003578 test::DnsTlsFrontend tls;
Mike Yua772c202019-09-23 17:47:21 +08003579 ASSERT_TRUE(tls.startServer());
3580
Mike Yu40e67072019-10-09 21:14:09 +08003581 // The resolver will adjust the timeout value to 1000ms since the value is too small.
3582 ScopedSystemProperties scopedSystemProperties(kDotConnectTimeoutMsFlag, "100");
Mike Yua772c202019-09-23 17:47:21 +08003583
Mike Yu40e67072019-10-09 21:14:09 +08003584 // Set up resolver to opportunistic mode with the default configuration.
Mike Yu8ac63402019-12-02 15:28:38 +08003585 const ResolverParamsParcel parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
Mike Yu40e67072019-10-09 21:14:09 +08003586 ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
Mike Yua772c202019-09-23 17:47:21 +08003587 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
3588 dns.clearQueries();
3589 tls.clearQueries();
3590
3591 // The server becomes unresponsive to the handshake request.
3592 tls.setHangOnHandshakeForTesting(true);
3593
3594 // Expect the things happening in getaddrinfo():
3595 // 1. Connect to the private DNS server.
3596 // 2. SSL handshake times out.
3597 // 3. Fallback to UDP transport, and then get the answer.
Mike Yu40e67072019-10-09 21:14:09 +08003598 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
3599 auto [result, timeTakenMs] = safe_getaddrinfo_time_taken(hostname1, nullptr, hints);
Mike Yua772c202019-09-23 17:47:21 +08003600
Mike Yu40e67072019-10-09 21:14:09 +08003601 EXPECT_NE(nullptr, result);
Mike Yua772c202019-09-23 17:47:21 +08003602 EXPECT_EQ(0, tls.queries());
Mike Yu40e67072019-10-09 21:14:09 +08003603 EXPECT_EQ(1U, GetNumQueries(dns, hostname1));
3604 EXPECT_EQ(records.at(0).addr, ToString(result));
Mike Yua772c202019-09-23 17:47:21 +08003605
Mike Yu40e67072019-10-09 21:14:09 +08003606 // A loose upper bound is set by adding 2000ms buffer time. Theoretically, getaddrinfo()
3607 // should just take a bit more than expetTimeout milliseconds.
3608 EXPECT_GE(timeTakenMs, expectedTimeout);
3609 EXPECT_LE(timeTakenMs, expectedTimeout + 2000);
3610
3611 // Set the server to be responsive. Verify that the resolver will attempt to reconnect
3612 // to the server and then get the result within the timeout.
3613 tls.setHangOnHandshakeForTesting(false);
3614 std::tie(result, timeTakenMs) = safe_getaddrinfo_time_taken(hostname2, nullptr, hints);
3615
3616 EXPECT_NE(nullptr, result);
3617 EXPECT_EQ(1, tls.queries());
3618 EXPECT_EQ(1U, GetNumQueries(dns, hostname2));
3619 EXPECT_EQ(records.at(1).addr, ToString(result));
3620
3621 EXPECT_LE(timeTakenMs, expectedTimeout);
Mike Yua772c202019-09-23 17:47:21 +08003622}
Hungming Chenbb90ab32019-10-28 18:20:31 +08003623
Ken Chen766feae2019-10-30 15:13:44 +08003624TEST_F(ResolverTest, FlushNetworkCache) {
Luke Huang0b5a76c2019-11-23 03:00:00 +08003625 SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsClient.resolvService(), 4);
Ken Chen766feae2019-10-30 15:13:44 +08003626 test::DNSResponder dns;
3627 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3628 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3629
3630 const hostent* result = gethostbyname("hello");
3631 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
3632
3633 // get result from cache
3634 result = gethostbyname("hello");
3635 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
3636
3637 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
3638
3639 result = gethostbyname("hello");
3640 EXPECT_EQ(2U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
3641}
3642
3643TEST_F(ResolverTest, FlushNetworkCache_random) {
Luke Huang0b5a76c2019-11-23 03:00:00 +08003644 SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsClient.resolvService(), 4);
Ken Chen766feae2019-10-30 15:13:44 +08003645 constexpr int num_flush = 10;
3646 constexpr int num_queries = 20;
3647 test::DNSResponder dns;
3648 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3649 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3650 const addrinfo hints = {.ai_family = AF_INET};
3651
3652 std::thread t([this]() {
3653 for (int i = 0; i < num_flush; ++i) {
3654 unsigned delay = arc4random_uniform(10 * 1000); // 10ms
3655 usleep(delay);
3656 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
3657 }
3658 });
3659
3660 for (int i = 0; i < num_queries; ++i) {
3661 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3662 EXPECT_TRUE(result != nullptr);
3663 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3664 }
3665 t.join();
3666}
3667
3668// flush cache while one query is wait-for-response, another is pending.
3669TEST_F(ResolverTest, FlushNetworkCache_concurrent) {
Luke Huang0b5a76c2019-11-23 03:00:00 +08003670 SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsClient.resolvService(), 4);
Ken Chen766feae2019-10-30 15:13:44 +08003671 const char* listen_addr1 = "127.0.0.9";
3672 const char* listen_addr2 = "127.0.0.10";
3673 test::DNSResponder dns1(listen_addr1);
3674 test::DNSResponder dns2(listen_addr2);
3675 StartDns(dns1, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3676 StartDns(dns2, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3677 addrinfo hints = {.ai_family = AF_INET};
3678
3679 // step 1: set server#1 into deferred responding mode
3680 dns1.setDeferredResp(true);
3681 std::thread t1([&listen_addr1, &hints, this]() {
3682 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr1}));
3683 // step 3: query
3684 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3685 // step 9: check result
3686 EXPECT_TRUE(result != nullptr);
3687 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3688 });
3689
3690 // step 2: wait for the query to reach the server
3691 while (GetNumQueries(dns1, kHelloExampleCom) == 0) {
3692 usleep(1000); // 1ms
3693 }
3694
3695 std::thread t2([&listen_addr2, &hints, &dns2, this]() {
3696 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr2}));
3697 // step 5: query (should be blocked in resolver)
3698 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3699 // step 7: check result
3700 EXPECT_TRUE(result != nullptr);
3701 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3702 EXPECT_EQ(1U, GetNumQueriesForType(dns2, ns_type::ns_t_a, kHelloExampleCom));
3703 });
3704
3705 // step 4: wait a bit for the 2nd query to enter pending state
3706 usleep(100 * 1000); // 100ms
3707 // step 6: flush cache (will unblock pending queries)
3708 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
3709 t2.join();
3710
3711 // step 8: resume server#1
3712 dns1.setDeferredResp(false);
3713 t1.join();
3714
3715 // step 10: verify if result is correctly cached
3716 dns2.clearQueries();
3717 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3718 EXPECT_EQ(0U, GetNumQueries(dns2, kHelloExampleCom));
3719 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3720}
3721
Hungming Chenbb90ab32019-10-28 18:20:31 +08003722// Parameterized tests.
3723// TODO: Merge the existing tests as parameterized test if possible.
3724// TODO: Perhaps move parameterized tests to an independent file.
3725enum class CallType { GETADDRINFO, GETHOSTBYNAME };
3726class ResolverParameterizedTest : public ResolverTest,
Hungming Chen63779052019-10-30 15:06:13 +08003727 public testing::WithParamInterface<CallType> {
3728 protected:
3729 void VerifyQueryHelloExampleComV4(const test::DNSResponder& dns, const CallType calltype) {
3730 if (calltype == CallType::GETADDRINFO) {
3731 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
3732 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3733 ASSERT_TRUE(result != nullptr);
3734 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3735 } else if (calltype == CallType::GETHOSTBYNAME) {
3736 const hostent* result = gethostbyname("hello");
3737 ASSERT_TRUE(result != nullptr);
3738 ASSERT_EQ(4, result->h_length);
3739 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
3740 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3741 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
3742 } else {
3743 FAIL() << "Unsupported call type: " << static_cast<uint32_t>(calltype);
3744 }
3745 EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
3746 }
3747};
Hungming Chenbb90ab32019-10-28 18:20:31 +08003748
Hungming Chen63779052019-10-30 15:06:13 +08003749INSTANTIATE_TEST_SUITE_P(QueryCallTest, ResolverParameterizedTest,
Hungming Chenbb90ab32019-10-28 18:20:31 +08003750 testing::Values(CallType::GETADDRINFO, CallType::GETHOSTBYNAME),
3751 [](const testing::TestParamInfo<CallType>& info) {
Hungming Chenbb90ab32019-10-28 18:20:31 +08003752 switch (info.param) {
3753 case CallType::GETADDRINFO:
Hungming Chen63779052019-10-30 15:06:13 +08003754 return "GetAddrInfo";
Hungming Chenbb90ab32019-10-28 18:20:31 +08003755 case CallType::GETHOSTBYNAME:
Hungming Chen63779052019-10-30 15:06:13 +08003756 return "GetHostByName";
Hungming Chenbb90ab32019-10-28 18:20:31 +08003757 default:
Hungming Chen63779052019-10-30 15:06:13 +08003758 return "InvalidParameter"; // Should not happen.
Hungming Chenbb90ab32019-10-28 18:20:31 +08003759 }
Hungming Chenbb90ab32019-10-28 18:20:31 +08003760 });
3761
3762TEST_P(ResolverParameterizedTest, AuthoritySectionAndAdditionalSection) {
3763 // DNS response may have more information in authority section and additional section.
3764 // Currently, getanswer() of packages/modules/DnsResolver/getaddrinfo.cpp doesn't parse the
3765 // content of authority section and additional section. Test these sections if they crash
3766 // the resolver, just in case. See also RFC 1035 section 4.1.
3767 const auto& calltype = GetParam();
3768 test::DNSHeader header(kDefaultDnsHeader);
3769
3770 // Create a DNS response which has a authoritative nameserver record in authority
3771 // section and its relevant address record in additional section.
3772 //
3773 // Question
3774 // hello.example.com. IN A
3775 // Answer
3776 // hello.example.com. IN A 1.2.3.4
3777 // Authority:
3778 // hello.example.com. IN NS ns1.example.com.
3779 // Additional:
3780 // ns1.example.com. IN A 5.6.7.8
3781 //
3782 // A response may have only question, answer, and authority section. Current testing response
3783 // should be able to cover this condition.
3784
3785 // Question section.
3786 test::DNSQuestion question{
3787 .qname = {.name = kHelloExampleCom},
3788 .qtype = ns_type::ns_t_a,
3789 .qclass = ns_c_in,
3790 };
3791 header.questions.push_back(std::move(question));
3792
3793 // Answer section.
3794 test::DNSRecord recordAnswer{
3795 .name = {.name = kHelloExampleCom},
3796 .rtype = ns_type::ns_t_a,
3797 .rclass = ns_c_in,
3798 .ttl = 0, // no cache
3799 };
Hungming Chen63779052019-10-30 15:06:13 +08003800 EXPECT_TRUE(test::DNSResponder::fillRdata(kHelloExampleComAddrV4, recordAnswer));
Hungming Chenbb90ab32019-10-28 18:20:31 +08003801 header.answers.push_back(std::move(recordAnswer));
3802
3803 // Authority section.
3804 test::DNSRecord recordAuthority{
3805 .name = {.name = kHelloExampleCom},
3806 .rtype = ns_type::ns_t_ns,
3807 .rclass = ns_c_in,
3808 .ttl = 0, // no cache
3809 };
3810 EXPECT_TRUE(test::DNSResponder::fillRdata("ns1.example.com.", recordAuthority));
3811 header.authorities.push_back(std::move(recordAuthority));
3812
3813 // Additional section.
3814 test::DNSRecord recordAdditional{
3815 .name = {.name = "ns1.example.com."},
3816 .rtype = ns_type::ns_t_a,
3817 .rclass = ns_c_in,
3818 .ttl = 0, // no cache
3819 };
3820 EXPECT_TRUE(test::DNSResponder::fillRdata("5.6.7.8", recordAdditional));
3821 header.additionals.push_back(std::move(recordAdditional));
3822
3823 // Start DNS server.
3824 test::DNSResponder dns(test::DNSResponder::MappingType::DNS_HEADER);
3825 dns.addMappingDnsHeader(kHelloExampleCom, ns_type::ns_t_a, header);
3826 ASSERT_TRUE(dns.startServer());
3827 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3828 dns.clearQueries();
3829
3830 // Expect that get the address and the resolver doesn't crash.
Hungming Chen63779052019-10-30 15:06:13 +08003831 VerifyQueryHelloExampleComV4(dns, calltype);
3832}
3833
3834TEST_P(ResolverParameterizedTest, MessageCompression) {
3835 const auto& calltype = GetParam();
3836
3837 // The response with compressed domain name by a pointer. See RFC 1035 section 4.1.4.
3838 //
3839 // Ignoring the other fields of the message, the domain name of question section and answer
3840 // section are presented as:
3841 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3842 // 12 | 5 | h |
3843 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3844 // 14 | e | l |
3845 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3846 // 16 | l | o |
3847 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3848 // 18 | 7 | e |
3849 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3850 // 20 | x | a |
3851 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3852 // 22 | m | p |
3853 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3854 // 24 | l | e |
3855 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3856 // 26 | 3 | c |
3857 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3858 // 28 | o | m |
3859 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3860 // 30 | 0 | ... |
3861 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3862 //
3863 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3864 // 35 | 1 1| 12 |
3865 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3866 const std::vector<uint8_t> kResponseAPointer = {
3867 /* Header */
3868 0x00, 0x00, /* Transaction ID: 0x0000 */
3869 0x81, 0x80, /* Flags: qr rd ra */
3870 0x00, 0x01, /* Questions: 1 */
3871 0x00, 0x01, /* Answer RRs: 1 */
3872 0x00, 0x00, /* Authority RRs: 0 */
3873 0x00, 0x00, /* Additional RRs: 0 */
3874 /* Queries */
3875 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
3876 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
3877 0x00, 0x01, /* Type: A */
3878 0x00, 0x01, /* Class: IN */
3879 /* Answers */
3880 0xc0, 0x0c, /* Name: hello.example.com (a pointer) */
3881 0x00, 0x01, /* Type: A */
3882 0x00, 0x01, /* Class: IN */
3883 0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */
3884 0x00, 0x04, /* Data length: 4 */
3885 0x01, 0x02, 0x03, 0x04 /* Address: 1.2.3.4 */
3886 };
3887
3888 // The response with compressed domain name by a sequence of labels ending with a pointer. See
3889 // RFC 1035 section 4.1.4.
3890 //
3891 // Ignoring the other fields of the message, the domain name of question section and answer
3892 // section are presented as:
3893 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3894 // 12 | 5 | h |
3895 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3896 // 14 | e | l |
3897 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3898 // 16 | l | o |
3899 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3900 // 18 | 7 | e |
3901 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3902 // 20 | x | a |
3903 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3904 // 22 | m | p |
3905 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3906 // 24 | l | e |
3907 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3908 // 26 | 3 | c |
3909 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3910 // 28 | o | m |
3911 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3912 // 30 | 0 | ... |
3913 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3914 //
3915 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3916 // 35 | 5 | h |
3917 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3918 // 37 | e | l |
3919 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3920 // 39 | l | o |
3921 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3922 // 41 | 1 1| 18 |
3923 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3924 const std::vector<uint8_t> kResponseLabelEndingWithAPointer = {
3925 /* Header */
3926 0x00, 0x00, /* Transaction ID: 0x0000 */
3927 0x81, 0x80, /* Flags: qr rd ra */
3928 0x00, 0x01, /* Questions: 1 */
3929 0x00, 0x01, /* Answer RRs: 1 */
3930 0x00, 0x00, /* Authority RRs: 0 */
3931 0x00, 0x00, /* Additional RRs: 0 */
3932 /* Queries */
3933 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
3934 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
3935 0x00, 0x01, /* Type: A */
3936 0x00, 0x01, /* Class: IN */
3937 /* Answers */
3938 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0xc0,
3939 0x12, /* Name: hello.example.com (a label ending with a pointer) */
3940 0x00, 0x01, /* Type: A */
3941 0x00, 0x01, /* Class: IN */
3942 0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */
3943 0x00, 0x04, /* Data length: 4 */
3944 0x01, 0x02, 0x03, 0x04 /* Address: 1.2.3.4 */
3945 };
3946
3947 for (const auto& response : {kResponseAPointer, kResponseLabelEndingWithAPointer}) {
3948 SCOPED_TRACE(StringPrintf("Hex dump: %s", toHex(makeSlice(response)).c_str()));
3949
3950 test::DNSResponder dns(test::DNSResponder::MappingType::BINARY_PACKET);
3951 dns.addMappingBinaryPacket(kHelloExampleComQueryV4, response);
3952 StartDns(dns, {});
3953 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3954
3955 // Expect no cache because the TTL of testing responses are 0.
3956 VerifyQueryHelloExampleComV4(dns, calltype);
Hungming Chenbb90ab32019-10-28 18:20:31 +08003957 }
Mike Yu40e67072019-10-09 21:14:09 +08003958}