blob: dd0760aff4279bb451d7c8c17f6cac1f5d7eb7e1 [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:
Hungming Chen5bf09772019-04-25 11:16:13 +0800159 void SetUp() { mDnsClient.SetUp(); }
Hungming Chene8f970c2019-04-10 17:34:06 +0800160 void TearDown() { mDnsClient.TearDown(); }
nuccachena26cc2a2018-07-17 18:07:23 +0800161
Xiao Ma09b71022018-12-11 17:56:32 +0900162 void StartDns(test::DNSResponder& dns, const std::vector<DnsRecord>& records) {
163 for (const auto& r : records) {
164 dns.addMapping(r.host_name, r.type, r.addr);
165 }
166
167 ASSERT_TRUE(dns.startServer());
168 dns.clearQueries();
169 }
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900170
Hungming Chene8f970c2019-04-10 17:34:06 +0800171 bool WaitForNat64Prefix(ExpectNat64PrefixStatus status,
172 std::chrono::milliseconds timeout = std::chrono::milliseconds(1000)) {
Hungming Chen5bf09772019-04-25 11:16:13 +0800173 return sDnsMetricsListener->waitForNat64Prefix(status, timeout);
Hungming Chene8f970c2019-04-10 17:34:06 +0800174 }
175
Mike Yu724f77d2019-08-16 11:14:50 +0800176 bool WaitForPrivateDnsValidation(std::string serverAddr, bool validated) {
177 return sDnsMetricsListener->waitForPrivateDnsValidation(serverAddr, validated);
178 }
179
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900180 DnsResponderClient mDnsClient;
Xiao Ma09b71022018-12-11 17:56:32 +0900181
Hungming Chen5bf09772019-04-25 11:16:13 +0800182 // Use a shared static DNS listener for all tests to avoid registering lots of listeners
183 // which may be released late until process terminated. Currently, registered DNS listener
184 // is removed by binder death notification which is fired when the process hosting an
185 // IBinder has gone away. If every test in ResolverTest registers its DNS listener, Netd
186 // may temporarily hold lots of dead listeners until the unit test process terminates.
187 // TODO: Perhaps add an unregistering listener binder call or fork a listener process which
188 // could be terminated earlier.
Luke Huangf8215372019-11-22 11:53:41 +0800189 static std::shared_ptr<DnsMetricsListener>
190 sDnsMetricsListener; // Initialized in SetUpTestCase.
Hungming Chen5bf09772019-04-25 11:16:13 +0800191
192 // Use a shared static death recipient to monitor the service death. The static death
193 // recipient could monitor the death not only during the test but also between tests.
Luke Huangf8215372019-11-22 11:53:41 +0800194 static AIBinder_DeathRecipient* sResolvDeathRecipient; // Initialized in SetUpTestCase.
Ken Chenb9fa2062018-11-13 21:51:13 +0800195};
196
Hungming Chen5bf09772019-04-25 11:16:13 +0800197// Initialize static member of class.
Luke Huangf8215372019-11-22 11:53:41 +0800198std::shared_ptr<DnsMetricsListener> ResolverTest::sDnsMetricsListener;
199AIBinder_DeathRecipient* ResolverTest::sResolvDeathRecipient;
Hungming Chen5bf09772019-04-25 11:16:13 +0800200
Ken Chenb9fa2062018-11-13 21:51:13 +0800201TEST_F(ResolverTest, GetHostByName) {
Xiao Ma09b71022018-12-11 17:56:32 +0900202 constexpr char nonexistent_host_name[] = "nonexistent.example.com.";
203
204 test::DNSResponder dns;
205 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.3"}});
206 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800207
208 const hostent* result;
Ken Chenb9fa2062018-11-13 21:51:13 +0800209 result = gethostbyname("nonexistent");
210 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, nonexistent_host_name));
211 ASSERT_TRUE(result == nullptr);
212 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
213
214 dns.clearQueries();
215 result = gethostbyname("hello");
Xiao Ma09b71022018-12-11 17:56:32 +0900216 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
Ken Chenb9fa2062018-11-13 21:51:13 +0800217 ASSERT_FALSE(result == nullptr);
218 ASSERT_EQ(4, result->h_length);
219 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
220 EXPECT_EQ("1.2.3.3", ToString(result));
221 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800222}
223
lifr4e4a2e02019-01-29 16:53:51 +0800224TEST_F(ResolverTest, GetHostByName_cnames) {
225 constexpr char host_name[] = "host.example.com.";
226 size_t cnamecount = 0;
227 test::DNSResponder dns;
228
229 const std::vector<DnsRecord> records = {
230 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
231 {"a.example.com.", ns_type::ns_t_cname, "b.example.com."},
232 {"b.example.com.", ns_type::ns_t_cname, "c.example.com."},
233 {"c.example.com.", ns_type::ns_t_cname, "d.example.com."},
234 {"d.example.com.", ns_type::ns_t_cname, "e.example.com."},
235 {"e.example.com.", ns_type::ns_t_cname, host_name},
236 {host_name, ns_type::ns_t_a, "1.2.3.3"},
237 {host_name, ns_type::ns_t_aaaa, "2001:db8::42"},
238 };
239 StartDns(dns, records);
240 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
241
242 // using gethostbyname2() to resolve ipv4 hello.example.com. to 1.2.3.3
243 // Ensure the v4 address and cnames are correct
244 const hostent* result;
245 result = gethostbyname2("hello", AF_INET);
246 ASSERT_FALSE(result == nullptr);
247
248 for (int i = 0; result != nullptr && result->h_aliases[i] != nullptr; i++) {
249 std::string domain_name = records[i].host_name.substr(0, records[i].host_name.size() - 1);
250 EXPECT_EQ(result->h_aliases[i], domain_name);
251 cnamecount++;
252 }
253 // The size of "Non-cname type" record in DNS records is 2
254 ASSERT_EQ(cnamecount, records.size() - 2);
255 ASSERT_EQ(4, result->h_length);
256 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
257 EXPECT_EQ("1.2.3.3", ToString(result));
258 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
259 EXPECT_EQ(1U, dns.queries().size()) << dns.dumpQueries();
260
261 // using gethostbyname2() to resolve ipv6 hello.example.com. to 2001:db8::42
262 // Ensure the v6 address and cnames are correct
263 cnamecount = 0;
264 dns.clearQueries();
265 result = gethostbyname2("hello", AF_INET6);
266 for (unsigned i = 0; result != nullptr && result->h_aliases[i] != nullptr; i++) {
267 std::string domain_name = records[i].host_name.substr(0, records[i].host_name.size() - 1);
268 EXPECT_EQ(result->h_aliases[i], domain_name);
269 cnamecount++;
270 }
271 // The size of "Non-cname type" DNS record in records is 2
272 ASSERT_EQ(cnamecount, records.size() - 2);
273 ASSERT_FALSE(result == nullptr);
274 ASSERT_EQ(16, result->h_length);
275 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
276 EXPECT_EQ("2001:db8::42", ToString(result));
277 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
278}
279
280TEST_F(ResolverTest, GetHostByName_cnamesInfiniteLoop) {
281 test::DNSResponder dns;
282 const std::vector<DnsRecord> records = {
283 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
284 {"a.example.com.", ns_type::ns_t_cname, kHelloExampleCom},
285 };
286 StartDns(dns, records);
287 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
288
289 const hostent* result;
290 result = gethostbyname2("hello", AF_INET);
291 ASSERT_TRUE(result == nullptr);
292
293 dns.clearQueries();
294 result = gethostbyname2("hello", AF_INET6);
295 ASSERT_TRUE(result == nullptr);
296}
297
Ken Chenb9fa2062018-11-13 21:51:13 +0800298TEST_F(ResolverTest, GetHostByName_localhost) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800299 constexpr char name_camelcase[] = "LocalHost";
Ken Chenb9fa2062018-11-13 21:51:13 +0800300 constexpr char name_ip6_dot[] = "ip6-localhost.";
301 constexpr char name_ip6_fqdn[] = "ip6-localhost.example.com.";
302
303 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma09b71022018-12-11 17:56:32 +0900304 test::DNSResponder dns;
305 StartDns(dns, {});
306 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800307
308 // Expect no DNS queries; localhost is resolved via /etc/hosts
Xiao Ma09b71022018-12-11 17:56:32 +0900309 const hostent* result = gethostbyname(kLocalHost);
Ken Chenb9fa2062018-11-13 21:51:13 +0800310 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
311 ASSERT_FALSE(result == nullptr);
312 ASSERT_EQ(4, result->h_length);
313 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900314 EXPECT_EQ(kLocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800315 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
316
317 // Ensure the hosts file resolver ignores case of hostnames
318 result = gethostbyname(name_camelcase);
319 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
320 ASSERT_FALSE(result == nullptr);
321 ASSERT_EQ(4, result->h_length);
322 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900323 EXPECT_EQ(kLocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800324 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
325
326 // The hosts file also contains ip6-localhost, but gethostbyname() won't
chenbruce018fdb22019-06-12 18:08:04 +0800327 // return it. This would be easy to
Ken Chenb9fa2062018-11-13 21:51:13 +0800328 // change, but there's no point in changing the legacy behavior; new code
329 // should be calling getaddrinfo() anyway.
330 // So we check the legacy behavior, which results in amusing A-record
331 // lookups for ip6-localhost, with and without search domains appended.
332 dns.clearQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900333 result = gethostbyname(kIp6LocalHost);
Sehee Parkbbca0202018-11-16 10:53:16 +0900334 EXPECT_EQ(2U, dns.queries().size()) << dns.dumpQueries();
335 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, name_ip6_dot)) << dns.dumpQueries();
336 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, name_ip6_fqdn)) << dns.dumpQueries();
Ken Chenb9fa2062018-11-13 21:51:13 +0800337 ASSERT_TRUE(result == nullptr);
338
339 // Finally, use gethostbyname2() to resolve ip6-localhost to ::1 from
340 // the hosts file.
341 dns.clearQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900342 result = gethostbyname2(kIp6LocalHost, AF_INET6);
Ken Chenb9fa2062018-11-13 21:51:13 +0800343 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
344 ASSERT_FALSE(result == nullptr);
345 ASSERT_EQ(16, result->h_length);
346 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900347 EXPECT_EQ(kIp6LocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800348 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800349}
350
351TEST_F(ResolverTest, GetHostByName_numeric) {
352 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma09b71022018-12-11 17:56:32 +0900353 test::DNSResponder dns;
354 StartDns(dns, {});
355 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800356
357 // Numeric v4 address: expect no DNS queries
358 constexpr char numeric_v4[] = "192.168.0.1";
Ken Chenb9fa2062018-11-13 21:51:13 +0800359 const hostent* result = gethostbyname(numeric_v4);
Sehee Parkbbca0202018-11-16 10:53:16 +0900360 EXPECT_EQ(0U, dns.queries().size());
Ken Chenb9fa2062018-11-13 21:51:13 +0800361 ASSERT_FALSE(result == nullptr);
362 ASSERT_EQ(4, result->h_length); // v4
363 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
364 EXPECT_EQ(numeric_v4, ToString(result));
365 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
366
367 // gethostbyname() recognizes a v6 address, and fails with no DNS queries
368 constexpr char numeric_v6[] = "2001:db8::42";
369 dns.clearQueries();
370 result = gethostbyname(numeric_v6);
Sehee Parkbbca0202018-11-16 10:53:16 +0900371 EXPECT_EQ(0U, dns.queries().size());
Ken Chenb9fa2062018-11-13 21:51:13 +0800372 EXPECT_TRUE(result == nullptr);
373
374 // Numeric v6 address with gethostbyname2(): succeeds with no DNS queries
375 dns.clearQueries();
376 result = gethostbyname2(numeric_v6, AF_INET6);
Sehee Parkbbca0202018-11-16 10:53:16 +0900377 EXPECT_EQ(0U, dns.queries().size());
Ken Chenb9fa2062018-11-13 21:51:13 +0800378 ASSERT_FALSE(result == nullptr);
379 ASSERT_EQ(16, result->h_length); // v6
380 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
381 EXPECT_EQ(numeric_v6, ToString(result));
382 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
383
384 // Numeric v6 address with scope work with getaddrinfo(),
385 // but gethostbyname2() does not understand them; it issues two dns
386 // queries, then fails. This hardly ever happens, there's no point
387 // in fixing this. This test simply verifies the current (bogus)
388 // behavior to avoid further regressions (like crashes, or leaks).
389 constexpr char numeric_v6_scope[] = "fe80::1%lo";
390 dns.clearQueries();
391 result = gethostbyname2(numeric_v6_scope, AF_INET6);
Sehee Parkbbca0202018-11-16 10:53:16 +0900392 EXPECT_EQ(2U, dns.queries().size()); // OUCH!
Ken Chenb9fa2062018-11-13 21:51:13 +0800393 ASSERT_TRUE(result == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800394}
395
396TEST_F(ResolverTest, BinderSerialization) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800397 std::vector<int> params_offsets = {
Luke Huang5bd827c2019-03-14 16:10:04 +0800398 IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY,
399 IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD,
400 IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES,
401 IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES,
402 IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC,
403 IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT,
Ken Chenb9fa2062018-11-13 21:51:13 +0800404 };
Bernie Innocentib102dd22018-12-04 14:57:48 +0900405 const int size = static_cast<int>(params_offsets.size());
Luke Huang5bd827c2019-03-14 16:10:04 +0800406 EXPECT_EQ(size, IDnsResolver::RESOLVER_PARAMS_COUNT);
Ken Chenb9fa2062018-11-13 21:51:13 +0800407 std::sort(params_offsets.begin(), params_offsets.end());
Bernie Innocentib102dd22018-12-04 14:57:48 +0900408 for (int i = 0; i < size; ++i) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800409 EXPECT_EQ(params_offsets[i], i);
410 }
411}
412
413TEST_F(ResolverTest, GetHostByName_Binder) {
Luke Huangf8215372019-11-22 11:53:41 +0800414 std::vector<std::string> domains = {"example.com"};
Ken Chenb9fa2062018-11-13 21:51:13 +0800415 std::vector<std::unique_ptr<test::DNSResponder>> dns;
416 std::vector<std::string> servers;
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900417 std::vector<DnsResponderClient::Mapping> mappings;
418 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupMappings(1, domains, &mappings));
419 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupDNSServers(4, mappings, &dns, &servers));
Ken Chenb9fa2062018-11-13 21:51:13 +0800420 ASSERT_EQ(1U, mappings.size());
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900421 const DnsResponderClient::Mapping& mapping = mappings[0];
Ken Chenb9fa2062018-11-13 21:51:13 +0800422
Xiao Ma09b71022018-12-11 17:56:32 +0900423 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains, kDefaultParams));
Ken Chenb9fa2062018-11-13 21:51:13 +0800424
425 const hostent* result = gethostbyname(mapping.host.c_str());
Bernie Innocentib102dd22018-12-04 14:57:48 +0900426 const size_t total_queries =
Luke Huangfde82482019-06-04 01:04:53 +0800427 std::accumulate(dns.begin(), dns.end(), 0, [&mapping](size_t total, auto& d) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800428 return total + GetNumQueriesForType(*d, ns_type::ns_t_a, mapping.entry.c_str());
429 });
430
431 EXPECT_LE(1U, total_queries);
432 ASSERT_FALSE(result == nullptr);
433 ASSERT_EQ(4, result->h_length);
434 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
435 EXPECT_EQ(mapping.ip4, ToString(result));
436 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
437
438 std::vector<std::string> res_servers;
439 std::vector<std::string> res_domains;
Mike Yu0a1c53d2018-11-26 13:26:21 +0900440 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900441 res_params res_params;
Ken Chenb9fa2062018-11-13 21:51:13 +0800442 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +0800443 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800444 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
445 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
446 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chenb9fa2062018-11-13 21:51:13 +0800447 EXPECT_EQ(servers.size(), res_servers.size());
448 EXPECT_EQ(domains.size(), res_domains.size());
Mike Yu0a1c53d2018-11-26 13:26:21 +0900449 EXPECT_EQ(0U, res_tls_servers.size());
Luke Huang5bd827c2019-03-14 16:10:04 +0800450 ASSERT_EQ(static_cast<size_t>(IDnsResolver::RESOLVER_PARAMS_COUNT), kDefaultParams.size());
451 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY],
452 res_params.sample_validity);
453 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD],
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900454 res_params.success_threshold);
Luke Huang5bd827c2019-03-14 16:10:04 +0800455 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
456 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
457 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
Ken Chenb9fa2062018-11-13 21:51:13 +0800458 res_params.base_timeout_msec);
459 EXPECT_EQ(servers.size(), res_stats.size());
460
Bernie Innocenti0c067e42019-04-01 15:33:16 +0900461 EXPECT_THAT(res_servers, testing::UnorderedElementsAreArray(servers));
462 EXPECT_THAT(res_domains, testing::UnorderedElementsAreArray(domains));
Ken Chenb9fa2062018-11-13 21:51:13 +0800463}
464
465TEST_F(ResolverTest, GetAddrInfo) {
Xiao Ma09b71022018-12-11 17:56:32 +0900466 constexpr char listen_addr[] = "127.0.0.4";
467 constexpr char listen_addr2[] = "127.0.0.5";
468 constexpr char host_name[] = "howdy.example.com.";
Ken Chenb9fa2062018-11-13 21:51:13 +0800469
Xiao Ma09b71022018-12-11 17:56:32 +0900470 const std::vector<DnsRecord> records = {
471 {host_name, ns_type::ns_t_a, "1.2.3.4"},
472 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
473 };
474 test::DNSResponder dns(listen_addr);
475 test::DNSResponder dns2(listen_addr2);
476 StartDns(dns, records);
477 StartDns(dns2, records);
Ken Chenb9fa2062018-11-13 21:51:13 +0800478
Xiao Ma09b71022018-12-11 17:56:32 +0900479 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr}));
Ken Chenb9fa2062018-11-13 21:51:13 +0800480 dns.clearQueries();
481 dns2.clearQueries();
482
483 ScopedAddrinfo result = safe_getaddrinfo("howdy", nullptr, nullptr);
484 EXPECT_TRUE(result != nullptr);
485 size_t found = GetNumQueries(dns, host_name);
486 EXPECT_LE(1U, found);
487 // Could be A or AAAA
488 std::string result_str = ToString(result);
489 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
Luke Huangf8215372019-11-22 11:53:41 +0800490 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +0800491
492 // Verify that the name is cached.
493 size_t old_found = found;
494 result = safe_getaddrinfo("howdy", nullptr, nullptr);
495 EXPECT_TRUE(result != nullptr);
496 found = GetNumQueries(dns, host_name);
497 EXPECT_LE(1U, found);
498 EXPECT_EQ(old_found, found);
499 result_str = ToString(result);
Luke Huangf8215372019-11-22 11:53:41 +0800500 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4") << result_str;
Ken Chenb9fa2062018-11-13 21:51:13 +0800501
502 // Change the DNS resolver, ensure that queries are still cached.
Xiao Ma09b71022018-12-11 17:56:32 +0900503 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr2}));
Ken Chenb9fa2062018-11-13 21:51:13 +0800504 dns.clearQueries();
505 dns2.clearQueries();
506
507 result = safe_getaddrinfo("howdy", nullptr, nullptr);
508 EXPECT_TRUE(result != nullptr);
509 found = GetNumQueries(dns, host_name);
510 size_t found2 = GetNumQueries(dns2, host_name);
511 EXPECT_EQ(0U, found);
512 EXPECT_LE(0U, found2);
513
514 // Could be A or AAAA
515 result_str = ToString(result);
516 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
Luke Huangf8215372019-11-22 11:53:41 +0800517 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +0800518}
519
520TEST_F(ResolverTest, GetAddrInfoV4) {
Xiao Ma09b71022018-12-11 17:56:32 +0900521 test::DNSResponder dns;
522 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.5"}});
523 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800524
Xiao Ma09b71022018-12-11 17:56:32 +0900525 const addrinfo hints = {.ai_family = AF_INET};
526 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
Ken Chenb9fa2062018-11-13 21:51:13 +0800527 EXPECT_TRUE(result != nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900528 EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
Ken Chenb9fa2062018-11-13 21:51:13 +0800529 EXPECT_EQ("1.2.3.5", ToString(result));
530}
531
532TEST_F(ResolverTest, GetAddrInfo_localhost) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800533 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma09b71022018-12-11 17:56:32 +0900534 test::DNSResponder dns;
535 StartDns(dns, {});
536 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800537
Xiao Ma09b71022018-12-11 17:56:32 +0900538 ScopedAddrinfo result = safe_getaddrinfo(kLocalHost, nullptr, nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800539 EXPECT_TRUE(result != nullptr);
540 // Expect no DNS queries; localhost is resolved via /etc/hosts
541 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900542 EXPECT_EQ(kLocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800543
Xiao Ma09b71022018-12-11 17:56:32 +0900544 result = safe_getaddrinfo(kIp6LocalHost, nullptr, nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800545 EXPECT_TRUE(result != nullptr);
546 // Expect no DNS queries; ip6-localhost is resolved via /etc/hosts
547 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900548 EXPECT_EQ(kIp6LocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800549}
550
Luke Huangd8ac4752019-06-18 17:05:47 +0800551TEST_F(ResolverTest, GetAddrInfo_InvalidSocketType) {
552 test::DNSResponder dns;
553 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.5"}});
554 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
555
556 // TODO: Test other invalid socket types.
557 const addrinfo hints = {
558 .ai_family = AF_UNSPEC,
Luke Huangd8ac4752019-06-18 17:05:47 +0800559 .ai_socktype = SOCK_PACKET,
Nick Desaulnierscd6395a2019-10-11 09:15:24 -0700560 .ai_protocol = ANY,
Luke Huangd8ac4752019-06-18 17:05:47 +0800561 };
562 addrinfo* result = nullptr;
563 // This is a valid hint, but the query won't be sent because the socket type is
564 // not supported.
565 EXPECT_EQ(EAI_NODATA, getaddrinfo("hello", nullptr, &hints, &result));
566 ScopedAddrinfo result_cleanup(result);
567 EXPECT_EQ(nullptr, result);
568}
569
Ken Chen92bed612018-12-22 21:46:55 +0800570// Verify if the resolver correctly handle multiple queries simultaneously
571// step 1: set dns server#1 into deferred responding mode.
572// step 2: thread#1 query "hello.example.com." --> resolver send query to server#1.
573// step 3: thread#2 query "hello.example.com." --> resolver hold the request and wait for
574// response of previous pending query sent by thread#1.
575// step 4: thread#3 query "konbanha.example.com." --> resolver send query to server#3. Server
576// respond to resolver immediately.
577// step 5: check if server#1 get 1 query by thread#1, server#2 get 0 query, server#3 get 1 query.
578// step 6: resume dns server#1 to respond dns query in step#2.
579// step 7: thread#1 and #2 should get returned from DNS query after step#6. Also, check the
580// number of queries in server#2 is 0 to ensure thread#2 does not wake up unexpectedly
581// before signaled by thread#1.
582TEST_F(ResolverTest, GetAddrInfoV4_deferred_resp) {
583 const char* listen_addr1 = "127.0.0.9";
584 const char* listen_addr2 = "127.0.0.10";
585 const char* listen_addr3 = "127.0.0.11";
586 const char* listen_srv = "53";
587 const char* host_name_deferred = "hello.example.com.";
588 const char* host_name_normal = "konbanha.example.com.";
Mike Yufc125e42019-05-15 20:41:28 +0800589 test::DNSResponder dns1(listen_addr1, listen_srv, ns_rcode::ns_r_servfail);
590 test::DNSResponder dns2(listen_addr2, listen_srv, ns_rcode::ns_r_servfail);
591 test::DNSResponder dns3(listen_addr3, listen_srv, ns_rcode::ns_r_servfail);
Ken Chen92bed612018-12-22 21:46:55 +0800592 dns1.addMapping(host_name_deferred, ns_type::ns_t_a, "1.2.3.4");
593 dns2.addMapping(host_name_deferred, ns_type::ns_t_a, "1.2.3.4");
594 dns3.addMapping(host_name_normal, ns_type::ns_t_a, "1.2.3.5");
595 ASSERT_TRUE(dns1.startServer());
596 ASSERT_TRUE(dns2.startServer());
597 ASSERT_TRUE(dns3.startServer());
598 const std::vector<std::string> servers_for_t1 = {listen_addr1};
599 const std::vector<std::string> servers_for_t2 = {listen_addr2};
600 const std::vector<std::string> servers_for_t3 = {listen_addr3};
601 addrinfo hints = {.ai_family = AF_INET};
602 const std::vector<int> params = {300, 25, 8, 8, 5000};
603 bool t3_task_done = false;
604
605 dns1.setDeferredResp(true);
606 std::thread t1([&, this]() {
607 ASSERT_TRUE(
608 mDnsClient.SetResolversForNetwork(servers_for_t1, kDefaultSearchDomains, params));
609 ScopedAddrinfo result = safe_getaddrinfo(host_name_deferred, nullptr, &hints);
610 // t3's dns query should got returned first
611 EXPECT_TRUE(t3_task_done);
612 EXPECT_EQ(1U, GetNumQueries(dns1, host_name_deferred));
613 EXPECT_TRUE(result != nullptr);
614 EXPECT_EQ("1.2.3.4", ToString(result));
615 });
616
617 // ensuring t1 and t2 handler functions are processed in order
618 usleep(100 * 1000);
619 std::thread t2([&, this]() {
620 ASSERT_TRUE(
621 mDnsClient.SetResolversForNetwork(servers_for_t2, kDefaultSearchDomains, params));
622 ScopedAddrinfo result = safe_getaddrinfo(host_name_deferred, nullptr, &hints);
623 EXPECT_TRUE(t3_task_done);
624 EXPECT_EQ(0U, GetNumQueries(dns2, host_name_deferred));
625 EXPECT_TRUE(result != nullptr);
626 EXPECT_EQ("1.2.3.4", ToString(result));
627
628 std::vector<std::string> res_servers;
629 std::vector<std::string> res_domains;
630 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900631 res_params res_params;
Ken Chen92bed612018-12-22 21:46:55 +0800632 std::vector<ResolverStats> res_stats;
633 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800634 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
635 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains,
636 &res_tls_servers, &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chen92bed612018-12-22 21:46:55 +0800637 EXPECT_EQ(0, wait_for_pending_req_timeout_count);
638 });
639
640 // ensuring t2 and t3 handler functions are processed in order
641 usleep(100 * 1000);
642 std::thread t3([&, this]() {
643 ASSERT_TRUE(
644 mDnsClient.SetResolversForNetwork(servers_for_t3, kDefaultSearchDomains, params));
645 ScopedAddrinfo result = safe_getaddrinfo(host_name_normal, nullptr, &hints);
646 EXPECT_EQ(1U, GetNumQueries(dns1, host_name_deferred));
647 EXPECT_EQ(0U, GetNumQueries(dns2, host_name_deferred));
648 EXPECT_EQ(1U, GetNumQueries(dns3, host_name_normal));
649 EXPECT_TRUE(result != nullptr);
650 EXPECT_EQ("1.2.3.5", ToString(result));
651
652 t3_task_done = true;
653 dns1.setDeferredResp(false);
654 });
655 t3.join();
656 t1.join();
657 t2.join();
658}
659
lifr4e4a2e02019-01-29 16:53:51 +0800660TEST_F(ResolverTest, GetAddrInfo_cnames) {
661 constexpr char host_name[] = "host.example.com.";
662 test::DNSResponder dns;
663 const std::vector<DnsRecord> records = {
664 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
665 {"a.example.com.", ns_type::ns_t_cname, "b.example.com."},
666 {"b.example.com.", ns_type::ns_t_cname, "c.example.com."},
667 {"c.example.com.", ns_type::ns_t_cname, "d.example.com."},
668 {"d.example.com.", ns_type::ns_t_cname, "e.example.com."},
669 {"e.example.com.", ns_type::ns_t_cname, host_name},
670 {host_name, ns_type::ns_t_a, "1.2.3.3"},
671 {host_name, ns_type::ns_t_aaaa, "2001:db8::42"},
672 };
673 StartDns(dns, records);
674 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
675
676 addrinfo hints = {.ai_family = AF_INET};
677 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
678 EXPECT_TRUE(result != nullptr);
679 EXPECT_EQ("1.2.3.3", ToString(result));
680
681 dns.clearQueries();
682 hints = {.ai_family = AF_INET6};
683 result = safe_getaddrinfo("hello", nullptr, &hints);
684 EXPECT_TRUE(result != nullptr);
685 EXPECT_EQ("2001:db8::42", ToString(result));
686}
687
688TEST_F(ResolverTest, GetAddrInfo_cnamesNoIpAddress) {
689 test::DNSResponder dns;
690 const std::vector<DnsRecord> records = {
691 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
692 };
693 StartDns(dns, records);
694 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
695
696 addrinfo hints = {.ai_family = AF_INET};
697 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
698 EXPECT_TRUE(result == nullptr);
699
700 dns.clearQueries();
701 hints = {.ai_family = AF_INET6};
702 result = safe_getaddrinfo("hello", nullptr, &hints);
703 EXPECT_TRUE(result == nullptr);
704}
705
706TEST_F(ResolverTest, GetAddrInfo_cnamesIllegalRdata) {
707 test::DNSResponder dns;
708 const std::vector<DnsRecord> records = {
709 {kHelloExampleCom, ns_type::ns_t_cname, ".!#?"},
710 };
711 StartDns(dns, records);
712 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
713
714 addrinfo hints = {.ai_family = AF_INET};
715 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
716 EXPECT_TRUE(result == nullptr);
717
718 dns.clearQueries();
719 hints = {.ai_family = AF_INET6};
720 result = safe_getaddrinfo("hello", nullptr, &hints);
721 EXPECT_TRUE(result == nullptr);
722}
723
Ken Chenb9fa2062018-11-13 21:51:13 +0800724TEST_F(ResolverTest, MultidomainResolution) {
Xiao Ma09b71022018-12-11 17:56:32 +0900725 constexpr char host_name[] = "nihao.example2.com.";
Luke Huangf8215372019-11-22 11:53:41 +0800726 std::vector<std::string> searchDomains = {"example1.com", "example2.com", "example3.com"};
Ken Chenb9fa2062018-11-13 21:51:13 +0800727
Xiao Ma09b71022018-12-11 17:56:32 +0900728 test::DNSResponder dns("127.0.0.6");
729 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.3"}});
730 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({"127.0.0.6"}, searchDomains));
731
Ken Chenb9fa2062018-11-13 21:51:13 +0800732 const hostent* result = gethostbyname("nihao");
Xiao Ma09b71022018-12-11 17:56:32 +0900733
Ken Chenb9fa2062018-11-13 21:51:13 +0800734 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
735 ASSERT_FALSE(result == nullptr);
736 ASSERT_EQ(4, result->h_length);
737 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
738 EXPECT_EQ("1.2.3.3", ToString(result));
739 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800740}
741
742TEST_F(ResolverTest, GetAddrInfoV6_numeric) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800743 constexpr char host_name[] = "ohayou.example.com.";
744 constexpr char numeric_addr[] = "fe80::1%lo";
745
Xiao Ma09b71022018-12-11 17:56:32 +0900746 test::DNSResponder dns;
Ken Chenb9fa2062018-11-13 21:51:13 +0800747 dns.setResponseProbability(0.0);
Xiao Ma09b71022018-12-11 17:56:32 +0900748 StartDns(dns, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
749 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800750
751 addrinfo hints = {.ai_family = AF_INET6};
752 ScopedAddrinfo result = safe_getaddrinfo(numeric_addr, nullptr, &hints);
753 EXPECT_TRUE(result != nullptr);
754 EXPECT_EQ(numeric_addr, ToString(result));
755 EXPECT_TRUE(dns.queries().empty()); // Ensure no DNS queries were sent out
756
757 // Now try a non-numeric hostname query with the AI_NUMERICHOST flag set.
758 // We should fail without sending out a DNS query.
759 hints.ai_flags |= AI_NUMERICHOST;
760 result = safe_getaddrinfo(host_name, nullptr, &hints);
761 EXPECT_TRUE(result == nullptr);
762 EXPECT_TRUE(dns.queries().empty()); // Ensure no DNS queries were sent out
763}
764
765TEST_F(ResolverTest, GetAddrInfoV6_failing) {
Xiao Ma09b71022018-12-11 17:56:32 +0900766 constexpr char listen_addr0[] = "127.0.0.7";
767 constexpr char listen_addr1[] = "127.0.0.8";
Ken Chenb9fa2062018-11-13 21:51:13 +0800768 const char* host_name = "ohayou.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +0900769
770 test::DNSResponder dns0(listen_addr0);
771 test::DNSResponder dns1(listen_addr1);
Ken Chenb9fa2062018-11-13 21:51:13 +0800772 dns0.setResponseProbability(0.0);
Xiao Ma09b71022018-12-11 17:56:32 +0900773 StartDns(dns0, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
774 StartDns(dns1, {{host_name, ns_type::ns_t_aaaa, "2001:db8::6"}});
775
Luke Huangf8215372019-11-22 11:53:41 +0800776 std::vector<std::string> servers = {listen_addr0, listen_addr1};
Ken Chenb9fa2062018-11-13 21:51:13 +0800777 // <sample validity in s> <success threshold in percent> <min samples> <max samples>
778 int sample_count = 8;
Luke Huangf8215372019-11-22 11:53:41 +0800779 const std::vector<int> params = {300, 25, sample_count, sample_count};
Xiao Ma09b71022018-12-11 17:56:32 +0900780 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, kDefaultSearchDomains, params));
Ken Chenb9fa2062018-11-13 21:51:13 +0800781
782 // Repeatedly perform resolutions for non-existing domains until MAXNSSAMPLES resolutions have
783 // reached the dns0, which is set to fail. No more requests should then arrive at that server
784 // for the next sample_lifetime seconds.
785 // TODO: This approach is implementation-dependent, change once metrics reporting is available.
Xiao Ma09b71022018-12-11 17:56:32 +0900786 const addrinfo hints = {.ai_family = AF_INET6};
Bernie Innocentib102dd22018-12-04 14:57:48 +0900787 for (int i = 0; i < sample_count; ++i) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800788 std::string domain = StringPrintf("nonexistent%d", i);
789 ScopedAddrinfo result = safe_getaddrinfo(domain.c_str(), nullptr, &hints);
790 }
791 // Due to 100% errors for all possible samples, the server should be ignored from now on and
792 // only the second one used for all following queries, until NSSAMPLE_VALIDITY is reached.
793 dns0.clearQueries();
794 dns1.clearQueries();
795 ScopedAddrinfo result = safe_getaddrinfo("ohayou", nullptr, &hints);
796 EXPECT_TRUE(result != nullptr);
797 EXPECT_EQ(0U, GetNumQueries(dns0, host_name));
798 EXPECT_EQ(1U, GetNumQueries(dns1, host_name));
799}
800
801TEST_F(ResolverTest, GetAddrInfoV6_nonresponsive) {
Xiao Ma09b71022018-12-11 17:56:32 +0900802 constexpr char listen_addr0[] = "127.0.0.7";
803 constexpr char listen_addr1[] = "127.0.0.8";
804 constexpr char listen_srv[] = "53";
805 constexpr char host_name1[] = "ohayou.example.com.";
806 constexpr char host_name2[] = "ciao.example.com.";
Luke Huang483cf332019-06-03 17:24:51 +0800807 const std::vector<std::string> defaultSearchDomain = {"example.com"};
808 // The minimal timeout is 1000ms, so we can't decrease timeout
809 // So reduce retry count.
810 const std::vector<int> reduceRetryParams = {
811 300, // sample validity in seconds
812 25, // success threshod in percent
813 8, 8, // {MIN,MAX}_SAMPLES
814 1000, // BASE_TIMEOUT_MSEC
815 1, // retry count
816 };
Xiao Ma09b71022018-12-11 17:56:32 +0900817 const std::vector<DnsRecord> records0 = {
818 {host_name1, ns_type::ns_t_aaaa, "2001:db8::5"},
819 {host_name2, ns_type::ns_t_aaaa, "2001:db8::5"},
820 };
821 const std::vector<DnsRecord> records1 = {
822 {host_name1, ns_type::ns_t_aaaa, "2001:db8::6"},
823 {host_name2, ns_type::ns_t_aaaa, "2001:db8::6"},
824 };
Ken Chenb9fa2062018-11-13 21:51:13 +0800825
826 // dns0 does not respond with 100% probability, while
827 // dns1 responds normally, at least initially.
Mike Yufc125e42019-05-15 20:41:28 +0800828 test::DNSResponder dns0(listen_addr0, listen_srv, static_cast<ns_rcode>(-1));
829 test::DNSResponder dns1(listen_addr1, listen_srv, static_cast<ns_rcode>(-1));
Ken Chenb9fa2062018-11-13 21:51:13 +0800830 dns0.setResponseProbability(0.0);
Xiao Ma09b71022018-12-11 17:56:32 +0900831 StartDns(dns0, records0);
832 StartDns(dns1, records1);
Luke Huang483cf332019-06-03 17:24:51 +0800833 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr0, listen_addr1}, defaultSearchDomain,
834 reduceRetryParams));
Ken Chenb9fa2062018-11-13 21:51:13 +0800835
Luke Huang483cf332019-06-03 17:24:51 +0800836 // Specify ai_socktype to make getaddrinfo will only query 1 time
837 const addrinfo hints = {.ai_family = AF_INET6, .ai_socktype = SOCK_STREAM};
Ken Chenb9fa2062018-11-13 21:51:13 +0800838
839 // dns0 will ignore the request, and we'll fallback to dns1 after the first
840 // retry.
841 ScopedAddrinfo result = safe_getaddrinfo(host_name1, nullptr, &hints);
842 EXPECT_TRUE(result != nullptr);
843 EXPECT_EQ(1U, GetNumQueries(dns0, host_name1));
844 EXPECT_EQ(1U, GetNumQueries(dns1, host_name1));
845
846 // Now make dns1 also ignore 100% requests... The resolve should alternate
Luke Huang483cf332019-06-03 17:24:51 +0800847 // queries between the nameservers and fail
Ken Chenb9fa2062018-11-13 21:51:13 +0800848 dns1.setResponseProbability(0.0);
849 addrinfo* result2 = nullptr;
850 EXPECT_EQ(EAI_NODATA, getaddrinfo(host_name2, nullptr, &hints, &result2));
851 EXPECT_EQ(nullptr, result2);
Luke Huang483cf332019-06-03 17:24:51 +0800852 EXPECT_EQ(1U, GetNumQueries(dns0, host_name2));
853 EXPECT_EQ(1U, GetNumQueries(dns1, host_name2));
Ken Chenb9fa2062018-11-13 21:51:13 +0800854}
855
856TEST_F(ResolverTest, GetAddrInfoV6_concurrent) {
Xiao Ma09b71022018-12-11 17:56:32 +0900857 constexpr char listen_addr0[] = "127.0.0.9";
858 constexpr char listen_addr1[] = "127.0.0.10";
859 constexpr char listen_addr2[] = "127.0.0.11";
860 constexpr char host_name[] = "konbanha.example.com.";
861
862 test::DNSResponder dns0(listen_addr0);
863 test::DNSResponder dns1(listen_addr1);
864 test::DNSResponder dns2(listen_addr2);
865 StartDns(dns0, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
866 StartDns(dns1, {{host_name, ns_type::ns_t_aaaa, "2001:db8::6"}});
867 StartDns(dns2, {{host_name, ns_type::ns_t_aaaa, "2001:db8::7"}});
868
Luke Huangf8215372019-11-22 11:53:41 +0800869 const std::vector<std::string> servers = {listen_addr0, listen_addr1, listen_addr2};
Ken Chenb9fa2062018-11-13 21:51:13 +0800870 std::vector<std::thread> threads(10);
871 for (std::thread& thread : threads) {
Luke Huangf8215372019-11-22 11:53:41 +0800872 thread = std::thread([this, &servers]() {
873 unsigned delay = arc4random_uniform(1 * 1000 * 1000); // <= 1s
Ken Chenb9fa2062018-11-13 21:51:13 +0800874 usleep(delay);
875 std::vector<std::string> serverSubset;
876 for (const auto& server : servers) {
877 if (arc4random_uniform(2)) {
878 serverSubset.push_back(server);
879 }
880 }
881 if (serverSubset.empty()) serverSubset = servers;
Xiao Ma09b71022018-12-11 17:56:32 +0900882 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(serverSubset));
883 const addrinfo hints = {.ai_family = AF_INET6};
Ken Chenb9fa2062018-11-13 21:51:13 +0800884 addrinfo* result = nullptr;
885 int rv = getaddrinfo("konbanha", nullptr, &hints, &result);
886 EXPECT_EQ(0, rv) << "error [" << rv << "] " << gai_strerror(rv);
887 if (result) {
888 freeaddrinfo(result);
889 result = nullptr;
890 }
891 });
892 }
893 for (std::thread& thread : threads) {
894 thread.join();
895 }
Ken Chen92bed612018-12-22 21:46:55 +0800896
897 std::vector<std::string> res_servers;
898 std::vector<std::string> res_domains;
899 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900900 res_params res_params;
Ken Chen92bed612018-12-22 21:46:55 +0800901 std::vector<ResolverStats> res_stats;
902 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800903 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
904 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
905 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chen92bed612018-12-22 21:46:55 +0800906 EXPECT_EQ(0, wait_for_pending_req_timeout_count);
Ken Chenb9fa2062018-11-13 21:51:13 +0800907}
908
Mike Yu8ac63402019-12-02 15:28:38 +0800909TEST_F(ResolverTest, SkipBadServersDueToInternalError) {
910 constexpr char listen_addr1[] = "fe80::1";
911 constexpr char listen_addr2[] = "255.255.255.255";
912 constexpr char listen_addr3[] = "127.0.0.3";
913
914 test::DNSResponder dns(listen_addr3);
915 ASSERT_TRUE(dns.startServer());
916
917 ResolverParamsParcel parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
918 parcel.servers = {listen_addr1, listen_addr2, listen_addr3};
919
920 // Bad servers can be distinguished after two attempts.
921 parcel.minSamples = 2;
922 ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
923
924 // Start querying five times.
925 for (int i = 0; i < 5; i++) {
926 std::string hostName = StringPrintf("hello%d.com.", i);
927 dns.addMapping(hostName, ns_type::ns_t_a, "1.2.3.4");
928 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
929 EXPECT_TRUE(safe_getaddrinfo(hostName.c_str(), nullptr, &hints) != nullptr);
930 }
931
932 std::vector<std::string> res_servers;
933 std::vector<std::string> res_domains;
934 std::vector<std::string> res_tls_servers;
935 res_params res_params;
936 std::vector<ResolverStats> res_stats;
937 int wait_for_pending_req_timeout_count;
938 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
939 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
940 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
941
942 // Verify the result by means of the statistics.
943 EXPECT_EQ(res_stats[0].successes, 0);
944 EXPECT_EQ(res_stats[1].successes, 0);
945 EXPECT_EQ(res_stats[2].successes, 5);
946 EXPECT_EQ(res_stats[0].internal_errors, 2);
947 EXPECT_EQ(res_stats[1].internal_errors, 2);
948 EXPECT_EQ(res_stats[2].internal_errors, 0);
949}
950
951TEST_F(ResolverTest, SkipBadServersDueToTimeout) {
952 constexpr char listen_addr1[] = "127.0.0.3";
953 constexpr char listen_addr2[] = "127.0.0.4";
954
955 // Set dns1 non-responsive and dns2 workable.
956 test::DNSResponder dns1(listen_addr1, test::kDefaultListenService, static_cast<ns_rcode>(-1));
957 test::DNSResponder dns2(listen_addr2);
958 dns1.setResponseProbability(0.0);
959 ASSERT_TRUE(dns1.startServer());
960 ASSERT_TRUE(dns2.startServer());
961
962 ResolverParamsParcel parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
963 parcel.servers = {listen_addr1, listen_addr2};
964
965 // Bad servers can be distinguished after two attempts.
966 parcel.minSamples = 2;
967 ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
968
969 // Start querying five times.
970 for (int i = 0; i < 5; i++) {
971 std::string hostName = StringPrintf("hello%d.com.", i);
972 dns1.addMapping(hostName, ns_type::ns_t_a, "1.2.3.4");
973 dns2.addMapping(hostName, ns_type::ns_t_a, "1.2.3.5");
974 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
975 EXPECT_TRUE(safe_getaddrinfo(hostName.c_str(), nullptr, &hints) != nullptr);
976 }
977
978 std::vector<std::string> res_servers;
979 std::vector<std::string> res_domains;
980 std::vector<std::string> res_tls_servers;
981 res_params res_params;
982 std::vector<ResolverStats> res_stats;
983 int wait_for_pending_req_timeout_count;
984 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
985 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
986 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
987
988 // Verify the result by means of the statistics as well as the query counts.
989 EXPECT_EQ(res_stats[0].successes, 0);
990 EXPECT_EQ(res_stats[1].successes, 5);
991 EXPECT_EQ(res_stats[0].timeouts, 2);
992 EXPECT_EQ(res_stats[1].timeouts, 0);
993 EXPECT_EQ(dns1.queries().size(), 2U);
994 EXPECT_EQ(dns2.queries().size(), 5U);
995}
996
chenbrucefd837fa2019-10-29 18:35:36 +0800997TEST_F(ResolverTest, GetAddrInfoFromCustTable_InvalidInput) {
998 constexpr char hostnameNoip[] = "noip.example.com.";
999 constexpr char hostnameInvalidip[] = "invalidip.example.com.";
1000 const std::vector<aidl::android::net::ResolverHostsParcel> invalidCustHosts = {
1001 {"", hostnameNoip},
1002 {"wrong IP", hostnameInvalidip},
1003 };
1004 test::DNSResponder dns;
1005 StartDns(dns, {});
1006 auto resolverParams = DnsResponderClient::GetDefaultResolverParamsParcel();
Ken Chen99344882020-01-01 14:59:38 +08001007 resolverParams.experimentalOptions.hosts = invalidCustHosts;
chenbrucefd837fa2019-10-29 18:35:36 +08001008 ASSERT_TRUE(mDnsClient.resolvService()->setResolverConfiguration(resolverParams).isOk());
1009 for (const auto& hostname : {hostnameNoip, hostnameInvalidip}) {
1010 // The query won't get data from customized table because of invalid customized table
1011 // and DNSResponder also has no records. hostnameNoip has never registered and
1012 // hostnameInvalidip has registered but wrong IP.
1013 const addrinfo hints = {.ai_family = AF_UNSPEC};
1014 ScopedAddrinfo result = safe_getaddrinfo(hostname, nullptr, &hints);
1015 ASSERT_TRUE(result == nullptr);
1016 EXPECT_EQ(4U, GetNumQueries(dns, hostname));
1017 }
1018}
1019
1020TEST_F(ResolverTest, GetAddrInfoFromCustTable) {
1021 constexpr char hostnameV4[] = "v4only.example.com.";
1022 constexpr char hostnameV6[] = "v6only.example.com.";
1023 constexpr char hostnameV4V6[] = "v4v6.example.com.";
1024 constexpr char custAddrV4[] = "1.2.3.4";
1025 constexpr char custAddrV6[] = "::1.2.3.4";
1026 constexpr char dnsSvAddrV4[] = "1.2.3.5";
1027 constexpr char dnsSvAddrV6[] = "::1.2.3.5";
1028 const std::vector<aidl::android::net::ResolverHostsParcel> custHostV4 = {
1029 {custAddrV4, hostnameV4},
1030 };
1031 const std::vector<aidl::android::net::ResolverHostsParcel> custHostV6 = {
1032 {custAddrV6, hostnameV6},
1033 };
1034 const std::vector<aidl::android::net::ResolverHostsParcel> custHostV4V6 = {
1035 {custAddrV4, hostnameV4V6},
1036 {custAddrV6, hostnameV4V6},
1037 };
1038 const std::vector<DnsRecord> dnsSvHostV4 = {
1039 {hostnameV4, ns_type::ns_t_a, dnsSvAddrV4},
1040 };
1041 const std::vector<DnsRecord> dnsSvHostV6 = {
1042 {hostnameV6, ns_type::ns_t_aaaa, dnsSvAddrV6},
1043 };
1044 const std::vector<DnsRecord> dnsSvHostV4V6 = {
1045 {hostnameV4V6, ns_type::ns_t_a, dnsSvAddrV4},
1046 {hostnameV4V6, ns_type::ns_t_aaaa, dnsSvAddrV6},
1047 };
1048 struct TestConfig {
1049 const std::string name;
1050 const std::vector<aidl::android::net::ResolverHostsParcel> customizedHosts;
1051 const std::vector<DnsRecord> dnsserverHosts;
1052 const std::vector<std::string> queryResult;
1053 std::string asParameters() const {
1054 return StringPrintf("name: %s, customizedHosts: %s, dnsserverHosts: %s", name.c_str(),
1055 customizedHosts.empty() ? "No" : "Yes",
1056 dnsserverHosts.empty() ? "No" : "Yes");
1057 }
1058 } testConfigs[]{
1059 // clang-format off
1060 {hostnameV4, {}, {}, {}},
1061 {hostnameV4, {}, dnsSvHostV4, {dnsSvAddrV4}},
1062 {hostnameV4, custHostV4, {}, {custAddrV4}},
1063 {hostnameV4, custHostV4, dnsSvHostV4, {custAddrV4}},
1064 {hostnameV6, {}, {}, {}},
1065 {hostnameV6, {}, dnsSvHostV6, {dnsSvAddrV6}},
1066 {hostnameV6, custHostV6, {}, {custAddrV6}},
1067 {hostnameV6, custHostV6, dnsSvHostV6, {custAddrV6}},
1068 {hostnameV4V6, {}, {}, {}},
1069 {hostnameV4V6, {}, dnsSvHostV4V6, {dnsSvAddrV4, dnsSvAddrV6}},
1070 {hostnameV4V6, custHostV4V6, {}, {custAddrV4, custAddrV6}},
1071 {hostnameV4V6, custHostV4V6, dnsSvHostV4V6, {custAddrV4, custAddrV6}},
1072 // clang-format on
1073 };
1074
1075 for (const auto& config : testConfigs) {
1076 SCOPED_TRACE(config.asParameters());
1077
1078 test::DNSResponder dns;
1079 StartDns(dns, config.dnsserverHosts);
1080
1081 auto resolverParams = DnsResponderClient::GetDefaultResolverParamsParcel();
Ken Chen99344882020-01-01 14:59:38 +08001082 resolverParams.experimentalOptions.hosts = config.customizedHosts;
chenbrucefd837fa2019-10-29 18:35:36 +08001083 ASSERT_TRUE(mDnsClient.resolvService()->setResolverConfiguration(resolverParams).isOk());
1084 const addrinfo hints = {.ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM};
1085 ScopedAddrinfo result = safe_getaddrinfo(config.name.c_str(), nullptr, &hints);
1086 if (config.customizedHosts.empty() && config.dnsserverHosts.empty()) {
1087 ASSERT_TRUE(result == nullptr);
1088 EXPECT_EQ(2U, GetNumQueries(dns, config.name.c_str()));
1089 } else {
1090 ASSERT_TRUE(result != nullptr);
1091 EXPECT_THAT(ToStrings(result), testing::UnorderedElementsAreArray(config.queryResult));
1092 EXPECT_EQ(config.customizedHosts.empty() ? 2U : 0U,
1093 GetNumQueries(dns, config.name.c_str()));
1094 }
1095
1096 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
1097 }
1098}
1099
1100TEST_F(ResolverTest, GetAddrInfoFromCustTable_Modify) {
1101 constexpr char hostnameV4V6[] = "v4v6.example.com.";
1102 constexpr char custAddrV4[] = "1.2.3.4";
1103 constexpr char custAddrV6[] = "::1.2.3.4";
1104 constexpr char dnsSvAddrV4[] = "1.2.3.5";
1105 constexpr char dnsSvAddrV6[] = "::1.2.3.5";
1106 const std::vector<DnsRecord> dnsSvHostV4V6 = {
1107 {hostnameV4V6, ns_type::ns_t_a, dnsSvAddrV4},
1108 {hostnameV4V6, ns_type::ns_t_aaaa, dnsSvAddrV6},
1109 };
1110 const std::vector<aidl::android::net::ResolverHostsParcel> custHostV4V6 = {
1111 {custAddrV4, hostnameV4V6},
1112 {custAddrV6, hostnameV4V6},
1113 };
1114 test::DNSResponder dns;
1115 StartDns(dns, dnsSvHostV4V6);
1116 auto resolverParams = DnsResponderClient::GetDefaultResolverParamsParcel();
1117
Ken Chen99344882020-01-01 14:59:38 +08001118 resolverParams.experimentalOptions.hosts = custHostV4V6;
chenbrucefd837fa2019-10-29 18:35:36 +08001119 ASSERT_TRUE(mDnsClient.resolvService()->setResolverConfiguration(resolverParams).isOk());
1120 const addrinfo hints = {.ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM};
1121 ScopedAddrinfo result = safe_getaddrinfo(hostnameV4V6, nullptr, &hints);
1122 ASSERT_TRUE(result != nullptr);
1123 EXPECT_THAT(ToStrings(result), testing::UnorderedElementsAreArray({custAddrV4, custAddrV6}));
1124 EXPECT_EQ(0U, GetNumQueries(dns, hostnameV4V6));
1125
Ken Chen99344882020-01-01 14:59:38 +08001126 resolverParams.experimentalOptions.hosts = {};
chenbrucefd837fa2019-10-29 18:35:36 +08001127 ASSERT_TRUE(mDnsClient.resolvService()->setResolverConfiguration(resolverParams).isOk());
1128 result = safe_getaddrinfo(hostnameV4V6, nullptr, &hints);
1129 ASSERT_TRUE(result != nullptr);
1130 EXPECT_THAT(ToStrings(result), testing::UnorderedElementsAreArray({dnsSvAddrV4, dnsSvAddrV6}));
1131 EXPECT_EQ(2U, GetNumQueries(dns, hostnameV4V6));
1132}
1133
Ken Chenb9fa2062018-11-13 21:51:13 +08001134TEST_F(ResolverTest, EmptySetup) {
Ken Chenb9fa2062018-11-13 21:51:13 +08001135 std::vector<std::string> servers;
1136 std::vector<std::string> domains;
Xiao Ma09b71022018-12-11 17:56:32 +09001137 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Ken Chenb9fa2062018-11-13 21:51:13 +08001138 std::vector<std::string> res_servers;
1139 std::vector<std::string> res_domains;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001140 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +09001141 res_params res_params;
Ken Chenb9fa2062018-11-13 21:51:13 +08001142 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +08001143 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +08001144 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
1145 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
1146 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chenb9fa2062018-11-13 21:51:13 +08001147 EXPECT_EQ(0U, res_servers.size());
1148 EXPECT_EQ(0U, res_domains.size());
Mike Yu0a1c53d2018-11-26 13:26:21 +09001149 EXPECT_EQ(0U, res_tls_servers.size());
Luke Huang5bd827c2019-03-14 16:10:04 +08001150 ASSERT_EQ(static_cast<size_t>(IDnsResolver::RESOLVER_PARAMS_COUNT), kDefaultParams.size());
1151 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY],
1152 res_params.sample_validity);
1153 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD],
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +09001154 res_params.success_threshold);
Luke Huang5bd827c2019-03-14 16:10:04 +08001155 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
1156 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
1157 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
Ken Chenb9fa2062018-11-13 21:51:13 +08001158 res_params.base_timeout_msec);
Luke Huang5bd827c2019-03-14 16:10:04 +08001159 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT], res_params.retry_count);
Ken Chenb9fa2062018-11-13 21:51:13 +08001160}
1161
1162TEST_F(ResolverTest, SearchPathChange) {
Xiao Ma09b71022018-12-11 17:56:32 +09001163 constexpr char listen_addr[] = "127.0.0.13";
1164 constexpr char host_name1[] = "test13.domain1.org.";
1165 constexpr char host_name2[] = "test13.domain2.org.";
Luke Huangf8215372019-11-22 11:53:41 +08001166 std::vector<std::string> servers = {listen_addr};
1167 std::vector<std::string> domains = {"domain1.org"};
Xiao Ma09b71022018-12-11 17:56:32 +09001168
1169 const std::vector<DnsRecord> records = {
1170 {host_name1, ns_type::ns_t_aaaa, "2001:db8::13"},
1171 {host_name2, ns_type::ns_t_aaaa, "2001:db8::1:13"},
1172 };
1173 test::DNSResponder dns(listen_addr);
1174 StartDns(dns, records);
1175 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Ken Chenb9fa2062018-11-13 21:51:13 +08001176
1177 const addrinfo hints = {.ai_family = AF_INET6};
1178 ScopedAddrinfo result = safe_getaddrinfo("test13", nullptr, &hints);
1179 EXPECT_TRUE(result != nullptr);
1180 EXPECT_EQ(1U, dns.queries().size());
1181 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
1182 EXPECT_EQ("2001:db8::13", ToString(result));
1183
1184 // Test that changing the domain search path on its own works.
Luke Huangf8215372019-11-22 11:53:41 +08001185 domains = {"domain2.org"};
Xiao Ma09b71022018-12-11 17:56:32 +09001186 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Ken Chenb9fa2062018-11-13 21:51:13 +08001187 dns.clearQueries();
1188
1189 result = safe_getaddrinfo("test13", nullptr, &hints);
1190 EXPECT_TRUE(result != nullptr);
1191 EXPECT_EQ(1U, dns.queries().size());
1192 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
1193 EXPECT_EQ("2001:db8::1:13", ToString(result));
1194}
1195
Luke Huang2dac4382019-06-24 13:28:44 +08001196namespace {
1197
Luke Huangf8215372019-11-22 11:53:41 +08001198std::vector<std::string> getResolverDomains(aidl::android::net::IDnsResolver* dnsResolverService,
Luke Huang2dac4382019-06-24 13:28:44 +08001199 unsigned netId) {
1200 std::vector<std::string> res_servers;
1201 std::vector<std::string> res_domains;
1202 std::vector<std::string> res_tls_servers;
1203 res_params res_params;
1204 std::vector<ResolverStats> res_stats;
1205 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +08001206 DnsResponderClient::GetResolverInfo(dnsResolverService, netId, &res_servers, &res_domains,
1207 &res_tls_servers, &res_params, &res_stats,
1208 &wait_for_pending_req_timeout_count);
Luke Huang2dac4382019-06-24 13:28:44 +08001209 return res_domains;
1210}
1211
1212} // namespace
1213
1214TEST_F(ResolverTest, SearchPathPrune) {
1215 constexpr size_t DUPLICATED_DOMAIN_NUM = 3;
1216 constexpr char listen_addr[] = "127.0.0.13";
1217 constexpr char domian_name1[] = "domain13.org.";
1218 constexpr char domian_name2[] = "domain14.org.";
1219 constexpr char host_name1[] = "test13.domain13.org.";
1220 constexpr char host_name2[] = "test14.domain14.org.";
1221 std::vector<std::string> servers = {listen_addr};
1222
1223 std::vector<std::string> testDomains1;
1224 std::vector<std::string> testDomains2;
1225 // Domain length should be <= 255
1226 // Max number of domains in search path is 6
1227 for (size_t i = 0; i < MAXDNSRCH + 1; i++) {
1228 // Fill up with invalid domain
1229 testDomains1.push_back(std::string(300, i + '0'));
1230 // Fill up with valid but duplicated domain
1231 testDomains2.push_back(StringPrintf("domain%zu.org", i % DUPLICATED_DOMAIN_NUM));
1232 }
1233
1234 // Add valid domain used for query.
1235 testDomains1.push_back(domian_name1);
1236
1237 // Add valid domain twice used for query.
1238 testDomains2.push_back(domian_name2);
1239 testDomains2.push_back(domian_name2);
1240
1241 const std::vector<DnsRecord> records = {
1242 {host_name1, ns_type::ns_t_aaaa, "2001:db8::13"},
1243 {host_name2, ns_type::ns_t_aaaa, "2001:db8::1:13"},
1244 };
1245 test::DNSResponder dns(listen_addr);
1246 StartDns(dns, records);
1247 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, testDomains1));
1248
1249 const addrinfo hints = {.ai_family = AF_INET6};
1250 ScopedAddrinfo result = safe_getaddrinfo("test13", nullptr, &hints);
1251
1252 EXPECT_TRUE(result != nullptr);
1253
1254 EXPECT_EQ(1U, dns.queries().size());
1255 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
1256 EXPECT_EQ("2001:db8::13", ToString(result));
1257
1258 const auto& res_domains1 = getResolverDomains(mDnsClient.resolvService(), TEST_NETID);
1259 // Expect 1 valid domain, invalid domains are removed.
1260 ASSERT_EQ(1U, res_domains1.size());
1261 EXPECT_EQ(domian_name1, res_domains1[0]);
1262
1263 dns.clearQueries();
1264
1265 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, testDomains2));
1266
1267 result = safe_getaddrinfo("test14", nullptr, &hints);
1268 EXPECT_TRUE(result != nullptr);
1269
1270 // (3 domains * 2 retries) + 1 success query = 7
1271 EXPECT_EQ(7U, dns.queries().size());
1272 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
1273 EXPECT_EQ("2001:db8::1:13", ToString(result));
1274
1275 const auto& res_domains2 = getResolverDomains(mDnsClient.resolvService(), TEST_NETID);
1276 // Expect 4 valid domain, duplicate domains are removed.
1277 EXPECT_EQ(DUPLICATED_DOMAIN_NUM + 1U, res_domains2.size());
1278 EXPECT_THAT(
1279 std::vector<std::string>({"domain0.org", "domain1.org", "domain2.org", domian_name2}),
1280 testing::ElementsAreArray(res_domains2));
1281}
1282
Mike Yu0a1c53d2018-11-26 13:26:21 +09001283// If we move this function to dns_responder_client, it will complicate the dependency need of
1284// dns_tls_frontend.h.
1285static void setupTlsServers(const std::vector<std::string>& servers,
waynema0e73c2e2019-07-31 15:04:08 +08001286 std::vector<std::unique_ptr<test::DnsTlsFrontend>>* tls) {
Xiao Ma09b71022018-12-11 17:56:32 +09001287 constexpr char listen_udp[] = "53";
1288 constexpr char listen_tls[] = "853";
Mike Yu0a1c53d2018-11-26 13:26:21 +09001289
1290 for (const auto& server : servers) {
1291 auto t = std::make_unique<test::DnsTlsFrontend>(server, listen_tls, server, listen_udp);
1292 t = std::make_unique<test::DnsTlsFrontend>(server, listen_tls, server, listen_udp);
1293 t->startServer();
Mike Yu0a1c53d2018-11-26 13:26:21 +09001294 tls->push_back(std::move(t));
1295 }
1296}
1297
Mike Yu0a1c53d2018-11-26 13:26:21 +09001298TEST_F(ResolverTest, MaxServerPrune_Binder) {
Mike Yu0a1c53d2018-11-26 13:26:21 +09001299 std::vector<std::string> domains;
1300 std::vector<std::unique_ptr<test::DNSResponder>> dns;
1301 std::vector<std::unique_ptr<test::DnsTlsFrontend>> tls;
1302 std::vector<std::string> servers;
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +09001303 std::vector<DnsResponderClient::Mapping> mappings;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001304
1305 for (unsigned i = 0; i < MAXDNSRCH + 1; i++) {
1306 domains.push_back(StringPrintf("example%u.com", i));
1307 }
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +09001308 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupMappings(1, domains, &mappings));
1309 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupDNSServers(MAXNS + 1, mappings, &dns, &servers));
waynema0e73c2e2019-07-31 15:04:08 +08001310 ASSERT_NO_FATAL_FAILURE(setupTlsServers(servers, &tls));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001311
waynema0e73c2e2019-07-31 15:04:08 +08001312 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, domains, kDefaultParams,
1313 kDefaultPrivateDnsHostName));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001314
Mike Yu383855b2019-01-15 17:53:27 +08001315 // If the private DNS validation hasn't completed yet before backend DNS servers stop,
1316 // TLS servers will get stuck in handleOneRequest(), which causes this test stuck in
1317 // ~DnsTlsFrontend() because the TLS server loop threads can't be terminated.
1318 // So, wait for private DNS validation done before stopping backend DNS servers.
1319 for (int i = 0; i < MAXNS; i++) {
chenbruceaff85842019-05-31 15:46:42 +08001320 LOG(INFO) << "Waiting for private DNS validation on " << tls[i]->listen_address() << ".";
Mike Yu724f77d2019-08-16 11:14:50 +08001321 EXPECT_TRUE(WaitForPrivateDnsValidation(tls[i]->listen_address(), true));
chenbruceaff85842019-05-31 15:46:42 +08001322 LOG(INFO) << "private DNS validation on " << tls[i]->listen_address() << " done.";
Mike Yu383855b2019-01-15 17:53:27 +08001323 }
1324
Mike Yu0a1c53d2018-11-26 13:26:21 +09001325 std::vector<std::string> res_servers;
1326 std::vector<std::string> res_domains;
1327 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +09001328 res_params res_params;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001329 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +08001330 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +08001331 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
1332 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
1333 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001334
1335 // Check the size of the stats and its contents.
1336 EXPECT_EQ(static_cast<size_t>(MAXNS), res_servers.size());
1337 EXPECT_EQ(static_cast<size_t>(MAXNS), res_tls_servers.size());
1338 EXPECT_EQ(static_cast<size_t>(MAXDNSRCH), res_domains.size());
1339 EXPECT_TRUE(std::equal(servers.begin(), servers.begin() + MAXNS, res_servers.begin()));
1340 EXPECT_TRUE(std::equal(servers.begin(), servers.begin() + MAXNS, res_tls_servers.begin()));
1341 EXPECT_TRUE(std::equal(domains.begin(), domains.begin() + MAXDNSRCH, res_domains.begin()));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001342}
1343
1344TEST_F(ResolverTest, ResolverStats) {
Xiao Ma09b71022018-12-11 17:56:32 +09001345 constexpr char listen_addr1[] = "127.0.0.4";
1346 constexpr char listen_addr2[] = "127.0.0.5";
1347 constexpr char listen_addr3[] = "127.0.0.6";
Mike Yu0a1c53d2018-11-26 13:26:21 +09001348
1349 // Set server 1 timeout.
Mike Yufc125e42019-05-15 20:41:28 +08001350 test::DNSResponder dns1(listen_addr1, "53", static_cast<ns_rcode>(-1));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001351 dns1.setResponseProbability(0.0);
1352 ASSERT_TRUE(dns1.startServer());
1353
1354 // Set server 2 responding server failure.
Xiao Ma09b71022018-12-11 17:56:32 +09001355 test::DNSResponder dns2(listen_addr2);
Mike Yu0a1c53d2018-11-26 13:26:21 +09001356 dns2.setResponseProbability(0.0);
1357 ASSERT_TRUE(dns2.startServer());
1358
1359 // Set server 3 workable.
Xiao Ma09b71022018-12-11 17:56:32 +09001360 test::DNSResponder dns3(listen_addr3);
1361 dns3.addMapping(kHelloExampleCom, ns_type::ns_t_a, "1.2.3.4");
Mike Yu0a1c53d2018-11-26 13:26:21 +09001362 ASSERT_TRUE(dns3.startServer());
1363
1364 std::vector<std::string> servers = {listen_addr1, listen_addr2, listen_addr3};
Xiao Ma09b71022018-12-11 17:56:32 +09001365 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001366
1367 dns3.clearQueries();
Xiao Ma09b71022018-12-11 17:56:32 +09001368 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
Mike Yu0a1c53d2018-11-26 13:26:21 +09001369 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
Xiao Ma09b71022018-12-11 17:56:32 +09001370 size_t found = GetNumQueries(dns3, kHelloExampleCom);
Mike Yu0a1c53d2018-11-26 13:26:21 +09001371 EXPECT_LE(1U, found);
1372 std::string result_str = ToString(result);
1373 EXPECT_TRUE(result_str == "1.2.3.4") << ", result_str='" << result_str << "'";
1374
1375 std::vector<std::string> res_servers;
1376 std::vector<std::string> res_domains;
1377 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +09001378 res_params res_params;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001379 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +08001380 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +08001381 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
1382 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
1383 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001384
1385 EXPECT_EQ(1, res_stats[0].timeouts);
1386 EXPECT_EQ(1, res_stats[1].errors);
1387 EXPECT_EQ(1, res_stats[2].successes);
Mike Yu0a1c53d2018-11-26 13:26:21 +09001388}
1389
Ken Chenb9fa2062018-11-13 21:51:13 +08001390// Test what happens if the specified TLS server is nonexistent.
1391TEST_F(ResolverTest, GetHostByName_TlsMissing) {
Xiao Ma09b71022018-12-11 17:56:32 +09001392 constexpr char listen_addr[] = "127.0.0.3";
1393 constexpr char host_name[] = "tlsmissing.example.com.";
1394
1395 test::DNSResponder dns;
1396 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.3"}});
Luke Huangf8215372019-11-22 11:53:41 +08001397 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001398
1399 // There's nothing listening on this address, so validation will either fail or
1400 /// hang. Either way, queries will continue to flow to the DNSResponder.
waynema0e73c2e2019-07-31 15:04:08 +08001401 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Ken Chenb9fa2062018-11-13 21:51:13 +08001402
1403 const hostent* result;
1404
1405 result = gethostbyname("tlsmissing");
1406 ASSERT_FALSE(result == nullptr);
1407 EXPECT_EQ("1.2.3.3", ToString(result));
1408
1409 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001410 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001411}
1412
1413// Test what happens if the specified TLS server replies with garbage.
1414TEST_F(ResolverTest, GetHostByName_TlsBroken) {
Xiao Ma09b71022018-12-11 17:56:32 +09001415 constexpr char listen_addr[] = "127.0.0.3";
1416 constexpr char host_name1[] = "tlsbroken1.example.com.";
1417 constexpr char host_name2[] = "tlsbroken2.example.com.";
1418 const std::vector<DnsRecord> records = {
1419 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1420 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1421 };
1422
1423 test::DNSResponder dns;
1424 StartDns(dns, records);
Luke Huangf8215372019-11-22 11:53:41 +08001425 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001426
1427 // Bind the specified private DNS socket but don't respond to any client sockets yet.
1428 int s = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
1429 ASSERT_TRUE(s >= 0);
1430 struct sockaddr_in tlsServer = {
Luke Huangf8215372019-11-22 11:53:41 +08001431 .sin_family = AF_INET,
1432 .sin_port = htons(853),
Ken Chenb9fa2062018-11-13 21:51:13 +08001433 };
1434 ASSERT_TRUE(inet_pton(AF_INET, listen_addr, &tlsServer.sin_addr));
1435 ASSERT_TRUE(enableSockopt(s, SOL_SOCKET, SO_REUSEPORT).ok());
1436 ASSERT_TRUE(enableSockopt(s, SOL_SOCKET, SO_REUSEADDR).ok());
1437 ASSERT_FALSE(bind(s, reinterpret_cast<struct sockaddr*>(&tlsServer), sizeof(tlsServer)));
1438 ASSERT_FALSE(listen(s, 1));
1439
1440 // Trigger TLS validation.
waynema0e73c2e2019-07-31 15:04:08 +08001441 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Ken Chenb9fa2062018-11-13 21:51:13 +08001442
1443 struct sockaddr_storage cliaddr;
1444 socklen_t sin_size = sizeof(cliaddr);
Luke Huangf8215372019-11-22 11:53:41 +08001445 int new_fd = accept4(s, reinterpret_cast<struct sockaddr*>(&cliaddr), &sin_size, SOCK_CLOEXEC);
Ken Chenb9fa2062018-11-13 21:51:13 +08001446 ASSERT_TRUE(new_fd > 0);
1447
1448 // We've received the new file descriptor but not written to it or closed, so the
1449 // validation is still pending. Queries should still flow correctly because the
1450 // server is not used until validation succeeds.
1451 const hostent* result;
1452 result = gethostbyname("tlsbroken1");
1453 ASSERT_FALSE(result == nullptr);
1454 EXPECT_EQ("1.2.3.1", ToString(result));
1455
1456 // Now we cause the validation to fail.
1457 std::string garbage = "definitely not a valid TLS ServerHello";
1458 write(new_fd, garbage.data(), garbage.size());
1459 close(new_fd);
1460
1461 // Validation failure shouldn't interfere with lookups, because lookups won't be sent
1462 // to the TLS server unless validation succeeds.
1463 result = gethostbyname("tlsbroken2");
1464 ASSERT_FALSE(result == nullptr);
1465 EXPECT_EQ("1.2.3.2", ToString(result));
1466
1467 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001468 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001469 close(s);
1470}
1471
1472TEST_F(ResolverTest, GetHostByName_Tls) {
Xiao Ma09b71022018-12-11 17:56:32 +09001473 constexpr char listen_addr[] = "127.0.0.3";
1474 constexpr char listen_udp[] = "53";
1475 constexpr char listen_tls[] = "853";
1476 constexpr char host_name1[] = "tls1.example.com.";
1477 constexpr char host_name2[] = "tls2.example.com.";
1478 constexpr char host_name3[] = "tls3.example.com.";
1479 const std::vector<DnsRecord> records = {
1480 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1481 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1482 {host_name3, ns_type::ns_t_a, "1.2.3.3"},
1483 };
1484
1485 test::DNSResponder dns;
1486 StartDns(dns, records);
Luke Huangf8215372019-11-22 11:53:41 +08001487 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001488
1489 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1490 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08001491 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08001492 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Ken Chenb9fa2062018-11-13 21:51:13 +08001493
Mike Yu724f77d2019-08-16 11:14:50 +08001494 const hostent* result = gethostbyname("tls1");
Ken Chenb9fa2062018-11-13 21:51:13 +08001495 ASSERT_FALSE(result == nullptr);
1496 EXPECT_EQ("1.2.3.1", ToString(result));
1497
1498 // Wait for query to get counted.
1499 EXPECT_TRUE(tls.waitForQueries(2, 5000));
1500
1501 // Stop the TLS server. Since we're in opportunistic mode, queries will
1502 // fall back to the locally-assigned (clear text) nameservers.
1503 tls.stopServer();
1504
1505 dns.clearQueries();
1506 result = gethostbyname("tls2");
1507 EXPECT_FALSE(result == nullptr);
1508 EXPECT_EQ("1.2.3.2", ToString(result));
1509 const auto queries = dns.queries();
1510 EXPECT_EQ(1U, queries.size());
waynema29253052019-08-20 11:26:08 +08001511 EXPECT_EQ("tls2.example.com.", queries[0].name);
1512 EXPECT_EQ(ns_t_a, queries[0].type);
Ken Chenb9fa2062018-11-13 21:51:13 +08001513
1514 // Reset the resolvers without enabling TLS. Queries should still be routed
1515 // to the UDP endpoint.
Xiao Ma09b71022018-12-11 17:56:32 +09001516 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001517
1518 result = gethostbyname("tls3");
1519 ASSERT_FALSE(result == nullptr);
1520 EXPECT_EQ("1.2.3.3", ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +08001521}
1522
Ken Chenb9fa2062018-11-13 21:51:13 +08001523TEST_F(ResolverTest, GetHostByName_TlsFailover) {
Xiao Ma09b71022018-12-11 17:56:32 +09001524 constexpr char listen_addr1[] = "127.0.0.3";
1525 constexpr char listen_addr2[] = "127.0.0.4";
1526 constexpr char listen_udp[] = "53";
1527 constexpr char listen_tls[] = "853";
1528 constexpr char host_name1[] = "tlsfailover1.example.com.";
1529 constexpr char host_name2[] = "tlsfailover2.example.com.";
1530 const std::vector<DnsRecord> records1 = {
1531 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1532 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1533 };
1534 const std::vector<DnsRecord> records2 = {
1535 {host_name1, ns_type::ns_t_a, "1.2.3.3"},
1536 {host_name2, ns_type::ns_t_a, "1.2.3.4"},
1537 };
1538
1539 test::DNSResponder dns1(listen_addr1);
1540 test::DNSResponder dns2(listen_addr2);
1541 StartDns(dns1, records1);
1542 StartDns(dns2, records2);
1543
Luke Huangf8215372019-11-22 11:53:41 +08001544 std::vector<std::string> servers = {listen_addr1, listen_addr2};
Ken Chenb9fa2062018-11-13 21:51:13 +08001545
1546 test::DnsTlsFrontend tls1(listen_addr1, listen_tls, listen_addr1, listen_udp);
1547 test::DnsTlsFrontend tls2(listen_addr2, listen_tls, listen_addr2, listen_udp);
1548 ASSERT_TRUE(tls1.startServer());
1549 ASSERT_TRUE(tls2.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08001550 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
1551 kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08001552 EXPECT_TRUE(WaitForPrivateDnsValidation(tls1.listen_address(), true));
1553 EXPECT_TRUE(WaitForPrivateDnsValidation(tls2.listen_address(), true));
Ken Chenb9fa2062018-11-13 21:51:13 +08001554
Mike Yu724f77d2019-08-16 11:14:50 +08001555 const hostent* result = gethostbyname("tlsfailover1");
Ken Chenb9fa2062018-11-13 21:51:13 +08001556 ASSERT_FALSE(result == nullptr);
1557 EXPECT_EQ("1.2.3.1", ToString(result));
1558
1559 // Wait for query to get counted.
1560 EXPECT_TRUE(tls1.waitForQueries(2, 5000));
1561 // No new queries should have reached tls2.
1562 EXPECT_EQ(1, tls2.queries());
1563
1564 // Stop tls1. Subsequent queries should attempt to reach tls1, fail, and retry to tls2.
1565 tls1.stopServer();
1566
1567 result = gethostbyname("tlsfailover2");
1568 EXPECT_EQ("1.2.3.4", ToString(result));
1569
1570 // Wait for query to get counted.
1571 EXPECT_TRUE(tls2.waitForQueries(2, 5000));
1572
1573 // No additional queries should have reached the insecure servers.
1574 EXPECT_EQ(2U, dns1.queries().size());
1575 EXPECT_EQ(2U, dns2.queries().size());
1576
1577 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001578 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Ken Chenb9fa2062018-11-13 21:51:13 +08001579}
1580
1581TEST_F(ResolverTest, GetHostByName_BadTlsName) {
Xiao Ma09b71022018-12-11 17:56:32 +09001582 constexpr char listen_addr[] = "127.0.0.3";
1583 constexpr char listen_udp[] = "53";
1584 constexpr char listen_tls[] = "853";
1585 constexpr char host_name[] = "badtlsname.example.com.";
1586
1587 test::DNSResponder dns;
1588 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.1"}});
Luke Huangf8215372019-11-22 11:53:41 +08001589 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001590
1591 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1592 ASSERT_TRUE(tls.startServer());
Xiao Ma09b71022018-12-11 17:56:32 +09001593 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
waynema0e73c2e2019-07-31 15:04:08 +08001594 kDefaultIncorrectPrivateDnsHostName));
Ken Chenb9fa2062018-11-13 21:51:13 +08001595
waynema0e73c2e2019-07-31 15:04:08 +08001596 // The TLS handshake would fail because the name of TLS server doesn't
1597 // match with TLS server's certificate.
Mike Yu724f77d2019-08-16 11:14:50 +08001598 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), false));
Ken Chenb9fa2062018-11-13 21:51:13 +08001599
1600 // The query should fail hard, because a name was specified.
1601 EXPECT_EQ(nullptr, gethostbyname("badtlsname"));
1602
1603 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001604 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001605}
1606
1607TEST_F(ResolverTest, GetAddrInfo_Tls) {
Xiao Ma09b71022018-12-11 17:56:32 +09001608 constexpr char listen_addr[] = "127.0.0.3";
1609 constexpr char listen_udp[] = "53";
1610 constexpr char listen_tls[] = "853";
1611 constexpr char host_name[] = "addrinfotls.example.com.";
1612 const std::vector<DnsRecord> records = {
1613 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1614 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1615 };
1616
1617 test::DNSResponder dns;
1618 StartDns(dns, records);
Luke Huangf8215372019-11-22 11:53:41 +08001619 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001620
1621 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1622 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08001623 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
1624 kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08001625 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Ken Chenb9fa2062018-11-13 21:51:13 +08001626
1627 dns.clearQueries();
1628 ScopedAddrinfo result = safe_getaddrinfo("addrinfotls", nullptr, nullptr);
1629 EXPECT_TRUE(result != nullptr);
1630 size_t found = GetNumQueries(dns, host_name);
1631 EXPECT_LE(1U, found);
1632 // Could be A or AAAA
1633 std::string result_str = ToString(result);
1634 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
Luke Huangf8215372019-11-22 11:53:41 +08001635 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +08001636 // Wait for both A and AAAA queries to get counted.
1637 EXPECT_TRUE(tls.waitForQueries(3, 5000));
1638
1639 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001640 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001641}
1642
1643TEST_F(ResolverTest, TlsBypass) {
1644 const char OFF[] = "off";
1645 const char OPPORTUNISTIC[] = "opportunistic";
1646 const char STRICT[] = "strict";
1647
1648 const char GETHOSTBYNAME[] = "gethostbyname";
1649 const char GETADDRINFO[] = "getaddrinfo";
1650 const char GETADDRINFOFORNET[] = "getaddrinfofornet";
1651
1652 const unsigned BYPASS_NETID = NETID_USE_LOCAL_NAMESERVERS | TEST_NETID;
1653
Ken Chenb9fa2062018-11-13 21:51:13 +08001654 const char ADDR4[] = "192.0.2.1";
1655 const char ADDR6[] = "2001:db8::1";
1656
1657 const char cleartext_addr[] = "127.0.0.53";
1658 const char cleartext_port[] = "53";
1659 const char tls_port[] = "853";
Luke Huangf8215372019-11-22 11:53:41 +08001660 const std::vector<std::string> servers = {cleartext_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001661
Xiao Ma09b71022018-12-11 17:56:32 +09001662 test::DNSResponder dns(cleartext_addr);
Ken Chenb9fa2062018-11-13 21:51:13 +08001663 ASSERT_TRUE(dns.startServer());
1664
1665 test::DnsTlsFrontend tls(cleartext_addr, tls_port, cleartext_addr, cleartext_port);
Mike Yudd4ac2d2019-05-31 16:52:11 +08001666 ASSERT_TRUE(tls.startServer());
Ken Chenb9fa2062018-11-13 21:51:13 +08001667
Luke Huangf8215372019-11-22 11:53:41 +08001668 // clang-format off
Ken Chenb9fa2062018-11-13 21:51:13 +08001669 struct TestConfig {
1670 const std::string mode;
1671 const bool withWorkingTLS;
1672 const std::string method;
1673
1674 std::string asHostName() const {
Luke Huangf8215372019-11-22 11:53:41 +08001675 return StringPrintf("%s.%s.%s.", mode.c_str(), withWorkingTLS ? "tlsOn" : "tlsOff",
Ken Chenb9fa2062018-11-13 21:51:13 +08001676 method.c_str());
1677 }
1678 } testConfigs[]{
Ken Chenb9fa2062018-11-13 21:51:13 +08001679 {OFF, true, GETHOSTBYNAME},
1680 {OPPORTUNISTIC, true, GETHOSTBYNAME},
1681 {STRICT, true, GETHOSTBYNAME},
Ken Chenb9fa2062018-11-13 21:51:13 +08001682 {OFF, true, GETADDRINFO},
1683 {OPPORTUNISTIC, true, GETADDRINFO},
1684 {STRICT, true, GETADDRINFO},
Ken Chenb9fa2062018-11-13 21:51:13 +08001685 {OFF, true, GETADDRINFOFORNET},
1686 {OPPORTUNISTIC, true, GETADDRINFOFORNET},
1687 {STRICT, true, GETADDRINFOFORNET},
Mike Yudd4ac2d2019-05-31 16:52:11 +08001688 {OFF, false, GETHOSTBYNAME},
1689 {OPPORTUNISTIC, false, GETHOSTBYNAME},
1690 {STRICT, false, GETHOSTBYNAME},
1691 {OFF, false, GETADDRINFO},
1692 {OPPORTUNISTIC, false, GETADDRINFO},
1693 {STRICT, false, GETADDRINFO},
1694 {OFF, false, GETADDRINFOFORNET},
1695 {OPPORTUNISTIC, false, GETADDRINFOFORNET},
1696 {STRICT, false, GETADDRINFOFORNET},
Ken Chenb9fa2062018-11-13 21:51:13 +08001697 };
Luke Huangf8215372019-11-22 11:53:41 +08001698 // clang-format on
Ken Chenb9fa2062018-11-13 21:51:13 +08001699
1700 for (const auto& config : testConfigs) {
1701 const std::string testHostName = config.asHostName();
1702 SCOPED_TRACE(testHostName);
1703
1704 // Don't tempt test bugs due to caching.
1705 const char* host_name = testHostName.c_str();
1706 dns.addMapping(host_name, ns_type::ns_t_a, ADDR4);
1707 dns.addMapping(host_name, ns_type::ns_t_aaaa, ADDR6);
1708
Mike Yudd4ac2d2019-05-31 16:52:11 +08001709 if (config.withWorkingTLS) {
1710 if (!tls.running()) {
1711 ASSERT_TRUE(tls.startServer());
1712 }
1713 } else {
1714 if (tls.running()) {
1715 ASSERT_TRUE(tls.stopServer());
1716 }
1717 }
Ken Chenb9fa2062018-11-13 21:51:13 +08001718
1719 if (config.mode == OFF) {
Xiao Ma09b71022018-12-11 17:56:32 +09001720 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, kDefaultSearchDomains,
1721 kDefaultParams));
Ken Chenb9fa2062018-11-13 21:51:13 +08001722 } else if (config.mode == OPPORTUNISTIC) {
Xiao Ma09b71022018-12-11 17:56:32 +09001723 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08001724 kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08001725
1726 // Wait for the validation event. If the server is running, the validation should
1727 // be successful; otherwise, the validation should be failed.
1728 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), config.withWorkingTLS));
Ken Chenb9fa2062018-11-13 21:51:13 +08001729 } else if (config.mode == STRICT) {
Xiao Ma09b71022018-12-11 17:56:32 +09001730 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08001731 kDefaultParams, kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08001732
1733 // Wait for the validation event.
1734 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), config.withWorkingTLS));
Ken Chenb9fa2062018-11-13 21:51:13 +08001735 }
Mike Yudd4ac2d2019-05-31 16:52:11 +08001736 tls.clearQueries();
Ken Chenb9fa2062018-11-13 21:51:13 +08001737
1738 const hostent* h_result = nullptr;
1739 ScopedAddrinfo ai_result;
1740
1741 if (config.method == GETHOSTBYNAME) {
1742 ASSERT_EQ(0, setNetworkForResolv(BYPASS_NETID));
1743 h_result = gethostbyname(host_name);
1744
1745 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
1746 ASSERT_FALSE(h_result == nullptr);
1747 ASSERT_EQ(4, h_result->h_length);
1748 ASSERT_FALSE(h_result->h_addr_list[0] == nullptr);
1749 EXPECT_EQ(ADDR4, ToString(h_result));
1750 EXPECT_TRUE(h_result->h_addr_list[1] == nullptr);
1751 } else if (config.method == GETADDRINFO) {
1752 ASSERT_EQ(0, setNetworkForResolv(BYPASS_NETID));
1753 ai_result = safe_getaddrinfo(host_name, nullptr, nullptr);
1754 EXPECT_TRUE(ai_result != nullptr);
1755
1756 EXPECT_LE(1U, GetNumQueries(dns, host_name));
1757 // Could be A or AAAA
1758 const std::string result_str = ToString(ai_result);
1759 EXPECT_TRUE(result_str == ADDR4 || result_str == ADDR6)
Luke Huangf8215372019-11-22 11:53:41 +08001760 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +08001761 } else if (config.method == GETADDRINFOFORNET) {
1762 addrinfo* raw_ai_result = nullptr;
1763 EXPECT_EQ(0, android_getaddrinfofornet(host_name, /*servname=*/nullptr,
1764 /*hints=*/nullptr, BYPASS_NETID, MARK_UNSET,
1765 &raw_ai_result));
1766 ai_result.reset(raw_ai_result);
1767
1768 EXPECT_LE(1U, GetNumQueries(dns, host_name));
1769 // Could be A or AAAA
1770 const std::string result_str = ToString(ai_result);
1771 EXPECT_TRUE(result_str == ADDR4 || result_str == ADDR6)
Luke Huangf8215372019-11-22 11:53:41 +08001772 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +08001773 }
1774
Mike Yudd4ac2d2019-05-31 16:52:11 +08001775 EXPECT_EQ(0, tls.queries());
Ken Chenb9fa2062018-11-13 21:51:13 +08001776
1777 // Clear per-process resolv netid.
1778 ASSERT_EQ(0, setNetworkForResolv(NETID_UNSET));
Ken Chenb9fa2062018-11-13 21:51:13 +08001779 dns.clearQueries();
1780 }
Ken Chenb9fa2062018-11-13 21:51:13 +08001781}
1782
1783TEST_F(ResolverTest, StrictMode_NoTlsServers) {
Xiao Ma09b71022018-12-11 17:56:32 +09001784 constexpr char cleartext_addr[] = "127.0.0.53";
Luke Huangf8215372019-11-22 11:53:41 +08001785 const std::vector<std::string> servers = {cleartext_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001786 constexpr char host_name[] = "strictmode.notlsips.example.com.";
1787 const std::vector<DnsRecord> records = {
1788 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1789 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1790 };
Ken Chenb9fa2062018-11-13 21:51:13 +08001791
Xiao Ma09b71022018-12-11 17:56:32 +09001792 test::DNSResponder dns(cleartext_addr);
1793 StartDns(dns, records);
Ken Chenb9fa2062018-11-13 21:51:13 +08001794
waynema0e73c2e2019-07-31 15:04:08 +08001795 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
1796 kDefaultIncorrectPrivateDnsHostName));
Ken Chenb9fa2062018-11-13 21:51:13 +08001797
1798 addrinfo* ai_result = nullptr;
1799 EXPECT_NE(0, getaddrinfo(host_name, nullptr, nullptr, &ai_result));
1800 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
1801}
Luke Huang94b10b92018-11-21 20:13:38 +08001802
1803namespace {
1804
Luke Huang70931aa2019-01-31 11:57:41 +08001805int getAsyncResponse(int fd, int* rcode, uint8_t* buf, int bufLen) {
Luke Huang94b10b92018-11-21 20:13:38 +08001806 struct pollfd wait_fd[1];
1807 wait_fd[0].fd = fd;
1808 wait_fd[0].events = POLLIN;
1809 short revents;
1810 int ret;
1811
1812 ret = poll(wait_fd, 1, -1);
1813 revents = wait_fd[0].revents;
1814 if (revents & POLLIN) {
1815 int n = resNetworkResult(fd, rcode, buf, bufLen);
Luke Huangba7bef92018-12-26 16:53:03 +08001816 // Verify that resNetworkResult() closed the fd
1817 char dummy;
1818 EXPECT_EQ(-1, read(fd, &dummy, sizeof dummy));
1819 EXPECT_EQ(EBADF, errno);
Luke Huang94b10b92018-11-21 20:13:38 +08001820 return n;
1821 }
1822 return -1;
1823}
1824
Luke Huang70931aa2019-01-31 11:57:41 +08001825std::string toString(uint8_t* buf, int bufLen, int ipType) {
Luke Huang94b10b92018-11-21 20:13:38 +08001826 ns_msg handle;
1827 int ancount, n = 0;
1828 ns_rr rr;
1829
Luke Huangf8215372019-11-22 11:53:41 +08001830 if (ns_initparse((const uint8_t*)buf, bufLen, &handle) >= 0) {
Luke Huang94b10b92018-11-21 20:13:38 +08001831 ancount = ns_msg_count(handle, ns_s_an);
1832 if (ns_parserr(&handle, ns_s_an, n, &rr) == 0) {
Luke Huang70931aa2019-01-31 11:57:41 +08001833 const uint8_t* rdata = ns_rr_rdata(rr);
Luke Huang94b10b92018-11-21 20:13:38 +08001834 char buffer[INET6_ADDRSTRLEN];
Luke Huangf8215372019-11-22 11:53:41 +08001835 if (inet_ntop(ipType, (const char*)rdata, buffer, sizeof(buffer))) {
Luke Huang94b10b92018-11-21 20:13:38 +08001836 return buffer;
1837 }
1838 }
1839 }
1840 return "";
1841}
1842
1843int dns_open_proxy() {
1844 int s = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
1845 if (s == -1) {
1846 return -1;
1847 }
1848 const int one = 1;
1849 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1850
1851 static const struct sockaddr_un proxy_addr = {
1852 .sun_family = AF_UNIX,
1853 .sun_path = "/dev/socket/dnsproxyd",
1854 };
1855
Luke Huangf8215372019-11-22 11:53:41 +08001856 if (TEMP_FAILURE_RETRY(connect(s, (const struct sockaddr*)&proxy_addr, sizeof(proxy_addr))) !=
Luke Huang94b10b92018-11-21 20:13:38 +08001857 0) {
1858 close(s);
1859 return -1;
1860 }
1861
1862 return s;
1863}
1864
Luke Huangba7bef92018-12-26 16:53:03 +08001865void expectAnswersValid(int fd, int ipType, const std::string& expectedAnswer) {
1866 int rcode = -1;
1867 uint8_t buf[MAXPACKET] = {};
1868
1869 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
1870 EXPECT_GT(res, 0);
1871 EXPECT_EQ(expectedAnswer, toString(buf, res, ipType));
1872}
1873
1874void expectAnswersNotValid(int fd, int expectedErrno) {
1875 int rcode = -1;
1876 uint8_t buf[MAXPACKET] = {};
1877
1878 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
1879 EXPECT_EQ(expectedErrno, res);
1880}
1881
Luke Huang94b10b92018-11-21 20:13:38 +08001882} // namespace
1883
1884TEST_F(ResolverTest, Async_NormalQueryV4V6) {
Xiao Ma09b71022018-12-11 17:56:32 +09001885 constexpr char listen_addr[] = "127.0.0.4";
1886 constexpr char host_name[] = "howdy.example.com.";
1887 const std::vector<DnsRecord> records = {
1888 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1889 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1890 };
1891
1892 test::DNSResponder dns(listen_addr);
1893 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001894 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001895 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001896
Luke Huangba7bef92018-12-26 16:53:03 +08001897 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
1898 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001899 EXPECT_TRUE(fd1 != -1);
1900 EXPECT_TRUE(fd2 != -1);
1901
Luke Huang70931aa2019-01-31 11:57:41 +08001902 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001903 int rcode;
1904 int res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
1905 EXPECT_GT(res, 0);
1906 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
1907
1908 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
1909 EXPECT_GT(res, 0);
1910 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
1911
1912 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
1913
1914 // Re-query verify cache works
Luke Huangba7bef92018-12-26 16:53:03 +08001915 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
1916 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001917
1918 EXPECT_TRUE(fd1 != -1);
1919 EXPECT_TRUE(fd2 != -1);
1920
1921 res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
1922 EXPECT_GT(res, 0);
1923 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
1924
1925 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
1926 EXPECT_GT(res, 0);
1927 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
1928
1929 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
1930}
1931
1932TEST_F(ResolverTest, Async_BadQuery) {
Xiao Ma09b71022018-12-11 17:56:32 +09001933 constexpr char listen_addr[] = "127.0.0.4";
1934 constexpr char host_name[] = "howdy.example.com.";
1935 const std::vector<DnsRecord> records = {
1936 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1937 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1938 };
1939
1940 test::DNSResponder dns(listen_addr);
1941 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001942 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001943 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001944
1945 static struct {
1946 int fd;
1947 const char* dname;
1948 const int queryType;
1949 const int expectRcode;
1950 } kTestData[] = {
Luke Huangba7bef92018-12-26 16:53:03 +08001951 {-1, "", ns_t_aaaa, 0},
1952 {-1, "as65ass46", ns_t_aaaa, 0},
1953 {-1, "454564564564", ns_t_aaaa, 0},
1954 {-1, "h645235", ns_t_a, 0},
1955 {-1, "www.google.com", ns_t_a, 0},
Luke Huang94b10b92018-11-21 20:13:38 +08001956 };
1957
1958 for (auto& td : kTestData) {
1959 SCOPED_TRACE(td.dname);
Luke Huangba7bef92018-12-26 16:53:03 +08001960 td.fd = resNetworkQuery(TEST_NETID, td.dname, ns_c_in, td.queryType, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001961 EXPECT_TRUE(td.fd != -1);
1962 }
1963
1964 // dns_responder return empty resp(packet only contains query part) with no error currently
1965 for (const auto& td : kTestData) {
Luke Huang70931aa2019-01-31 11:57:41 +08001966 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001967 int rcode;
1968 SCOPED_TRACE(td.dname);
1969 int res = getAsyncResponse(td.fd, &rcode, buf, MAXPACKET);
1970 EXPECT_GT(res, 0);
1971 EXPECT_EQ(rcode, td.expectRcode);
1972 }
1973}
1974
1975TEST_F(ResolverTest, Async_EmptyAnswer) {
Xiao Ma09b71022018-12-11 17:56:32 +09001976 constexpr char listen_addr[] = "127.0.0.4";
1977 constexpr char host_name[] = "howdy.example.com.";
1978 const std::vector<DnsRecord> records = {
1979 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1980 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1981 };
1982
1983 test::DNSResponder dns(listen_addr);
1984 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001985 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001986 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001987
Luke Huang9c264bb2018-12-18 16:44:41 +08001988 // TODO: Disable retry to make this test explicit.
1989 auto& cv = dns.getCv();
1990 auto& cvMutex = dns.getCvMutex();
1991 int fd1;
1992 // Wait on the condition variable to ensure that the DNS server has handled our first query.
1993 {
1994 std::unique_lock lk(cvMutex);
Luke Huangba7bef92018-12-26 16:53:03 +08001995 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huang9c264bb2018-12-18 16:44:41 +08001996 EXPECT_TRUE(fd1 != -1);
1997 EXPECT_EQ(std::cv_status::no_timeout, cv.wait_for(lk, std::chrono::seconds(1)));
1998 }
Luke Huang94b10b92018-11-21 20:13:38 +08001999
Luke Huang94b10b92018-11-21 20:13:38 +08002000 dns.setResponseProbability(0.0);
Luke Huang94b10b92018-11-21 20:13:38 +08002001
Luke Huangba7bef92018-12-26 16:53:03 +08002002 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08002003 EXPECT_TRUE(fd2 != -1);
2004
Luke Huangba7bef92018-12-26 16:53:03 +08002005 int fd3 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08002006 EXPECT_TRUE(fd3 != -1);
2007
Luke Huang9c264bb2018-12-18 16:44:41 +08002008 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08002009 int rcode;
2010
Luke Huang9c264bb2018-12-18 16:44:41 +08002011 // expect no response
2012 int res = getAsyncResponse(fd3, &rcode, buf, MAXPACKET);
2013 EXPECT_EQ(-ETIMEDOUT, res);
Luke Huang94b10b92018-11-21 20:13:38 +08002014
Luke Huang9c264bb2018-12-18 16:44:41 +08002015 // expect no response
Luke Huang94b10b92018-11-21 20:13:38 +08002016 memset(buf, 0, MAXPACKET);
Luke Huang9c264bb2018-12-18 16:44:41 +08002017 res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
2018 EXPECT_EQ(-ETIMEDOUT, res);
Luke Huang94b10b92018-11-21 20:13:38 +08002019
Luke Huang94b10b92018-11-21 20:13:38 +08002020 dns.setResponseProbability(1.0);
Luke Huang94b10b92018-11-21 20:13:38 +08002021
Luke Huangba7bef92018-12-26 16:53:03 +08002022 int fd4 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08002023 EXPECT_TRUE(fd4 != -1);
2024
2025 memset(buf, 0, MAXPACKET);
2026 res = getAsyncResponse(fd4, &rcode, buf, MAXPACKET);
2027 EXPECT_GT(res, 0);
2028 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
2029
2030 memset(buf, 0, MAXPACKET);
2031 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
2032 EXPECT_GT(res, 0);
2033 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
2034}
2035
2036TEST_F(ResolverTest, Async_MalformedQuery) {
Xiao Ma09b71022018-12-11 17:56:32 +09002037 constexpr char listen_addr[] = "127.0.0.4";
2038 constexpr char host_name[] = "howdy.example.com.";
2039 const std::vector<DnsRecord> records = {
2040 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2041 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
2042 };
2043
2044 test::DNSResponder dns(listen_addr);
2045 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08002046 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002047 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08002048
2049 int fd = dns_open_proxy();
2050 EXPECT_TRUE(fd > 0);
2051
2052 const std::string badMsg = "16-52512#";
Xiao Ma09b71022018-12-11 17:56:32 +09002053 static const struct {
Luke Huang94b10b92018-11-21 20:13:38 +08002054 const std::string cmd;
2055 const int expectErr;
2056 } kTestData[] = {
Luke Huangba7bef92018-12-26 16:53:03 +08002057 // Too few arguments
Luke Huang94b10b92018-11-21 20:13:38 +08002058 {"resnsend " + badMsg + '\0', -EINVAL},
2059 // Bad netId
Luke Huangba7bef92018-12-26 16:53:03 +08002060 {"resnsend badnetId 0 " + badMsg + '\0', -EINVAL},
Luke Huang94b10b92018-11-21 20:13:38 +08002061 // Bad raw data
Luke Huangba7bef92018-12-26 16:53:03 +08002062 {"resnsend " + std::to_string(TEST_NETID) + " 0 " + badMsg + '\0', -EILSEQ},
Luke Huang94b10b92018-11-21 20:13:38 +08002063 };
2064
2065 for (unsigned int i = 0; i < std::size(kTestData); i++) {
2066 auto& td = kTestData[i];
2067 SCOPED_TRACE(td.cmd);
2068 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, td.cmd.c_str(), td.cmd.size()));
2069 EXPECT_EQ(rc, static_cast<ssize_t>(td.cmd.size()));
2070
2071 int32_t tmp;
2072 rc = TEMP_FAILURE_RETRY(read(fd, &tmp, sizeof(tmp)));
2073 EXPECT_TRUE(rc > 0);
2074 EXPECT_EQ(static_cast<int>(ntohl(tmp)), td.expectErr);
2075 }
2076 // Normal query with answer buffer
2077 // This is raw data of query "howdy.example.com" type 1 class 1
2078 std::string query = "81sBAAABAAAAAAAABWhvd2R5B2V4YW1wbGUDY29tAAABAAE=";
Luke Huangba7bef92018-12-26 16:53:03 +08002079 std::string cmd = "resnsend " + std::to_string(TEST_NETID) + " 0 " + query + '\0';
Luke Huang94b10b92018-11-21 20:13:38 +08002080 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size()));
2081 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size()));
2082
Luke Huang70931aa2019-01-31 11:57:41 +08002083 uint8_t smallBuf[1] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08002084 int rcode;
2085 rc = getAsyncResponse(fd, &rcode, smallBuf, 1);
Luke Huangba7bef92018-12-26 16:53:03 +08002086 EXPECT_EQ(-EMSGSIZE, rc);
Luke Huang94b10b92018-11-21 20:13:38 +08002087
2088 // Do the normal test with large buffer again
2089 fd = dns_open_proxy();
2090 EXPECT_TRUE(fd > 0);
2091 rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size()));
2092 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size()));
Luke Huang70931aa2019-01-31 11:57:41 +08002093 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08002094 rc = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
2095 EXPECT_EQ("1.2.3.4", toString(buf, rc, AF_INET));
Mike Yu4f3747b2018-12-02 17:54:29 +09002096}
2097
Luke Huangba7bef92018-12-26 16:53:03 +08002098TEST_F(ResolverTest, Async_CacheFlags) {
Xiao Ma09b71022018-12-11 17:56:32 +09002099 constexpr char listen_addr[] = "127.0.0.4";
2100 constexpr char host_name[] = "howdy.example.com.";
Luke Huang40f5f492019-05-09 19:37:35 +08002101 constexpr char another_host_name[] = "howdy.example2.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002102 const std::vector<DnsRecord> records = {
2103 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2104 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
Luke Huang40f5f492019-05-09 19:37:35 +08002105 {another_host_name, ns_type::ns_t_a, "1.2.3.5"},
2106 {another_host_name, ns_type::ns_t_aaaa, "::1.2.3.5"},
Xiao Ma09b71022018-12-11 17:56:32 +09002107 };
2108
2109 test::DNSResponder dns(listen_addr);
2110 StartDns(dns, records);
Luke Huangba7bef92018-12-26 16:53:03 +08002111 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002112 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huangba7bef92018-12-26 16:53:03 +08002113
2114 // ANDROID_RESOLV_NO_CACHE_STORE
2115 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2116 ANDROID_RESOLV_NO_CACHE_STORE);
2117 EXPECT_TRUE(fd1 != -1);
2118 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2119 ANDROID_RESOLV_NO_CACHE_STORE);
2120 EXPECT_TRUE(fd2 != -1);
2121 int fd3 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2122 ANDROID_RESOLV_NO_CACHE_STORE);
2123 EXPECT_TRUE(fd3 != -1);
2124
2125 expectAnswersValid(fd3, AF_INET, "1.2.3.4");
2126 expectAnswersValid(fd2, AF_INET, "1.2.3.4");
2127 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
2128
2129 // No cache exists, expect 3 queries
2130 EXPECT_EQ(3U, GetNumQueries(dns, host_name));
2131
2132 // Re-query and cache
2133 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
2134
2135 EXPECT_TRUE(fd1 != -1);
2136
2137 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
2138
2139 // Now we have cache, expect 4 queries
2140 EXPECT_EQ(4U, GetNumQueries(dns, host_name));
2141
2142 // ANDROID_RESOLV_NO_CACHE_LOOKUP
2143 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2144 ANDROID_RESOLV_NO_CACHE_LOOKUP);
2145 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2146 ANDROID_RESOLV_NO_CACHE_LOOKUP);
2147
2148 EXPECT_TRUE(fd1 != -1);
2149 EXPECT_TRUE(fd2 != -1);
2150
2151 expectAnswersValid(fd2, AF_INET, "1.2.3.4");
2152 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
2153
2154 // Skip cache, expect 6 queries
2155 EXPECT_EQ(6U, GetNumQueries(dns, host_name));
2156
2157 // Re-query verify cache works
2158 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2159 ANDROID_RESOLV_NO_CACHE_STORE);
2160 EXPECT_TRUE(fd1 != -1);
2161 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
2162
2163 // Cache hits, expect still 6 queries
2164 EXPECT_EQ(6U, GetNumQueries(dns, host_name));
Luke Huanga1d74182019-03-19 17:30:36 +08002165
2166 // Start to verify if ANDROID_RESOLV_NO_CACHE_LOOKUP does write response into cache
2167 dns.clearQueries();
2168
2169 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
2170 ANDROID_RESOLV_NO_CACHE_LOOKUP);
2171 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
2172 ANDROID_RESOLV_NO_CACHE_LOOKUP);
2173
2174 EXPECT_TRUE(fd1 != -1);
2175 EXPECT_TRUE(fd2 != -1);
2176
2177 expectAnswersValid(fd2, AF_INET6, "::1.2.3.4");
2178 expectAnswersValid(fd1, AF_INET6, "::1.2.3.4");
2179
2180 // Skip cache, expect 2 queries
2181 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
2182
2183 // Re-query without flags
2184 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
2185 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
2186
2187 EXPECT_TRUE(fd1 != -1);
2188 EXPECT_TRUE(fd2 != -1);
2189
2190 expectAnswersValid(fd2, AF_INET6, "::1.2.3.4");
2191 expectAnswersValid(fd1, AF_INET6, "::1.2.3.4");
2192
2193 // Cache hits, expect still 2 queries
2194 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
Luke Huang40f5f492019-05-09 19:37:35 +08002195
2196 // Test both ANDROID_RESOLV_NO_CACHE_STORE and ANDROID_RESOLV_NO_CACHE_LOOKUP are set
2197 dns.clearQueries();
2198
2199 // Make sure that the cache of "howdy.example2.com" exists.
2200 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_aaaa, 0);
2201 EXPECT_TRUE(fd1 != -1);
2202 expectAnswersValid(fd1, AF_INET6, "::1.2.3.5");
2203 EXPECT_EQ(1U, GetNumQueries(dns, another_host_name));
2204
2205 // Re-query with testFlags
2206 const int testFlag = ANDROID_RESOLV_NO_CACHE_STORE | ANDROID_RESOLV_NO_CACHE_LOOKUP;
2207 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_aaaa, testFlag);
2208 EXPECT_TRUE(fd1 != -1);
2209 expectAnswersValid(fd1, AF_INET6, "::1.2.3.5");
2210 // Expect cache lookup is skipped.
2211 EXPECT_EQ(2U, GetNumQueries(dns, another_host_name));
2212
2213 // Do another query with testFlags
2214 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_a, testFlag);
2215 EXPECT_TRUE(fd1 != -1);
2216 expectAnswersValid(fd1, AF_INET, "1.2.3.5");
2217 // Expect cache lookup is skipped.
2218 EXPECT_EQ(3U, GetNumQueries(dns, another_host_name));
2219
2220 // Re-query with no flags
2221 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_a, 0);
2222 EXPECT_TRUE(fd1 != -1);
2223 expectAnswersValid(fd1, AF_INET, "1.2.3.5");
2224 // Expect no cache hit because cache storing is also skipped in previous query.
2225 EXPECT_EQ(4U, GetNumQueries(dns, another_host_name));
Luke Huangba7bef92018-12-26 16:53:03 +08002226}
2227
2228TEST_F(ResolverTest, Async_NoRetryFlag) {
Luke Huang70931aa2019-01-31 11:57:41 +08002229 constexpr char listen_addr0[] = "127.0.0.4";
2230 constexpr char listen_addr1[] = "127.0.0.6";
Xiao Ma09b71022018-12-11 17:56:32 +09002231 constexpr char host_name[] = "howdy.example.com.";
2232 const std::vector<DnsRecord> records = {
2233 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2234 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
2235 };
2236
Luke Huang70931aa2019-01-31 11:57:41 +08002237 test::DNSResponder dns0(listen_addr0);
2238 test::DNSResponder dns1(listen_addr1);
2239 StartDns(dns0, records);
2240 StartDns(dns1, records);
2241 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr0, listen_addr1}));
Luke Huangba7bef92018-12-26 16:53:03 +08002242
Luke Huang70931aa2019-01-31 11:57:41 +08002243 dns0.clearQueries();
2244 dns1.clearQueries();
2245
2246 dns0.setResponseProbability(0.0);
2247 dns1.setResponseProbability(0.0);
Luke Huangba7bef92018-12-26 16:53:03 +08002248
2249 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2250 ANDROID_RESOLV_NO_RETRY);
2251 EXPECT_TRUE(fd1 != -1);
2252
2253 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
2254 ANDROID_RESOLV_NO_RETRY);
2255 EXPECT_TRUE(fd2 != -1);
2256
2257 // expect no response
2258 expectAnswersNotValid(fd1, -ETIMEDOUT);
2259 expectAnswersNotValid(fd2, -ETIMEDOUT);
2260
Luke Huang70931aa2019-01-31 11:57:41 +08002261 // No retry case, expect total 2 queries. The server is selected randomly.
2262 EXPECT_EQ(2U, GetNumQueries(dns0, host_name) + GetNumQueries(dns1, host_name));
Luke Huangba7bef92018-12-26 16:53:03 +08002263
Luke Huang70931aa2019-01-31 11:57:41 +08002264 dns0.clearQueries();
2265 dns1.clearQueries();
Luke Huangba7bef92018-12-26 16:53:03 +08002266
2267 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
2268 EXPECT_TRUE(fd1 != -1);
2269
2270 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
2271 EXPECT_TRUE(fd2 != -1);
2272
2273 // expect no response
2274 expectAnswersNotValid(fd1, -ETIMEDOUT);
2275 expectAnswersNotValid(fd2, -ETIMEDOUT);
2276
2277 // Retry case, expect 4 queries
Luke Huang70931aa2019-01-31 11:57:41 +08002278 EXPECT_EQ(4U, GetNumQueries(dns0, host_name));
2279 EXPECT_EQ(4U, GetNumQueries(dns1, host_name));
2280}
2281
2282TEST_F(ResolverTest, Async_VerifyQueryID) {
2283 constexpr char listen_addr[] = "127.0.0.4";
2284 constexpr char host_name[] = "howdy.example.com.";
2285 const std::vector<DnsRecord> records = {
2286 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2287 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
2288 };
2289
2290 test::DNSResponder dns(listen_addr);
2291 StartDns(dns, records);
2292 std::vector<std::string> servers = {listen_addr};
2293 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
2294
2295 const uint8_t queryBuf1[] = {
2296 /* Header */
2297 0x55, 0x66, /* Transaction ID */
2298 0x01, 0x00, /* Flags */
2299 0x00, 0x01, /* Questions */
2300 0x00, 0x00, /* Answer RRs */
2301 0x00, 0x00, /* Authority RRs */
2302 0x00, 0x00, /* Additional RRs */
2303 /* Queries */
2304 0x05, 0x68, 0x6f, 0x77, 0x64, 0x79, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
2305 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
2306 0x00, 0x01, /* Type */
2307 0x00, 0x01 /* Class */
2308 };
2309
2310 int fd = resNetworkSend(TEST_NETID, queryBuf1, sizeof(queryBuf1), 0);
2311 EXPECT_TRUE(fd != -1);
2312
2313 uint8_t buf[MAXPACKET] = {};
2314 int rcode;
2315
2316 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
2317 EXPECT_GT(res, 0);
2318 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
2319
2320 auto hp = reinterpret_cast<HEADER*>(buf);
2321 EXPECT_EQ(21862U, htons(hp->id));
2322
2323 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
2324
2325 const uint8_t queryBuf2[] = {
2326 /* Header */
2327 0x00, 0x53, /* Transaction ID */
2328 0x01, 0x00, /* Flags */
2329 0x00, 0x01, /* Questions */
2330 0x00, 0x00, /* Answer RRs */
2331 0x00, 0x00, /* Authority RRs */
2332 0x00, 0x00, /* Additional RRs */
2333 /* Queries */
2334 0x05, 0x68, 0x6f, 0x77, 0x64, 0x79, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
2335 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
2336 0x00, 0x01, /* Type */
2337 0x00, 0x01 /* Class */
2338 };
2339
2340 // Re-query verify cache works and query id is correct
2341 fd = resNetworkSend(TEST_NETID, queryBuf2, sizeof(queryBuf2), 0);
2342
2343 EXPECT_TRUE(fd != -1);
2344
2345 res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
2346 EXPECT_GT(res, 0);
2347 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
2348
2349 EXPECT_EQ(0x0053U, htons(hp->id));
2350
2351 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
Luke Huangba7bef92018-12-26 16:53:03 +08002352}
2353
Mike Yu4f3747b2018-12-02 17:54:29 +09002354// This test checks that the resolver should not generate the request containing OPT RR when using
Ken Chen0a015532019-01-02 14:59:38 +08002355// cleartext DNS. If we query the DNS server not supporting EDNS0 and it reponds with
2356// FORMERR_ON_EDNS, we will fallback to no EDNS0 and try again. If the server does no response, we
2357// won't retry so that we get no answer.
Mike Yu4f3747b2018-12-02 17:54:29 +09002358TEST_F(ResolverTest, BrokenEdns) {
2359 typedef test::DNSResponder::Edns Edns;
2360 enum ExpectResult { EXPECT_FAILURE, EXPECT_SUCCESS };
2361
2362 const char OFF[] = "off";
2363 const char OPPORTUNISTIC_UDP[] = "opportunistic_udp";
2364 const char OPPORTUNISTIC_TLS[] = "opportunistic_tls";
2365 const char STRICT[] = "strict";
2366 const char GETHOSTBYNAME[] = "gethostbyname";
2367 const char GETADDRINFO[] = "getaddrinfo";
Mike Yu4f3747b2018-12-02 17:54:29 +09002368 const char ADDR4[] = "192.0.2.1";
2369 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2370 const char CLEARTEXT_PORT[] = "53";
2371 const char TLS_PORT[] = "853";
Luke Huangf8215372019-11-22 11:53:41 +08002372 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
Mike Yu4f3747b2018-12-02 17:54:29 +09002373
Mike Yufc125e42019-05-15 20:41:28 +08002374 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, ns_rcode::ns_r_servfail);
Mike Yu4f3747b2018-12-02 17:54:29 +09002375 ASSERT_TRUE(dns.startServer());
2376
2377 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2378
Luke Huangf8215372019-11-22 11:53:41 +08002379 // clang-format off
Mike Yu4f3747b2018-12-02 17:54:29 +09002380 static const struct TestConfig {
2381 std::string mode;
2382 std::string method;
2383 Edns edns;
2384 ExpectResult expectResult;
2385
2386 std::string asHostName() const {
2387 const char* ednsString;
2388 switch (edns) {
2389 case Edns::ON:
2390 ednsString = "ednsOn";
2391 break;
Ken Chen0a015532019-01-02 14:59:38 +08002392 case Edns::FORMERR_ON_EDNS:
Mike Yu4f3747b2018-12-02 17:54:29 +09002393 ednsString = "ednsFormerr";
2394 break;
2395 case Edns::DROP:
2396 ednsString = "ednsDrop";
2397 break;
2398 default:
2399 ednsString = "";
2400 break;
2401 }
2402 return StringPrintf("%s.%s.%s.", mode.c_str(), method.c_str(), ednsString);
2403 }
2404 } testConfigs[] = {
2405 // In OPPORTUNISTIC_TLS, we get no answer if the DNS server supports TLS but not EDNS0.
2406 // Could such server exist? if so, we might need to fallback to query cleartext DNS.
2407 // Another thing is that {OPPORTUNISTIC_TLS, Edns::DROP} and {STRICT, Edns::DROP} are
2408 // commented out since TLS timeout is not configurable.
2409 // TODO: Uncomment them after TLS timeout is configurable.
2410 {OFF, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2411 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2412 {OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2413 {STRICT, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
Ken Chen0a015532019-01-02 14:59:38 +08002414 {OFF, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2415 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2416 {OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
2417 {STRICT, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
Mike Yu4f3747b2018-12-02 17:54:29 +09002418 {OFF, GETHOSTBYNAME, Edns::DROP, EXPECT_SUCCESS},
2419 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::DROP, EXPECT_SUCCESS},
2420 //{OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::DROP, EXPECT_FAILURE},
2421 //{STRICT, GETHOSTBYNAME, Edns::DROP, EXPECT_FAILURE},
2422 {OFF, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2423 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2424 {OPPORTUNISTIC_TLS, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2425 {STRICT, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
Ken Chen0a015532019-01-02 14:59:38 +08002426 {OFF, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2427 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2428 {OPPORTUNISTIC_TLS, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
2429 {STRICT, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
Mike Yu4f3747b2018-12-02 17:54:29 +09002430 {OFF, GETADDRINFO, Edns::DROP, EXPECT_SUCCESS},
2431 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::DROP, EXPECT_SUCCESS},
2432 //{OPPORTUNISTIC_TLS, GETADDRINFO, Edns::DROP, EXPECT_FAILURE},
2433 //{STRICT, GETADDRINFO, Edns::DROP, EXPECT_FAILURE},
2434 };
Luke Huangf8215372019-11-22 11:53:41 +08002435 // clang-format on
Mike Yu4f3747b2018-12-02 17:54:29 +09002436
2437 for (const auto& config : testConfigs) {
2438 const std::string testHostName = config.asHostName();
2439 SCOPED_TRACE(testHostName);
2440
2441 const char* host_name = testHostName.c_str();
2442 dns.addMapping(host_name, ns_type::ns_t_a, ADDR4);
2443 dns.setEdns(config.edns);
2444
2445 if (config.mode == OFF) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002446 if (tls.running()) {
2447 ASSERT_TRUE(tls.stopServer());
2448 }
Xiao Ma09b71022018-12-11 17:56:32 +09002449 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Mike Yu4f3747b2018-12-02 17:54:29 +09002450 } else if (config.mode == OPPORTUNISTIC_UDP) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002451 if (tls.running()) {
2452 ASSERT_TRUE(tls.stopServer());
2453 }
Xiao Ma09b71022018-12-11 17:56:32 +09002454 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08002455 kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002456 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), false));
Mike Yu4f3747b2018-12-02 17:54:29 +09002457 } else if (config.mode == OPPORTUNISTIC_TLS) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002458 if (!tls.running()) {
2459 ASSERT_TRUE(tls.startServer());
2460 }
Xiao Ma09b71022018-12-11 17:56:32 +09002461 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08002462 kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002463 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yu4f3747b2018-12-02 17:54:29 +09002464 } else if (config.mode == STRICT) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002465 if (!tls.running()) {
2466 ASSERT_TRUE(tls.startServer());
2467 }
Xiao Ma09b71022018-12-11 17:56:32 +09002468 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08002469 kDefaultParams, kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08002470 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yu4f3747b2018-12-02 17:54:29 +09002471 }
2472
2473 if (config.method == GETHOSTBYNAME) {
2474 const hostent* h_result = gethostbyname(host_name);
2475 if (config.expectResult == EXPECT_SUCCESS) {
2476 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2477 ASSERT_TRUE(h_result != nullptr);
2478 ASSERT_EQ(4, h_result->h_length);
2479 ASSERT_FALSE(h_result->h_addr_list[0] == nullptr);
2480 EXPECT_EQ(ADDR4, ToString(h_result));
2481 EXPECT_TRUE(h_result->h_addr_list[1] == nullptr);
2482 } else {
2483 EXPECT_EQ(0U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
2484 ASSERT_TRUE(h_result == nullptr);
2485 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2486 }
2487 } else if (config.method == GETADDRINFO) {
2488 ScopedAddrinfo ai_result;
2489 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2490 ai_result = safe_getaddrinfo(host_name, nullptr, &hints);
2491 if (config.expectResult == EXPECT_SUCCESS) {
2492 EXPECT_TRUE(ai_result != nullptr);
2493 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
2494 const std::string result_str = ToString(ai_result);
2495 EXPECT_EQ(ADDR4, result_str);
2496 } else {
2497 EXPECT_TRUE(ai_result == nullptr);
2498 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
2499 }
2500 } else {
2501 FAIL() << "Unsupported query method: " << config.method;
2502 }
2503
Mike Yudd4ac2d2019-05-31 16:52:11 +08002504 tls.clearQueries();
Mike Yu4f3747b2018-12-02 17:54:29 +09002505 dns.clearQueries();
2506 }
Mike Yu4f3747b2018-12-02 17:54:29 +09002507}
nuccachena26cc2a2018-07-17 18:07:23 +08002508
Ken Chen0a015532019-01-02 14:59:38 +08002509// DNS-over-TLS validation success, but server does not respond to TLS query after a while.
2510// Resolver should have a reasonable number of retries instead of spinning forever. We don't have
2511// an efficient way to know if resolver is stuck in an infinite loop. However, test case will be
2512// failed due to timeout.
2513TEST_F(ResolverTest, UnstableTls) {
2514 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2515 const char CLEARTEXT_PORT[] = "53";
2516 const char TLS_PORT[] = "853";
2517 const char* host_name1 = "nonexistent1.example.com.";
2518 const char* host_name2 = "nonexistent2.example.com.";
2519 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
2520
Mike Yufc125e42019-05-15 20:41:28 +08002521 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, ns_rcode::ns_r_servfail);
Ken Chen0a015532019-01-02 14:59:38 +08002522 ASSERT_TRUE(dns.startServer());
2523 dns.setEdns(test::DNSResponder::Edns::FORMERR_ON_EDNS);
2524 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2525 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08002526 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002527 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
2528
Ken Chen0a015532019-01-02 14:59:38 +08002529 // Shutdown TLS server to get an error. It's similar to no response case but without waiting.
2530 tls.stopServer();
2531
2532 const hostent* h_result = gethostbyname(host_name1);
2533 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
2534 ASSERT_TRUE(h_result == nullptr);
2535 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2536
2537 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2538 ScopedAddrinfo ai_result = safe_getaddrinfo(host_name2, nullptr, &hints);
2539 EXPECT_TRUE(ai_result == nullptr);
2540 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
2541}
2542
2543// DNS-over-TLS validation success, but server does not respond to TLS query after a while.
2544// Moreover, server responds RCODE=FORMERR even on non-EDNS query.
2545TEST_F(ResolverTest, BogusDnsServer) {
2546 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2547 const char CLEARTEXT_PORT[] = "53";
2548 const char TLS_PORT[] = "853";
2549 const char* host_name1 = "nonexistent1.example.com.";
2550 const char* host_name2 = "nonexistent2.example.com.";
2551 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
2552
Mike Yufc125e42019-05-15 20:41:28 +08002553 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, ns_rcode::ns_r_servfail);
Ken Chen0a015532019-01-02 14:59:38 +08002554 ASSERT_TRUE(dns.startServer());
2555 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2556 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08002557 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002558 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
2559
Ken Chen0a015532019-01-02 14:59:38 +08002560 // Shutdown TLS server to get an error. It's similar to no response case but without waiting.
2561 tls.stopServer();
2562 dns.setEdns(test::DNSResponder::Edns::FORMERR_UNCOND);
2563
2564 const hostent* h_result = gethostbyname(host_name1);
2565 EXPECT_EQ(0U, GetNumQueries(dns, host_name1));
2566 ASSERT_TRUE(h_result == nullptr);
2567 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2568
2569 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2570 ScopedAddrinfo ai_result = safe_getaddrinfo(host_name2, nullptr, &hints);
2571 EXPECT_TRUE(ai_result == nullptr);
2572 EXPECT_EQ(0U, GetNumQueries(dns, host_name2));
2573}
2574
nuccachena26cc2a2018-07-17 18:07:23 +08002575TEST_F(ResolverTest, GetAddrInfo_Dns64Synthesize) {
2576 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002577 constexpr char dns64_name[] = "ipv4only.arpa.";
2578 constexpr char host_name[] = "v4only.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002579 const std::vector<DnsRecord> records = {
2580 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2581 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2582 };
nuccachena26cc2a2018-07-17 18:07:23 +08002583
Xiao Ma09b71022018-12-11 17:56:32 +09002584 test::DNSResponder dns(listen_addr);
Xiao Ma09b71022018-12-11 17:56:32 +09002585 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002586
2587 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002588 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002589
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002590 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002591 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002592 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002593
2594 // hints are necessary in order to let netd know which type of addresses the caller is
2595 // interested in.
Xiao Ma09b71022018-12-11 17:56:32 +09002596 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachena26cc2a2018-07-17 18:07:23 +08002597 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, &hints);
2598 EXPECT_TRUE(result != nullptr);
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002599 // TODO: BUG: there should only be two queries, one AAAA (which returns no records) and one A
2600 // (which returns 1.2.3.4). But there is an extra AAAA.
2601 EXPECT_EQ(3U, GetNumQueries(dns, host_name));
nuccachena26cc2a2018-07-17 18:07:23 +08002602
2603 std::string result_str = ToString(result);
2604 EXPECT_EQ(result_str, "64:ff9b::102:304");
2605
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002606 // Stopping NAT64 prefix discovery disables synthesis.
Luke Huang5bd827c2019-03-14 16:10:04 +08002607 EXPECT_TRUE(mDnsClient.resolvService()->stopPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002608 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_NOT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002609
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002610 dns.clearQueries();
nuccachena26cc2a2018-07-17 18:07:23 +08002611
2612 result = safe_getaddrinfo("v4only", nullptr, &hints);
2613 EXPECT_TRUE(result != nullptr);
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002614 // TODO: BUG: there should only be one query, an AAAA (which returns no records), because the
2615 // A is already cached. But there is an extra AAAA.
2616 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
nuccachena26cc2a2018-07-17 18:07:23 +08002617
2618 result_str = ToString(result);
2619 EXPECT_EQ(result_str, "1.2.3.4");
2620}
2621
nuccachena26cc2a2018-07-17 18:07:23 +08002622TEST_F(ResolverTest, GetAddrInfo_Dns64QuerySpecified) {
2623 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002624 constexpr char dns64_name[] = "ipv4only.arpa.";
2625 constexpr char host_name[] = "v4only.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002626 const std::vector<DnsRecord> records = {
2627 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2628 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2629 };
nuccachena26cc2a2018-07-17 18:07:23 +08002630
Xiao Ma09b71022018-12-11 17:56:32 +09002631 test::DNSResponder dns(listen_addr);
2632 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002633 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002634 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002635
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002636 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002637 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002638 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002639
2640 // Ensure to synthesize AAAA if AF_INET6 is specified, and not to synthesize AAAA
2641 // in AF_INET case.
2642 addrinfo hints;
2643 memset(&hints, 0, sizeof(hints));
2644 hints.ai_family = AF_INET6;
2645 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, &hints);
2646 EXPECT_TRUE(result != nullptr);
2647 std::string result_str = ToString(result);
2648 EXPECT_EQ(result_str, "64:ff9b::102:304");
2649
2650 hints.ai_family = AF_INET;
2651 result = safe_getaddrinfo("v4only", nullptr, &hints);
2652 EXPECT_TRUE(result != nullptr);
2653 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2654 result_str = ToString(result);
2655 EXPECT_EQ(result_str, "1.2.3.4");
2656}
nuccachena26cc2a2018-07-17 18:07:23 +08002657
2658TEST_F(ResolverTest, GetAddrInfo_Dns64QueryUnspecifiedV6) {
2659 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002660 constexpr char dns64_name[] = "ipv4only.arpa.";
2661 constexpr char host_name[] = "v4v6.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002662 const std::vector<DnsRecord> records = {
2663 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2664 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2665 {host_name, 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
Xiao Ma09b71022018-12-11 17:56:32 +09002677 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachena26cc2a2018-07-17 18:07:23 +08002678 ScopedAddrinfo result = safe_getaddrinfo("v4v6", nullptr, &hints);
2679 EXPECT_TRUE(result != nullptr);
2680 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2681
2682 // In AF_UNSPEC case, do not synthesize AAAA if there's at least one AAAA answer.
Xiao Ma09b71022018-12-11 17:56:32 +09002683 const std::vector<std::string> result_strs = ToStrings(result);
nuccachena26cc2a2018-07-17 18:07:23 +08002684 for (const auto& str : result_strs) {
2685 EXPECT_TRUE(str == "1.2.3.4" || str == "2001:db8::102:304")
2686 << ", result_str='" << str << "'";
2687 }
2688}
2689
2690TEST_F(ResolverTest, GetAddrInfo_Dns64QueryUnspecifiedNoV6) {
2691 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002692 constexpr char dns64_name[] = "ipv4only.arpa.";
2693 constexpr char host_name[] = "v4v6.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002694 const std::vector<DnsRecord> records = {
2695 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2696 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2697 };
nuccachena26cc2a2018-07-17 18:07:23 +08002698
Xiao Ma09b71022018-12-11 17:56:32 +09002699 test::DNSResponder dns(listen_addr);
2700 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002701 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002702 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002703
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002704 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002705 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002706 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002707
Xiao Ma09b71022018-12-11 17:56:32 +09002708 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachena26cc2a2018-07-17 18:07:23 +08002709 ScopedAddrinfo result = safe_getaddrinfo("v4v6", nullptr, &hints);
2710 EXPECT_TRUE(result != nullptr);
2711 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2712
2713 // In AF_UNSPEC case, synthesize AAAA if there's no AAAA answer.
2714 std::string result_str = ToString(result);
2715 EXPECT_EQ(result_str, "64:ff9b::102:304");
2716}
2717
2718TEST_F(ResolverTest, GetAddrInfo_Dns64QuerySpecialUseIPv4Addresses) {
2719 constexpr char THIS_NETWORK[] = "this_network";
2720 constexpr char LOOPBACK[] = "loopback";
2721 constexpr char LINK_LOCAL[] = "link_local";
2722 constexpr char MULTICAST[] = "multicast";
2723 constexpr char LIMITED_BROADCAST[] = "limited_broadcast";
2724
2725 constexpr char ADDR_THIS_NETWORK[] = "0.0.0.1";
2726 constexpr char ADDR_LOOPBACK[] = "127.0.0.1";
2727 constexpr char ADDR_LINK_LOCAL[] = "169.254.0.1";
2728 constexpr char ADDR_MULTICAST[] = "224.0.0.1";
2729 constexpr char ADDR_LIMITED_BROADCAST[] = "255.255.255.255";
2730
2731 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002732 constexpr char dns64_name[] = "ipv4only.arpa.";
2733
Xiao Ma09b71022018-12-11 17:56:32 +09002734 test::DNSResponder dns(listen_addr);
2735 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachena26cc2a2018-07-17 18:07:23 +08002736 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002737 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002738
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002739 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002740 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002741 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002742
Luke Huangf8215372019-11-22 11:53:41 +08002743 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08002744 static const struct TestConfig {
2745 std::string name;
2746 std::string addr;
2747
2748 std::string asHostName() const { return StringPrintf("%s.example.com.", name.c_str()); }
2749 } testConfigs[]{
2750 {THIS_NETWORK, ADDR_THIS_NETWORK},
2751 {LOOPBACK, ADDR_LOOPBACK},
2752 {LINK_LOCAL, ADDR_LINK_LOCAL},
2753 {MULTICAST, ADDR_MULTICAST},
2754 {LIMITED_BROADCAST, ADDR_LIMITED_BROADCAST}
2755 };
Luke Huangf8215372019-11-22 11:53:41 +08002756 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08002757
2758 for (const auto& config : testConfigs) {
2759 const std::string testHostName = config.asHostName();
2760 SCOPED_TRACE(testHostName);
2761
2762 const char* host_name = testHostName.c_str();
2763 dns.addMapping(host_name, ns_type::ns_t_a, config.addr.c_str());
2764
2765 addrinfo hints;
2766 memset(&hints, 0, sizeof(hints));
2767 hints.ai_family = AF_INET6;
2768 ScopedAddrinfo result = safe_getaddrinfo(config.name.c_str(), nullptr, &hints);
2769 // In AF_INET6 case, don't return IPv4 answers
2770 EXPECT_TRUE(result == nullptr);
2771 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2772 dns.clearQueries();
2773
2774 memset(&hints, 0, sizeof(hints));
2775 hints.ai_family = AF_UNSPEC;
2776 result = safe_getaddrinfo(config.name.c_str(), nullptr, &hints);
2777 EXPECT_TRUE(result != nullptr);
2778 // Expect IPv6 query only. IPv4 answer has been cached in previous query.
2779 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2780 // In AF_UNSPEC case, don't synthesize special use IPv4 address.
2781 std::string result_str = ToString(result);
2782 EXPECT_EQ(result_str, config.addr.c_str());
2783 dns.clearQueries();
2784 }
2785}
2786
2787TEST_F(ResolverTest, GetAddrInfo_Dns64QueryWithNullArgumentHints) {
2788 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002789 constexpr char dns64_name[] = "ipv4only.arpa.";
2790 constexpr char host_name[] = "v4only.example.com.";
2791 constexpr char host_name2[] = "v4v6.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002792 const std::vector<DnsRecord> records = {
2793 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2794 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2795 {host_name2, ns_type::ns_t_a, "1.2.3.4"},
2796 {host_name2, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
2797 };
nuccachena26cc2a2018-07-17 18:07:23 +08002798
Xiao Ma09b71022018-12-11 17:56:32 +09002799 test::DNSResponder dns(listen_addr);
2800 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002801 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002802 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002803
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002804 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002805 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002806 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002807
2808 // Assign argument hints of getaddrinfo() as null is equivalent to set ai_family AF_UNSPEC.
2809 // In AF_UNSPEC case, synthesize AAAA if there has A answer only.
2810 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, nullptr);
2811 EXPECT_TRUE(result != nullptr);
2812 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2813 std::string result_str = ToString(result);
2814 EXPECT_EQ(result_str, "64:ff9b::102:304");
2815 dns.clearQueries();
2816
2817 // In AF_UNSPEC case, do not synthesize AAAA if there's at least one AAAA answer.
2818 result = safe_getaddrinfo("v4v6", nullptr, nullptr);
2819 EXPECT_TRUE(result != nullptr);
2820 EXPECT_LE(2U, GetNumQueries(dns, host_name2));
2821 std::vector<std::string> result_strs = ToStrings(result);
2822 for (const auto& str : result_strs) {
2823 EXPECT_TRUE(str == "1.2.3.4" || str == "2001:db8::102:304")
2824 << ", result_str='" << str << "'";
2825 }
2826}
2827
2828TEST_F(ResolverTest, GetAddrInfo_Dns64QueryNullArgumentNode) {
2829 constexpr char ADDR_ANYADDR_V4[] = "0.0.0.0";
2830 constexpr char ADDR_ANYADDR_V6[] = "::";
2831 constexpr char ADDR_LOCALHOST_V4[] = "127.0.0.1";
2832 constexpr char ADDR_LOCALHOST_V6[] = "::1";
2833
2834 constexpr char PORT_NAME_HTTP[] = "http";
2835 constexpr char PORT_NUMBER_HTTP[] = "80";
2836
2837 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002838 constexpr char dns64_name[] = "ipv4only.arpa.";
2839
Xiao Ma09b71022018-12-11 17:56:32 +09002840 test::DNSResponder dns(listen_addr);
2841 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachena26cc2a2018-07-17 18:07:23 +08002842 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002843 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002844
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002845 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002846 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002847 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002848
Luke Huangf8215372019-11-22 11:53:41 +08002849 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08002850 // If node is null, return address is listed by libc/getaddrinfo.c as follows.
2851 // - passive socket -> anyaddr (0.0.0.0 or ::)
2852 // - non-passive socket -> localhost (127.0.0.1 or ::1)
2853 static const struct TestConfig {
2854 int flag;
2855 std::string addr_v4;
2856 std::string addr_v6;
2857
2858 std::string asParameters() const {
2859 return StringPrintf("flag=%d, addr_v4=%s, addr_v6=%s", flag, addr_v4.c_str(),
2860 addr_v6.c_str());
2861 }
2862 } testConfigs[]{
2863 {0 /* non-passive */, ADDR_LOCALHOST_V4, ADDR_LOCALHOST_V6},
2864 {AI_PASSIVE, ADDR_ANYADDR_V4, ADDR_ANYADDR_V6}
2865 };
Luke Huangf8215372019-11-22 11:53:41 +08002866 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08002867
2868 for (const auto& config : testConfigs) {
2869 SCOPED_TRACE(config.asParameters());
2870
Xiao Ma09b71022018-12-11 17:56:32 +09002871 addrinfo hints = {
Nick Desaulnierscd6395a2019-10-11 09:15:24 -07002872 .ai_flags = config.flag,
Xiao Ma09b71022018-12-11 17:56:32 +09002873 .ai_family = AF_UNSPEC, // any address family
2874 .ai_socktype = 0, // any type
2875 .ai_protocol = 0, // any protocol
Xiao Ma09b71022018-12-11 17:56:32 +09002876 };
nuccachena26cc2a2018-07-17 18:07:23 +08002877
2878 // Assign hostname as null and service as port name.
2879 ScopedAddrinfo result = safe_getaddrinfo(nullptr, PORT_NAME_HTTP, &hints);
2880 ASSERT_TRUE(result != nullptr);
2881
2882 // Can't be synthesized because it should not get into Netd.
2883 std::vector<std::string> result_strs = ToStrings(result);
2884 for (const auto& str : result_strs) {
2885 EXPECT_TRUE(str == config.addr_v4 || str == config.addr_v6)
2886 << ", result_str='" << str << "'";
2887 }
2888
2889 // Assign hostname as null and service as numeric port number.
2890 hints.ai_flags = config.flag | AI_NUMERICSERV;
2891 result = safe_getaddrinfo(nullptr, PORT_NUMBER_HTTP, &hints);
2892 ASSERT_TRUE(result != nullptr);
2893
2894 // Can't be synthesized because it should not get into Netd.
2895 result_strs = ToStrings(result);
2896 for (const auto& str : result_strs) {
2897 EXPECT_TRUE(str == config.addr_v4 || str == config.addr_v6)
2898 << ", result_str='" << str << "'";
2899 }
2900 }
2901}
2902
2903TEST_F(ResolverTest, GetHostByAddr_ReverseDnsQueryWithHavingNat64Prefix) {
2904 struct hostent* result = nullptr;
2905 struct in_addr v4addr;
2906 struct in6_addr v6addr;
2907
2908 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002909 constexpr char dns64_name[] = "ipv4only.arpa.";
2910 constexpr char ptr_name[] = "v4v6.example.com.";
2911 // PTR record for IPv4 address 1.2.3.4
2912 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2913 // PTR record for IPv6 address 2001:db8::102:304
2914 constexpr char ptr_addr_v6[] =
2915 "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 +09002916 const std::vector<DnsRecord> records = {
2917 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2918 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2919 {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name},
2920 };
nuccachena26cc2a2018-07-17 18:07:23 +08002921
Xiao Ma09b71022018-12-11 17:56:32 +09002922 test::DNSResponder dns(listen_addr);
2923 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002924 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002925 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002926
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002927 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002928 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002929 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002930
2931 // Reverse IPv4 DNS query. Prefix should have no effect on it.
2932 inet_pton(AF_INET, "1.2.3.4", &v4addr);
2933 result = gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET);
2934 ASSERT_TRUE(result != nullptr);
2935 std::string result_str = result->h_name ? result->h_name : "null";
2936 EXPECT_EQ(result_str, "v4v6.example.com");
2937
2938 // Reverse IPv6 DNS query. Prefix should have no effect on it.
2939 inet_pton(AF_INET6, "2001:db8::102:304", &v6addr);
2940 result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2941 ASSERT_TRUE(result != nullptr);
2942 result_str = result->h_name ? result->h_name : "null";
2943 EXPECT_EQ(result_str, "v4v6.example.com");
2944}
2945
2946TEST_F(ResolverTest, GetHostByAddr_ReverseDns64Query) {
2947 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002948 constexpr char dns64_name[] = "ipv4only.arpa.";
2949 constexpr char ptr_name[] = "v4only.example.com.";
2950 // PTR record for IPv4 address 1.2.3.4
2951 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2952 // PTR record for IPv6 address 64:ff9b::1.2.3.4
2953 constexpr char ptr_addr_v6_nomapping[] =
2954 "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.";
2955 constexpr char ptr_name_v6_synthesis[] = "v6synthesis.example.com.";
2956 // PTR record for IPv6 address 64:ff9b::5.6.7.8
2957 constexpr char ptr_addr_v6_synthesis[] =
2958 "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 +09002959 const std::vector<DnsRecord> records = {
2960 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2961 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2962 {ptr_addr_v6_synthesis, ns_type::ns_t_ptr, ptr_name_v6_synthesis},
2963 };
nuccachena26cc2a2018-07-17 18:07:23 +08002964
Xiao Ma09b71022018-12-11 17:56:32 +09002965 test::DNSResponder dns(listen_addr);
2966 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002967 // "ptr_addr_v6_nomapping" is not mapped in DNS server
nuccachena26cc2a2018-07-17 18:07:23 +08002968 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002969 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002970
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002971 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002972 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002973 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002974
2975 // Synthesized PTR record doesn't exist on DNS server
2976 // Reverse IPv6 DNS64 query while DNS server doesn't have an answer for synthesized address.
2977 // After querying synthesized address failed, expect that prefix is removed from IPv6
2978 // synthesized address and do reverse IPv4 query instead.
2979 struct in6_addr v6addr;
2980 inet_pton(AF_INET6, "64:ff9b::1.2.3.4", &v6addr);
2981 struct hostent* result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2982 ASSERT_TRUE(result != nullptr);
2983 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_nomapping)); // PTR record not exist
2984 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4)); // PTR record exist
2985 std::string result_str = result->h_name ? result->h_name : "null";
2986 EXPECT_EQ(result_str, "v4only.example.com");
2987 // Check that return address has been mapped from IPv4 to IPv6 address because Netd
2988 // removes NAT64 prefix and does IPv4 DNS reverse lookup in this case. Then, Netd
2989 // fakes the return IPv4 address as original queried IPv6 address.
2990 result_str = ToString(result);
2991 EXPECT_EQ(result_str, "64:ff9b::102:304");
2992 dns.clearQueries();
2993
2994 // Synthesized PTR record exists on DNS server
2995 // Reverse IPv6 DNS64 query while DNS server has an answer for synthesized address.
2996 // Expect to Netd pass through synthesized address for DNS queries.
2997 inet_pton(AF_INET6, "64:ff9b::5.6.7.8", &v6addr);
2998 result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2999 ASSERT_TRUE(result != nullptr);
3000 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_synthesis));
3001 result_str = result->h_name ? result->h_name : "null";
3002 EXPECT_EQ(result_str, "v6synthesis.example.com");
3003}
3004
3005TEST_F(ResolverTest, GetHostByAddr_ReverseDns64QueryFromHostFile) {
3006 constexpr char dns64_name[] = "ipv4only.arpa.";
3007 constexpr char host_name[] = "localhost";
3008 // The address is synthesized by prefix64:localhost.
3009 constexpr char host_addr[] = "64:ff9b::7f00:1";
nuccachena26cc2a2018-07-17 18:07:23 +08003010 constexpr char listen_addr[] = "::1";
Xiao Ma09b71022018-12-11 17:56:32 +09003011
3012 test::DNSResponder dns(listen_addr);
3013 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
nuccachena26cc2a2018-07-17 18:07:23 +08003014 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003015 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003016
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003017 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003018 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003019 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003020
3021 // Using synthesized "localhost" address to be a trick for resolving host name
3022 // from host file /etc/hosts and "localhost" is the only name in /etc/hosts. Note that this is
3023 // not realistic: the code never synthesizes AAAA records for addresses in 127.0.0.0/8.
3024 struct in6_addr v6addr;
3025 inet_pton(AF_INET6, host_addr, &v6addr);
3026 struct hostent* result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
3027 ASSERT_TRUE(result != nullptr);
3028 // Expect no DNS queries; localhost is resolved via /etc/hosts.
3029 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
3030
Luke Huangf8215372019-11-22 11:53:41 +08003031 ASSERT_EQ(sizeof(in6_addr), (unsigned)result->h_length);
nuccachena26cc2a2018-07-17 18:07:23 +08003032 ASSERT_EQ(AF_INET6, result->h_addrtype);
3033 std::string result_str = ToString(result);
3034 EXPECT_EQ(result_str, host_addr);
3035 result_str = result->h_name ? result->h_name : "null";
3036 EXPECT_EQ(result_str, host_name);
3037}
3038
Hungming Chen9e6185a2019-06-04 16:09:19 +08003039TEST_F(ResolverTest, GetHostByAddr_cnamesClasslessReverseDelegation) {
3040 // IPv4 addresses in the subnet with notation '/' or '-'.
3041 constexpr char addr_slash[] = "192.0.2.1";
3042 constexpr char addr_hyphen[] = "192.0.3.1";
3043
3044 // Used to verify DNS reverse query for classless reverse lookup zone. See detail in RFC 2317
3045 // section 4.
3046 const static std::vector<DnsRecord> records = {
3047 // The records for reverse querying "192.0.2.1" in the subnet with notation '/'.
3048 {"1.2.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0/25.2.0.192.in-addr.arpa."},
3049 {"1.0/25.2.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
3050
3051 // The records for reverse querying "192.0.3.1" in the subnet with notation '-'.
3052 {"1.3.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0-127.3.0.192.in-addr.arpa."},
3053 {"1.0-127.3.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
3054 };
3055
3056 test::DNSResponder dns;
3057 StartDns(dns, records);
3058 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3059
3060 for (const auto& address : {addr_slash, addr_hyphen}) {
3061 SCOPED_TRACE(address);
3062
3063 in_addr v4addr;
3064 ASSERT_TRUE(inet_pton(AF_INET, address, &v4addr));
3065 hostent* result = gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET);
3066 ASSERT_TRUE(result != nullptr);
3067 EXPECT_STREQ("hello.example.com", result->h_name);
3068 }
3069}
3070
nuccachena26cc2a2018-07-17 18:07:23 +08003071TEST_F(ResolverTest, GetNameInfo_ReverseDnsQueryWithHavingNat64Prefix) {
3072 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08003073 constexpr char dns64_name[] = "ipv4only.arpa.";
3074 constexpr char ptr_name[] = "v4v6.example.com.";
3075 // PTR record for IPv4 address 1.2.3.4
3076 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
3077 // PTR record for IPv6 address 2001:db8::102:304
3078 constexpr char ptr_addr_v6[] =
3079 "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 +09003080 const std::vector<DnsRecord> records = {
3081 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
3082 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
3083 {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name},
3084 };
nuccachena26cc2a2018-07-17 18:07:23 +08003085
Xiao Ma09b71022018-12-11 17:56:32 +09003086 test::DNSResponder dns(listen_addr);
3087 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08003088 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003089 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003090
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003091 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003092 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003093 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003094
Luke Huangf8215372019-11-22 11:53:41 +08003095 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08003096 static const struct TestConfig {
3097 int flag;
3098 int family;
3099 std::string addr;
3100 std::string host;
3101
3102 std::string asParameters() const {
3103 return StringPrintf("flag=%d, family=%d, addr=%s, host=%s", flag, family, addr.c_str(),
3104 host.c_str());
3105 }
3106 } testConfigs[]{
3107 {NI_NAMEREQD, AF_INET, "1.2.3.4", "v4v6.example.com"},
3108 {NI_NUMERICHOST, AF_INET, "1.2.3.4", "1.2.3.4"},
3109 {0, AF_INET, "1.2.3.4", "v4v6.example.com"},
3110 {0, AF_INET, "5.6.7.8", "5.6.7.8"}, // unmapped
3111 {NI_NAMEREQD, AF_INET6, "2001:db8::102:304", "v4v6.example.com"},
3112 {NI_NUMERICHOST, AF_INET6, "2001:db8::102:304", "2001:db8::102:304"},
3113 {0, AF_INET6, "2001:db8::102:304", "v4v6.example.com"},
3114 {0, AF_INET6, "2001:db8::506:708", "2001:db8::506:708"}, // unmapped
3115 };
Luke Huangf8215372019-11-22 11:53:41 +08003116 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08003117
3118 // Reverse IPv4/IPv6 DNS query. Prefix should have no effect on it.
3119 for (const auto& config : testConfigs) {
3120 SCOPED_TRACE(config.asParameters());
3121
3122 int rv;
3123 char host[NI_MAXHOST];
3124 struct sockaddr_in sin;
3125 struct sockaddr_in6 sin6;
3126 if (config.family == AF_INET) {
3127 memset(&sin, 0, sizeof(sin));
3128 sin.sin_family = AF_INET;
3129 inet_pton(AF_INET, config.addr.c_str(), &sin.sin_addr);
Luke Huangf8215372019-11-22 11:53:41 +08003130 rv = getnameinfo((const struct sockaddr*)&sin, sizeof(sin), host, sizeof(host), nullptr,
3131 0, config.flag);
nuccachena26cc2a2018-07-17 18:07:23 +08003132 if (config.flag == NI_NAMEREQD) EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4));
3133 } else if (config.family == AF_INET6) {
3134 memset(&sin6, 0, sizeof(sin6));
3135 sin6.sin6_family = AF_INET6;
3136 inet_pton(AF_INET6, config.addr.c_str(), &sin6.sin6_addr);
Luke Huangf8215372019-11-22 11:53:41 +08003137 rv = getnameinfo((const struct sockaddr*)&sin6, sizeof(sin6), host, sizeof(host),
nuccachena26cc2a2018-07-17 18:07:23 +08003138 nullptr, 0, config.flag);
3139 if (config.flag == NI_NAMEREQD) EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6));
3140 }
3141 ASSERT_EQ(0, rv);
3142 std::string result_str = host;
3143 EXPECT_EQ(result_str, config.host);
3144 dns.clearQueries();
3145 }
3146}
3147
3148TEST_F(ResolverTest, GetNameInfo_ReverseDns64Query) {
3149 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08003150 constexpr char dns64_name[] = "ipv4only.arpa.";
3151 constexpr char ptr_name[] = "v4only.example.com.";
3152 // PTR record for IPv4 address 1.2.3.4
3153 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
3154 // PTR record for IPv6 address 64:ff9b::1.2.3.4
3155 constexpr char ptr_addr_v6_nomapping[] =
3156 "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.";
3157 constexpr char ptr_name_v6_synthesis[] = "v6synthesis.example.com.";
3158 // PTR record for IPv6 address 64:ff9b::5.6.7.8
3159 constexpr char ptr_addr_v6_synthesis[] =
3160 "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 +09003161 const std::vector<DnsRecord> records = {
3162 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
3163 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
3164 {ptr_addr_v6_synthesis, ns_type::ns_t_ptr, ptr_name_v6_synthesis},
3165 };
nuccachena26cc2a2018-07-17 18:07:23 +08003166
Xiao Ma09b71022018-12-11 17:56:32 +09003167 test::DNSResponder dns(listen_addr);
3168 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08003169 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003170 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003171
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003172 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003173 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003174 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003175
Luke Huangf8215372019-11-22 11:53:41 +08003176 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08003177 static const struct TestConfig {
3178 bool hasSynthesizedPtrRecord;
3179 int flag;
3180 std::string addr;
3181 std::string host;
3182
3183 std::string asParameters() const {
3184 return StringPrintf("hasSynthesizedPtrRecord=%d, flag=%d, addr=%s, host=%s",
3185 hasSynthesizedPtrRecord, flag, addr.c_str(), host.c_str());
3186 }
3187 } testConfigs[]{
3188 {false, NI_NAMEREQD, "64:ff9b::102:304", "v4only.example.com"},
3189 {false, NI_NUMERICHOST, "64:ff9b::102:304", "64:ff9b::102:304"},
3190 {false, 0, "64:ff9b::102:304", "v4only.example.com"},
3191 {true, NI_NAMEREQD, "64:ff9b::506:708", "v6synthesis.example.com"},
3192 {true, NI_NUMERICHOST, "64:ff9b::506:708", "64:ff9b::506:708"},
3193 {true, 0, "64:ff9b::506:708", "v6synthesis.example.com"}
3194 };
Luke Huangf8215372019-11-22 11:53:41 +08003195 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08003196
3197 // hasSynthesizedPtrRecord = false
3198 // Synthesized PTR record doesn't exist on DNS server
3199 // Reverse IPv6 DNS64 query while DNS server doesn't have an answer for synthesized address.
3200 // After querying synthesized address failed, expect that prefix is removed from IPv6
3201 // synthesized address and do reverse IPv4 query instead.
3202 //
3203 // hasSynthesizedPtrRecord = true
3204 // Synthesized PTR record exists on DNS server
3205 // Reverse IPv6 DNS64 query while DNS server has an answer for synthesized address.
3206 // Expect to just pass through synthesized address for DNS queries.
3207 for (const auto& config : testConfigs) {
3208 SCOPED_TRACE(config.asParameters());
3209
3210 char host[NI_MAXHOST];
3211 struct sockaddr_in6 sin6;
3212 memset(&sin6, 0, sizeof(sin6));
3213 sin6.sin6_family = AF_INET6;
3214 inet_pton(AF_INET6, config.addr.c_str(), &sin6.sin6_addr);
Luke Huangf8215372019-11-22 11:53:41 +08003215 int rv = getnameinfo((const struct sockaddr*)&sin6, sizeof(sin6), host, sizeof(host),
nuccachena26cc2a2018-07-17 18:07:23 +08003216 nullptr, 0, config.flag);
3217 ASSERT_EQ(0, rv);
3218 if (config.flag == NI_NAMEREQD) {
3219 if (config.hasSynthesizedPtrRecord) {
3220 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_synthesis));
3221 } else {
3222 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_nomapping)); // PTR record not exist.
3223 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4)); // PTR record exist.
3224 }
3225 }
3226 std::string result_str = host;
3227 EXPECT_EQ(result_str, config.host);
3228 dns.clearQueries();
3229 }
3230}
3231
3232TEST_F(ResolverTest, GetNameInfo_ReverseDns64QueryFromHostFile) {
3233 constexpr char dns64_name[] = "ipv4only.arpa.";
3234 constexpr char host_name[] = "localhost";
3235 // The address is synthesized by prefix64:localhost.
3236 constexpr char host_addr[] = "64:ff9b::7f00:1";
nuccachena26cc2a2018-07-17 18:07:23 +08003237 constexpr char listen_addr[] = "::1";
Xiao Ma09b71022018-12-11 17:56:32 +09003238
3239 test::DNSResponder dns(listen_addr);
3240 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
nuccachena26cc2a2018-07-17 18:07:23 +08003241 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003242 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003243
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003244 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003245 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003246 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003247
3248 // Using synthesized "localhost" address to be a trick for resolving host name
3249 // from host file /etc/hosts and "localhost" is the only name in /etc/hosts. Note that this is
3250 // not realistic: the code never synthesizes AAAA records for addresses in 127.0.0.0/8.
3251 char host[NI_MAXHOST];
Xiao Ma09b71022018-12-11 17:56:32 +09003252 struct sockaddr_in6 sin6 = {.sin6_family = AF_INET6};
nuccachena26cc2a2018-07-17 18:07:23 +08003253 inet_pton(AF_INET6, host_addr, &sin6.sin6_addr);
Luke Huangf8215372019-11-22 11:53:41 +08003254 int rv = getnameinfo((const struct sockaddr*)&sin6, sizeof(sin6), host, sizeof(host), nullptr,
nuccachena26cc2a2018-07-17 18:07:23 +08003255 0, NI_NAMEREQD);
3256 ASSERT_EQ(0, rv);
3257 // Expect no DNS queries; localhost is resolved via /etc/hosts.
3258 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
3259
3260 std::string result_str = host;
3261 EXPECT_EQ(result_str, host_name);
3262}
3263
Hungming Chen9e6185a2019-06-04 16:09:19 +08003264TEST_F(ResolverTest, GetNameInfo_cnamesClasslessReverseDelegation) {
3265 // IPv4 addresses in the subnet with notation '/' or '-'.
3266 constexpr char addr_slash[] = "192.0.2.1";
3267 constexpr char addr_hyphen[] = "192.0.3.1";
3268
3269 // Used to verify DNS reverse query for classless reverse lookup zone. See detail in RFC 2317
3270 // section 4.
3271 const static std::vector<DnsRecord> records = {
3272 // The records for reverse querying "192.0.2.1" in the subnet with notation '/'.
3273 {"1.2.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0/25.2.0.192.in-addr.arpa."},
3274 {"1.0/25.2.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
3275
3276 // The records for reverse querying "192.0.3.1" in the subnet with notation '-'.
3277 {"1.3.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0-127.3.0.192.in-addr.arpa."},
3278 {"1.0-127.3.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
3279 };
3280
3281 test::DNSResponder dns;
3282 StartDns(dns, records);
3283 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3284
3285 for (const auto& address : {addr_slash, addr_hyphen}) {
3286 SCOPED_TRACE(address);
3287
3288 char host[NI_MAXHOST];
3289 sockaddr_in sin = {.sin_family = AF_INET};
3290 ASSERT_TRUE(inet_pton(AF_INET, address, &sin.sin_addr));
3291 int rv = getnameinfo((const sockaddr*)&sin, sizeof(sin), host, sizeof(host), nullptr, 0,
3292 NI_NAMEREQD);
3293 ASSERT_EQ(0, rv);
3294 EXPECT_STREQ("hello.example.com", host);
3295 }
3296}
3297
nuccachena26cc2a2018-07-17 18:07:23 +08003298TEST_F(ResolverTest, GetHostByName2_Dns64Synthesize) {
Xiao Ma09b71022018-12-11 17:56:32 +09003299 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08003300 constexpr char dns64_name[] = "ipv4only.arpa.";
3301 constexpr char host_name[] = "ipv4only.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09003302 const std::vector<DnsRecord> records = {
3303 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
3304 {host_name, ns_type::ns_t_a, "1.2.3.4"},
3305 };
nuccachena26cc2a2018-07-17 18:07:23 +08003306
Xiao Ma09b71022018-12-11 17:56:32 +09003307 test::DNSResponder dns(listen_addr);
3308 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08003309 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003310 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003311
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003312 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003313 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003314 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003315
3316 // Query an IPv4-only hostname. Expect that gets a synthesized address.
3317 struct hostent* result = gethostbyname2("ipv4only", AF_INET6);
3318 ASSERT_TRUE(result != nullptr);
3319 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3320 std::string result_str = ToString(result);
3321 EXPECT_EQ(result_str, "64:ff9b::102:304");
3322}
nuccachena26cc2a2018-07-17 18:07:23 +08003323
3324TEST_F(ResolverTest, GetHostByName2_DnsQueryWithHavingNat64Prefix) {
3325 constexpr char dns64_name[] = "ipv4only.arpa.";
3326 constexpr char host_name[] = "v4v6.example.com.";
nuccachena26cc2a2018-07-17 18:07:23 +08003327 constexpr char listen_addr[] = "::1";
Xiao Ma09b71022018-12-11 17:56:32 +09003328 const std::vector<DnsRecord> records = {
3329 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
3330 {host_name, ns_type::ns_t_a, "1.2.3.4"},
3331 {host_name, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
3332 };
3333
3334 test::DNSResponder dns(listen_addr);
3335 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08003336 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003337 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003338
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003339 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003340 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003341 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003342
3343 // IPv4 DNS query. Prefix should have no effect on it.
3344 struct hostent* result = gethostbyname2("v4v6", AF_INET);
3345 ASSERT_TRUE(result != nullptr);
3346 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3347 std::string result_str = ToString(result);
3348 EXPECT_EQ(result_str, "1.2.3.4");
3349 dns.clearQueries();
3350
3351 // IPv6 DNS query. Prefix should have no effect on it.
3352 result = gethostbyname2("v4v6", AF_INET6);
3353 ASSERT_TRUE(result != nullptr);
3354 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3355 result_str = ToString(result);
3356 EXPECT_EQ(result_str, "2001:db8::102:304");
3357}
3358
3359TEST_F(ResolverTest, GetHostByName2_Dns64QuerySpecialUseIPv4Addresses) {
3360 constexpr char THIS_NETWORK[] = "this_network";
3361 constexpr char LOOPBACK[] = "loopback";
3362 constexpr char LINK_LOCAL[] = "link_local";
3363 constexpr char MULTICAST[] = "multicast";
3364 constexpr char LIMITED_BROADCAST[] = "limited_broadcast";
3365
3366 constexpr char ADDR_THIS_NETWORK[] = "0.0.0.1";
3367 constexpr char ADDR_LOOPBACK[] = "127.0.0.1";
3368 constexpr char ADDR_LINK_LOCAL[] = "169.254.0.1";
3369 constexpr char ADDR_MULTICAST[] = "224.0.0.1";
3370 constexpr char ADDR_LIMITED_BROADCAST[] = "255.255.255.255";
3371
3372 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08003373 constexpr char dns64_name[] = "ipv4only.arpa.";
3374
Xiao Ma09b71022018-12-11 17:56:32 +09003375 test::DNSResponder dns(listen_addr);
3376 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachena26cc2a2018-07-17 18:07:23 +08003377 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003378 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003379
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003380 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003381 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003382 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003383
Luke Huangf8215372019-11-22 11:53:41 +08003384 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08003385 static const struct TestConfig {
3386 std::string name;
3387 std::string addr;
3388
3389 std::string asHostName() const {
Luke Huangf8215372019-11-22 11:53:41 +08003390 return StringPrintf("%s.example.com.", name.c_str());
nuccachena26cc2a2018-07-17 18:07:23 +08003391 }
3392 } testConfigs[]{
3393 {THIS_NETWORK, ADDR_THIS_NETWORK},
3394 {LOOPBACK, ADDR_LOOPBACK},
3395 {LINK_LOCAL, ADDR_LINK_LOCAL},
3396 {MULTICAST, ADDR_MULTICAST},
3397 {LIMITED_BROADCAST, ADDR_LIMITED_BROADCAST}
3398 };
Luke Huangf8215372019-11-22 11:53:41 +08003399 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08003400
3401 for (const auto& config : testConfigs) {
3402 const std::string testHostName = config.asHostName();
3403 SCOPED_TRACE(testHostName);
3404
3405 const char* host_name = testHostName.c_str();
3406 dns.addMapping(host_name, ns_type::ns_t_a, config.addr.c_str());
3407
3408 struct hostent* result = gethostbyname2(config.name.c_str(), AF_INET6);
3409 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3410
3411 // In AF_INET6 case, don't synthesize special use IPv4 address.
3412 // Expect to have no answer
3413 EXPECT_EQ(nullptr, result);
3414
3415 dns.clearQueries();
3416 }
Bernie Innocenti2fef2b82018-12-20 15:56:40 +09003417}
Mike Yuf14e1a92019-05-10 13:54:58 +08003418
3419TEST_F(ResolverTest, PrefixDiscoveryBypassTls) {
3420 constexpr char listen_addr[] = "::1";
3421 constexpr char cleartext_port[] = "53";
3422 constexpr char tls_port[] = "853";
3423 constexpr char dns64_name[] = "ipv4only.arpa.";
3424 const std::vector<std::string> servers = {listen_addr};
3425
3426 test::DNSResponder dns(listen_addr);
3427 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
3428 test::DnsTlsFrontend tls(listen_addr, tls_port, listen_addr, cleartext_port);
3429 ASSERT_TRUE(tls.startServer());
3430
3431 // Setup OPPORTUNISTIC mode and wait for the validation complete.
waynema0e73c2e2019-07-31 15:04:08 +08003432 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08003433 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yuf14e1a92019-05-10 13:54:58 +08003434 tls.clearQueries();
3435
3436 // Start NAT64 prefix discovery and wait for it complete.
3437 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003438 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
Mike Yuf14e1a92019-05-10 13:54:58 +08003439
3440 // Verify it bypassed TLS even though there's a TLS server available.
3441 EXPECT_EQ(0, tls.queries());
3442 EXPECT_EQ(1U, GetNumQueries(dns, dns64_name));
3443
3444 // Restart the testing network to reset the cache.
3445 mDnsClient.TearDown();
3446 mDnsClient.SetUp();
3447 dns.clearQueries();
3448
3449 // Setup STRICT mode and wait for the validation complete.
waynema0e73c2e2019-07-31 15:04:08 +08003450 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
3451 kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08003452 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yuf14e1a92019-05-10 13:54:58 +08003453 tls.clearQueries();
3454
3455 // Start NAT64 prefix discovery and wait for it to complete.
3456 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003457 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
Mike Yuf14e1a92019-05-10 13:54:58 +08003458
3459 // Verify it bypassed TLS despite STRICT mode.
3460 EXPECT_EQ(0, tls.queries());
3461 EXPECT_EQ(1U, GetNumQueries(dns, dns64_name));
3462}
Luke Huang9807e6b2019-05-20 16:17:12 +08003463
3464namespace {
3465
Luke Huang0d592bc2019-05-25 18:24:03 +08003466class ScopedSetNetworkForProcess {
3467 public:
3468 explicit ScopedSetNetworkForProcess(unsigned netId) {
3469 mStoredNetId = getNetworkForProcess();
3470 if (netId == mStoredNetId) return;
3471 EXPECT_EQ(0, setNetworkForProcess(netId));
3472 }
3473 ~ScopedSetNetworkForProcess() { EXPECT_EQ(0, setNetworkForProcess(mStoredNetId)); }
3474
3475 private:
3476 unsigned mStoredNetId;
3477};
3478
3479class ScopedSetNetworkForResolv {
3480 public:
3481 explicit ScopedSetNetworkForResolv(unsigned netId) { EXPECT_EQ(0, setNetworkForResolv(netId)); }
3482 ~ScopedSetNetworkForResolv() { EXPECT_EQ(0, setNetworkForResolv(NETID_UNSET)); }
3483};
3484
Luke Huang9807e6b2019-05-20 16:17:12 +08003485void sendCommand(int fd, const std::string& cmd) {
3486 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size() + 1));
3487 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size() + 1));
3488}
3489
3490int32_t readBE32(int fd) {
3491 int32_t tmp;
3492 int n = TEMP_FAILURE_RETRY(read(fd, &tmp, sizeof(tmp)));
3493 EXPECT_TRUE(n > 0);
3494 return ntohl(tmp);
3495}
3496
Luke Huang0d592bc2019-05-25 18:24:03 +08003497int readResponseCode(int fd) {
Luke Huang9807e6b2019-05-20 16:17:12 +08003498 char buf[4];
3499 int n = TEMP_FAILURE_RETRY(read(fd, &buf, sizeof(buf)));
3500 EXPECT_TRUE(n > 0);
3501 // The format of response code is that 4 bytes for the code & null.
3502 buf[3] = '\0';
3503 int result;
3504 EXPECT_TRUE(ParseInt(buf, &result));
3505 return result;
3506}
3507
Luke Huang0d592bc2019-05-25 18:24:03 +08003508bool checkAndClearUseLocalNameserversFlag(unsigned* netid) {
3509 if (netid == nullptr || ((*netid) & NETID_USE_LOCAL_NAMESERVERS) == 0) {
3510 return false;
3511 }
3512 *netid = (*netid) & ~NETID_USE_LOCAL_NAMESERVERS;
3513 return true;
3514}
3515
Luke Huangf8215372019-11-22 11:53:41 +08003516aidl::android::net::UidRangeParcel makeUidRangeParcel(int start, int stop) {
3517 aidl::android::net::UidRangeParcel res;
Luke Huang0d592bc2019-05-25 18:24:03 +08003518 res.start = start;
3519 res.stop = stop;
3520
3521 return res;
3522}
3523
3524void expectNetIdWithLocalNameserversFlag(unsigned netId) {
3525 unsigned dnsNetId = 0;
3526 EXPECT_EQ(0, getNetworkForDns(&dnsNetId));
3527 EXPECT_TRUE(checkAndClearUseLocalNameserversFlag(&dnsNetId));
3528 EXPECT_EQ(netId, static_cast<unsigned>(dnsNetId));
3529}
3530
3531void expectDnsNetIdEquals(unsigned netId) {
3532 unsigned dnsNetId = 0;
3533 EXPECT_EQ(0, getNetworkForDns(&dnsNetId));
3534 EXPECT_EQ(netId, static_cast<unsigned>(dnsNetId));
3535}
3536
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003537void expectDnsNetIdIsDefaultNetwork(INetd* netdService) {
Luke Huang0d592bc2019-05-25 18:24:03 +08003538 int currentNetid;
3539 EXPECT_TRUE(netdService->networkGetDefault(&currentNetid).isOk());
3540 expectDnsNetIdEquals(currentNetid);
3541}
3542
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003543void expectDnsNetIdWithVpn(INetd* netdService, unsigned vpnNetId, unsigned expectedNetId) {
Luke Huang0d592bc2019-05-25 18:24:03 +08003544 EXPECT_TRUE(netdService->networkCreateVpn(vpnNetId, false /* secure */).isOk());
3545 uid_t uid = getuid();
3546 // Add uid to VPN
3547 EXPECT_TRUE(netdService->networkAddUidRanges(vpnNetId, {makeUidRangeParcel(uid, uid)}).isOk());
3548 expectDnsNetIdEquals(expectedNetId);
3549 EXPECT_TRUE(netdService->networkDestroy(vpnNetId).isOk());
3550}
3551
Luke Huang9807e6b2019-05-20 16:17:12 +08003552} // namespace
3553
3554TEST_F(ResolverTest, getDnsNetId) {
3555 // We've called setNetworkForProcess in SetupOemNetwork, so reset to default first.
3556 setNetworkForProcess(NETID_UNSET);
Luke Huang0d592bc2019-05-25 18:24:03 +08003557
3558 expectDnsNetIdIsDefaultNetwork(mDnsClient.netdService());
3559 expectDnsNetIdWithVpn(mDnsClient.netdService(), TEST_VPN_NETID, TEST_VPN_NETID);
Luke Huang9807e6b2019-05-20 16:17:12 +08003560
3561 // Test with setNetworkForProcess
Luke Huang0d592bc2019-05-25 18:24:03 +08003562 {
3563 ScopedSetNetworkForProcess scopedSetNetworkForProcess(TEST_NETID);
3564 expectDnsNetIdEquals(TEST_NETID);
3565 }
3566
3567 // Test with setNetworkForProcess with NETID_USE_LOCAL_NAMESERVERS
3568 {
3569 ScopedSetNetworkForProcess scopedSetNetworkForProcess(TEST_NETID |
3570 NETID_USE_LOCAL_NAMESERVERS);
3571 expectNetIdWithLocalNameserversFlag(TEST_NETID);
3572 }
Luke Huang9807e6b2019-05-20 16:17:12 +08003573
3574 // Test with setNetworkForResolv
Luke Huang0d592bc2019-05-25 18:24:03 +08003575 {
3576 ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID);
3577 expectDnsNetIdEquals(TEST_NETID);
3578 }
3579
3580 // Test with setNetworkForResolv with NETID_USE_LOCAL_NAMESERVERS
3581 {
3582 ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID |
3583 NETID_USE_LOCAL_NAMESERVERS);
3584 expectNetIdWithLocalNameserversFlag(TEST_NETID);
3585 }
3586
3587 // Test with setNetworkForResolv under bypassable vpn
3588 {
3589 ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID);
3590 expectDnsNetIdWithVpn(mDnsClient.netdService(), TEST_VPN_NETID, TEST_NETID);
3591 }
Luke Huang9807e6b2019-05-20 16:17:12 +08003592
3593 // Create socket connected to DnsProxyListener
3594 int fd = dns_open_proxy();
3595 EXPECT_TRUE(fd > 0);
3596 unique_fd ufd(fd);
3597
3598 // Test command with wrong netId
3599 sendCommand(fd, "getdnsnetid abc");
Luke Huang0d592bc2019-05-25 18:24:03 +08003600 EXPECT_EQ(ResponseCode::DnsProxyQueryResult, readResponseCode(fd));
Luke Huang9807e6b2019-05-20 16:17:12 +08003601 EXPECT_EQ(-EINVAL, readBE32(fd));
3602
3603 // Test unsupported command
3604 sendCommand(fd, "getdnsnetidNotSupported");
3605 // Keep in sync with FrameworkListener.cpp (500, "Command not recognized")
Luke Huang0d592bc2019-05-25 18:24:03 +08003606 EXPECT_EQ(500, readResponseCode(fd));
Luke Huang9807e6b2019-05-20 16:17:12 +08003607}
Sehee Park2c118782019-05-07 13:02:45 +09003608
3609TEST_F(ResolverTest, BlockDnsQueryWithUidRule) {
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003610 // This test relies on blocking traffic on loopback, which xt_qtaguid does not do.
3611 // See aosp/358413 and b/34444781 for why.
3612 SKIP_IF_BPF_NOT_SUPPORTED;
3613
Sehee Park2c118782019-05-07 13:02:45 +09003614 constexpr char listen_addr1[] = "127.0.0.4";
3615 constexpr char listen_addr2[] = "::1";
3616 constexpr char host_name[] = "howdy.example.com.";
3617 const std::vector<DnsRecord> records = {
3618 {host_name, ns_type::ns_t_a, "1.2.3.4"},
3619 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
3620 };
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003621 INetd* netdService = mDnsClient.netdService();
Sehee Park2c118782019-05-07 13:02:45 +09003622
3623 test::DNSResponder dns1(listen_addr1);
3624 test::DNSResponder dns2(listen_addr2);
3625 StartDns(dns1, records);
3626 StartDns(dns2, records);
3627
3628 std::vector<std::string> servers = {listen_addr1, listen_addr2};
3629 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
3630 dns1.clearQueries();
3631 dns2.clearQueries();
3632
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003633 // Add drop rule for TEST_UID. Also enable the standby chain because it might not be enabled.
3634 // Unfortunately we cannot use FIREWALL_CHAIN_NONE, or custom iptables rules, for this purpose
3635 // because netd calls fchown() on the DNS query sockets, and "iptables -m owner" matches the
3636 // UID of the socket creator, not the UID set by fchown().
3637 //
3638 // TODO: migrate FIREWALL_CHAIN_NONE to eBPF as well.
3639 EXPECT_TRUE(netdService->firewallEnableChildChain(INetd::FIREWALL_CHAIN_STANDBY, true).isOk());
3640 EXPECT_TRUE(netdService
Sehee Park2c118782019-05-07 13:02:45 +09003641 ->firewallSetUidRule(INetd::FIREWALL_CHAIN_STANDBY, TEST_UID,
3642 INetd::FIREWALL_RULE_DENY)
3643 .isOk());
3644
3645 // Save uid
3646 int suid = getuid();
3647
3648 // Switch to TEST_UID
3649 EXPECT_TRUE(seteuid(TEST_UID) == 0);
3650
3651 // Dns Query
3652 int fd1 = resNetworkQuery(TEST_NETID, host_name, ns_c_in, ns_t_a, 0);
3653 int fd2 = resNetworkQuery(TEST_NETID, host_name, ns_c_in, ns_t_aaaa, 0);
3654 EXPECT_TRUE(fd1 != -1);
3655 EXPECT_TRUE(fd2 != -1);
3656
3657 uint8_t buf[MAXPACKET] = {};
3658 int rcode;
3659 int res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
3660 EXPECT_EQ(-ECONNREFUSED, res);
3661
3662 memset(buf, 0, MAXPACKET);
3663 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
3664 EXPECT_EQ(-ECONNREFUSED, res);
3665
3666 // Restore uid
3667 EXPECT_TRUE(seteuid(suid) == 0);
3668
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003669 // Remove drop rule for TEST_UID, and disable the standby chain.
3670 EXPECT_TRUE(netdService
Sehee Park2c118782019-05-07 13:02:45 +09003671 ->firewallSetUidRule(INetd::FIREWALL_CHAIN_STANDBY, TEST_UID,
3672 INetd::FIREWALL_RULE_ALLOW)
3673 .isOk());
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003674 EXPECT_TRUE(netdService->firewallEnableChildChain(INetd::FIREWALL_CHAIN_STANDBY, false).isOk());
Sehee Park2c118782019-05-07 13:02:45 +09003675}
Mike Yua772c202019-09-23 17:47:21 +08003676
Mike Yu40e67072019-10-09 21:14:09 +08003677namespace {
3678
3679const std::string kDotConnectTimeoutMsFlag(
3680 "persist.device_config.netd_native.dot_connect_timeout_ms");
3681
3682class ScopedSystemProperties {
3683 public:
3684 explicit ScopedSystemProperties(const std::string& key, const std::string& value)
3685 : mStoredKey(key) {
3686 mStoredValue = android::base::GetProperty(key, "");
3687 android::base::SetProperty(key, value);
3688 }
3689 ~ScopedSystemProperties() { android::base::SetProperty(mStoredKey, mStoredValue); }
3690
3691 private:
3692 std::string mStoredKey;
3693 std::string mStoredValue;
3694};
3695
3696} // namespace
3697
Mike Yua772c202019-09-23 17:47:21 +08003698TEST_F(ResolverTest, ConnectTlsServerTimeout) {
Mike Yu40e67072019-10-09 21:14:09 +08003699 constexpr int expectedTimeout = 1000;
3700 constexpr char hostname1[] = "query1.example.com.";
3701 constexpr char hostname2[] = "query2.example.com.";
Mike Yua772c202019-09-23 17:47:21 +08003702 const std::vector<DnsRecord> records = {
Mike Yu40e67072019-10-09 21:14:09 +08003703 {hostname1, ns_type::ns_t_a, "1.2.3.4"},
3704 {hostname2, ns_type::ns_t_a, "1.2.3.5"},
Mike Yua772c202019-09-23 17:47:21 +08003705 };
3706
3707 test::DNSResponder dns;
3708 StartDns(dns, records);
Mike Yu40e67072019-10-09 21:14:09 +08003709 test::DnsTlsFrontend tls;
Mike Yua772c202019-09-23 17:47:21 +08003710 ASSERT_TRUE(tls.startServer());
3711
Mike Yu40e67072019-10-09 21:14:09 +08003712 // The resolver will adjust the timeout value to 1000ms since the value is too small.
3713 ScopedSystemProperties scopedSystemProperties(kDotConnectTimeoutMsFlag, "100");
Mike Yua772c202019-09-23 17:47:21 +08003714
Mike Yu40e67072019-10-09 21:14:09 +08003715 // Set up resolver to opportunistic mode with the default configuration.
Mike Yu8ac63402019-12-02 15:28:38 +08003716 const ResolverParamsParcel parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
Mike Yu40e67072019-10-09 21:14:09 +08003717 ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
Mike Yua772c202019-09-23 17:47:21 +08003718 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
3719 dns.clearQueries();
3720 tls.clearQueries();
3721
3722 // The server becomes unresponsive to the handshake request.
3723 tls.setHangOnHandshakeForTesting(true);
3724
3725 // Expect the things happening in getaddrinfo():
3726 // 1. Connect to the private DNS server.
3727 // 2. SSL handshake times out.
3728 // 3. Fallback to UDP transport, and then get the answer.
Mike Yu40e67072019-10-09 21:14:09 +08003729 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
3730 auto [result, timeTakenMs] = safe_getaddrinfo_time_taken(hostname1, nullptr, hints);
Mike Yua772c202019-09-23 17:47:21 +08003731
Mike Yu40e67072019-10-09 21:14:09 +08003732 EXPECT_NE(nullptr, result);
Mike Yua772c202019-09-23 17:47:21 +08003733 EXPECT_EQ(0, tls.queries());
Mike Yu40e67072019-10-09 21:14:09 +08003734 EXPECT_EQ(1U, GetNumQueries(dns, hostname1));
3735 EXPECT_EQ(records.at(0).addr, ToString(result));
Mike Yua772c202019-09-23 17:47:21 +08003736
Mike Yu40e67072019-10-09 21:14:09 +08003737 // A loose upper bound is set by adding 2000ms buffer time. Theoretically, getaddrinfo()
3738 // should just take a bit more than expetTimeout milliseconds.
3739 EXPECT_GE(timeTakenMs, expectedTimeout);
3740 EXPECT_LE(timeTakenMs, expectedTimeout + 2000);
3741
3742 // Set the server to be responsive. Verify that the resolver will attempt to reconnect
3743 // to the server and then get the result within the timeout.
3744 tls.setHangOnHandshakeForTesting(false);
3745 std::tie(result, timeTakenMs) = safe_getaddrinfo_time_taken(hostname2, nullptr, hints);
3746
3747 EXPECT_NE(nullptr, result);
3748 EXPECT_EQ(1, tls.queries());
3749 EXPECT_EQ(1U, GetNumQueries(dns, hostname2));
3750 EXPECT_EQ(records.at(1).addr, ToString(result));
3751
3752 EXPECT_LE(timeTakenMs, expectedTimeout);
Mike Yua772c202019-09-23 17:47:21 +08003753}
Hungming Chenbb90ab32019-10-28 18:20:31 +08003754
Ken Chen766feae2019-10-30 15:13:44 +08003755TEST_F(ResolverTest, FlushNetworkCache) {
Luke Huang0b5a76c2019-11-23 03:00:00 +08003756 SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsClient.resolvService(), 4);
Ken Chen766feae2019-10-30 15:13:44 +08003757 test::DNSResponder dns;
3758 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3759 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3760
3761 const hostent* result = gethostbyname("hello");
3762 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
3763
3764 // get result from cache
3765 result = gethostbyname("hello");
3766 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
3767
3768 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
3769
3770 result = gethostbyname("hello");
3771 EXPECT_EQ(2U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
3772}
3773
3774TEST_F(ResolverTest, FlushNetworkCache_random) {
Luke Huang0b5a76c2019-11-23 03:00:00 +08003775 SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsClient.resolvService(), 4);
Ken Chen766feae2019-10-30 15:13:44 +08003776 constexpr int num_flush = 10;
3777 constexpr int num_queries = 20;
3778 test::DNSResponder dns;
3779 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3780 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3781 const addrinfo hints = {.ai_family = AF_INET};
3782
3783 std::thread t([this]() {
3784 for (int i = 0; i < num_flush; ++i) {
3785 unsigned delay = arc4random_uniform(10 * 1000); // 10ms
3786 usleep(delay);
3787 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
3788 }
3789 });
3790
3791 for (int i = 0; i < num_queries; ++i) {
3792 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3793 EXPECT_TRUE(result != nullptr);
3794 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3795 }
3796 t.join();
3797}
3798
3799// flush cache while one query is wait-for-response, another is pending.
3800TEST_F(ResolverTest, FlushNetworkCache_concurrent) {
Luke Huang0b5a76c2019-11-23 03:00:00 +08003801 SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsClient.resolvService(), 4);
Ken Chen766feae2019-10-30 15:13:44 +08003802 const char* listen_addr1 = "127.0.0.9";
3803 const char* listen_addr2 = "127.0.0.10";
3804 test::DNSResponder dns1(listen_addr1);
3805 test::DNSResponder dns2(listen_addr2);
3806 StartDns(dns1, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3807 StartDns(dns2, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3808 addrinfo hints = {.ai_family = AF_INET};
3809
3810 // step 1: set server#1 into deferred responding mode
3811 dns1.setDeferredResp(true);
3812 std::thread t1([&listen_addr1, &hints, this]() {
3813 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr1}));
3814 // step 3: query
3815 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3816 // step 9: check result
3817 EXPECT_TRUE(result != nullptr);
3818 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3819 });
3820
3821 // step 2: wait for the query to reach the server
3822 while (GetNumQueries(dns1, kHelloExampleCom) == 0) {
3823 usleep(1000); // 1ms
3824 }
3825
3826 std::thread t2([&listen_addr2, &hints, &dns2, this]() {
3827 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr2}));
3828 // step 5: query (should be blocked in resolver)
3829 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3830 // step 7: check result
3831 EXPECT_TRUE(result != nullptr);
3832 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3833 EXPECT_EQ(1U, GetNumQueriesForType(dns2, ns_type::ns_t_a, kHelloExampleCom));
3834 });
3835
3836 // step 4: wait a bit for the 2nd query to enter pending state
3837 usleep(100 * 1000); // 100ms
3838 // step 6: flush cache (will unblock pending queries)
3839 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
3840 t2.join();
3841
3842 // step 8: resume server#1
3843 dns1.setDeferredResp(false);
3844 t1.join();
3845
3846 // step 10: verify if result is correctly cached
3847 dns2.clearQueries();
3848 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3849 EXPECT_EQ(0U, GetNumQueries(dns2, kHelloExampleCom));
3850 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3851}
3852
waynema29253052019-08-20 11:26:08 +08003853// TODO: Perhaps to have a boundary conditions test for TCP and UDP.
3854TEST_F(ResolverTest, TcpQueryWithOversizePayload) {
3855 test::DNSResponder dns;
3856 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3857 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3858
3859 int fd = dns_open_proxy();
3860 ASSERT_TRUE(fd > 0);
3861
3862 // Sending DNS query over TCP once the packet sizes exceed 512 bytes.
3863 // The raw data is combined with Question section and Additional section
3864 // Question section : query "hello.example.com", type A, class IN
3865 // Additional section : type OPT (41), Option PADDING, Option Length 546
3866 // Padding option which allows DNS clients and servers to artificially
3867 // increase the size of a DNS message by a variable number of bytes.
3868 // See also RFC7830, section 3
3869 const std::string query =
3870 "+c0BAAABAAAAAAABBWhlbGxvB2V4YW1wbGUDY29tAAABAAEAACkgAAAAgAACJgAMAiIAAAAAAAAAAAAAAAAAA"
3871 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
3872 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
3873 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
3874 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
3875 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
3876 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
3877 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
3878 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
3879 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
3880 const std::string cmd =
3881 "resnsend " + std::to_string(TEST_NETID) + " 0 " /* ResNsendFlags */ + query + '\0';
3882 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size()));
3883 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size()));
3884 expectAnswersValid(fd, AF_INET, kHelloExampleComAddrV4);
3885 EXPECT_EQ(1U, GetNumQueriesForProtocol(dns, IPPROTO_TCP, kHelloExampleCom));
3886 EXPECT_EQ(0U, GetNumQueriesForProtocol(dns, IPPROTO_UDP, kHelloExampleCom));
3887}
3888
Ken Chen99344882020-01-01 14:59:38 +08003889TEST_F(ResolverTest, TruncatedRspMode) {
3890 constexpr char listen_addr[] = "127.0.0.4";
3891 constexpr char listen_addr2[] = "127.0.0.5";
3892 constexpr char listen_srv[] = "53";
3893
3894 test::DNSResponder dns(listen_addr, listen_srv, static_cast<ns_rcode>(-1));
3895 test::DNSResponder dns2(listen_addr2, listen_srv, static_cast<ns_rcode>(-1));
3896 // dns supports UDP only, dns2 support UDP and TCP
3897 dns.setResponseProbability(0.0, IPPROTO_TCP);
3898 StartDns(dns, kLargeCnameChainRecords);
3899 StartDns(dns2, kLargeCnameChainRecords);
3900
3901 const struct TestConfig {
3902 const std::optional<int32_t> tcMode;
3903 const bool ret;
3904 const unsigned numQueries;
3905 std::string asParameters() const {
3906 return StringPrintf("tcMode: %d, ret: %s, numQueries: %u", tcMode.value_or(-1),
3907 ret ? "true" : "false", numQueries);
3908 }
3909 } testConfigs[]{
3910 // clang-format off
3911 {std::nullopt, true, 0}, /* mode unset */
3912 {aidl::android::net::IDnsResolver::TC_MODE_DEFAULT, true, 0}, /* default mode */
3913 {aidl::android::net::IDnsResolver::TC_MODE_UDP_TCP, true, 1}, /* alternative mode */
3914 {-666, false, 1}, /* invalid input */
3915 // clang-format on
3916 };
3917
3918 for (const auto& config : testConfigs) {
3919 SCOPED_TRACE(config.asParameters());
3920
3921 ResolverParamsParcel parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
3922 parcel.servers = {listen_addr, listen_addr2};
3923 if (config.tcMode) {
3924 parcel.experimentalOptions.tcMode = config.tcMode.value();
3925 }
3926 ASSERT_EQ(mDnsClient.resolvService()->setResolverConfiguration(parcel).isOk(), config.ret);
3927
3928 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
3929 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3930 ASSERT_TRUE(result != nullptr);
3931 EXPECT_EQ(ToString(result), kHelloExampleComAddrV4);
3932 // TC_MODE_DEFAULT: resolver retries on TCP-only on each name server.
3933 // TC_MODE_UDP_TCP: resolver retries on TCP on the same server, falls back to UDP from next.
3934 ASSERT_EQ(GetNumQueriesForProtocol(dns, IPPROTO_UDP, kHelloExampleCom), 1U);
3935 ASSERT_EQ(GetNumQueriesForProtocol(dns, IPPROTO_TCP, kHelloExampleCom), 1U);
3936 ASSERT_EQ(GetNumQueriesForProtocol(dns2, IPPROTO_UDP, kHelloExampleCom), config.numQueries);
3937 ASSERT_EQ(GetNumQueriesForProtocol(dns2, IPPROTO_TCP, kHelloExampleCom), 1U);
3938
3939 dns.clearQueries();
3940 dns2.clearQueries();
3941 ASSERT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
3942 }
3943}
3944
Hungming Chenbb90ab32019-10-28 18:20:31 +08003945// Parameterized tests.
3946// TODO: Merge the existing tests as parameterized test if possible.
3947// TODO: Perhaps move parameterized tests to an independent file.
3948enum class CallType { GETADDRINFO, GETHOSTBYNAME };
3949class ResolverParameterizedTest : public ResolverTest,
Hungming Chen63779052019-10-30 15:06:13 +08003950 public testing::WithParamInterface<CallType> {
3951 protected:
Hungming Chen22617fd2019-12-06 12:15:45 +08003952 void VerifyQueryHelloExampleComV4(const test::DNSResponder& dns, const CallType calltype,
3953 const bool verifyNumQueries = true) {
Hungming Chen63779052019-10-30 15:06:13 +08003954 if (calltype == CallType::GETADDRINFO) {
3955 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
3956 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3957 ASSERT_TRUE(result != nullptr);
3958 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3959 } else if (calltype == CallType::GETHOSTBYNAME) {
3960 const hostent* result = gethostbyname("hello");
3961 ASSERT_TRUE(result != nullptr);
3962 ASSERT_EQ(4, result->h_length);
3963 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
3964 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3965 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
3966 } else {
3967 FAIL() << "Unsupported call type: " << static_cast<uint32_t>(calltype);
3968 }
Hungming Chen22617fd2019-12-06 12:15:45 +08003969 if (verifyNumQueries) EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
Hungming Chen63779052019-10-30 15:06:13 +08003970 }
3971};
Hungming Chenbb90ab32019-10-28 18:20:31 +08003972
Hungming Chen63779052019-10-30 15:06:13 +08003973INSTANTIATE_TEST_SUITE_P(QueryCallTest, ResolverParameterizedTest,
Hungming Chenbb90ab32019-10-28 18:20:31 +08003974 testing::Values(CallType::GETADDRINFO, CallType::GETHOSTBYNAME),
3975 [](const testing::TestParamInfo<CallType>& info) {
Hungming Chenbb90ab32019-10-28 18:20:31 +08003976 switch (info.param) {
3977 case CallType::GETADDRINFO:
Hungming Chen63779052019-10-30 15:06:13 +08003978 return "GetAddrInfo";
Hungming Chenbb90ab32019-10-28 18:20:31 +08003979 case CallType::GETHOSTBYNAME:
Hungming Chen63779052019-10-30 15:06:13 +08003980 return "GetHostByName";
Hungming Chenbb90ab32019-10-28 18:20:31 +08003981 default:
Hungming Chen63779052019-10-30 15:06:13 +08003982 return "InvalidParameter"; // Should not happen.
Hungming Chenbb90ab32019-10-28 18:20:31 +08003983 }
Hungming Chenbb90ab32019-10-28 18:20:31 +08003984 });
3985
3986TEST_P(ResolverParameterizedTest, AuthoritySectionAndAdditionalSection) {
3987 // DNS response may have more information in authority section and additional section.
3988 // Currently, getanswer() of packages/modules/DnsResolver/getaddrinfo.cpp doesn't parse the
3989 // content of authority section and additional section. Test these sections if they crash
3990 // the resolver, just in case. See also RFC 1035 section 4.1.
3991 const auto& calltype = GetParam();
3992 test::DNSHeader header(kDefaultDnsHeader);
3993
3994 // Create a DNS response which has a authoritative nameserver record in authority
3995 // section and its relevant address record in additional section.
3996 //
3997 // Question
3998 // hello.example.com. IN A
3999 // Answer
4000 // hello.example.com. IN A 1.2.3.4
4001 // Authority:
4002 // hello.example.com. IN NS ns1.example.com.
4003 // Additional:
4004 // ns1.example.com. IN A 5.6.7.8
4005 //
4006 // A response may have only question, answer, and authority section. Current testing response
4007 // should be able to cover this condition.
4008
4009 // Question section.
4010 test::DNSQuestion question{
4011 .qname = {.name = kHelloExampleCom},
4012 .qtype = ns_type::ns_t_a,
4013 .qclass = ns_c_in,
4014 };
4015 header.questions.push_back(std::move(question));
4016
4017 // Answer section.
4018 test::DNSRecord recordAnswer{
4019 .name = {.name = kHelloExampleCom},
4020 .rtype = ns_type::ns_t_a,
4021 .rclass = ns_c_in,
4022 .ttl = 0, // no cache
4023 };
Hungming Chen63779052019-10-30 15:06:13 +08004024 EXPECT_TRUE(test::DNSResponder::fillRdata(kHelloExampleComAddrV4, recordAnswer));
Hungming Chenbb90ab32019-10-28 18:20:31 +08004025 header.answers.push_back(std::move(recordAnswer));
4026
4027 // Authority section.
4028 test::DNSRecord recordAuthority{
4029 .name = {.name = kHelloExampleCom},
4030 .rtype = ns_type::ns_t_ns,
4031 .rclass = ns_c_in,
4032 .ttl = 0, // no cache
4033 };
4034 EXPECT_TRUE(test::DNSResponder::fillRdata("ns1.example.com.", recordAuthority));
4035 header.authorities.push_back(std::move(recordAuthority));
4036
4037 // Additional section.
4038 test::DNSRecord recordAdditional{
4039 .name = {.name = "ns1.example.com."},
4040 .rtype = ns_type::ns_t_a,
4041 .rclass = ns_c_in,
4042 .ttl = 0, // no cache
4043 };
4044 EXPECT_TRUE(test::DNSResponder::fillRdata("5.6.7.8", recordAdditional));
4045 header.additionals.push_back(std::move(recordAdditional));
4046
4047 // Start DNS server.
4048 test::DNSResponder dns(test::DNSResponder::MappingType::DNS_HEADER);
4049 dns.addMappingDnsHeader(kHelloExampleCom, ns_type::ns_t_a, header);
4050 ASSERT_TRUE(dns.startServer());
4051 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
4052 dns.clearQueries();
4053
4054 // Expect that get the address and the resolver doesn't crash.
Hungming Chen63779052019-10-30 15:06:13 +08004055 VerifyQueryHelloExampleComV4(dns, calltype);
4056}
4057
4058TEST_P(ResolverParameterizedTest, MessageCompression) {
4059 const auto& calltype = GetParam();
4060
4061 // The response with compressed domain name by a pointer. See RFC 1035 section 4.1.4.
4062 //
4063 // Ignoring the other fields of the message, the domain name of question section and answer
4064 // section are presented as:
4065 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4066 // 12 | 5 | h |
4067 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4068 // 14 | e | l |
4069 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4070 // 16 | l | o |
4071 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4072 // 18 | 7 | e |
4073 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4074 // 20 | x | a |
4075 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4076 // 22 | m | p |
4077 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4078 // 24 | l | e |
4079 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4080 // 26 | 3 | c |
4081 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4082 // 28 | o | m |
4083 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4084 // 30 | 0 | ... |
4085 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4086 //
4087 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4088 // 35 | 1 1| 12 |
4089 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4090 const std::vector<uint8_t> kResponseAPointer = {
4091 /* Header */
4092 0x00, 0x00, /* Transaction ID: 0x0000 */
4093 0x81, 0x80, /* Flags: qr rd ra */
4094 0x00, 0x01, /* Questions: 1 */
4095 0x00, 0x01, /* Answer RRs: 1 */
4096 0x00, 0x00, /* Authority RRs: 0 */
4097 0x00, 0x00, /* Additional RRs: 0 */
4098 /* Queries */
4099 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
4100 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
4101 0x00, 0x01, /* Type: A */
4102 0x00, 0x01, /* Class: IN */
4103 /* Answers */
4104 0xc0, 0x0c, /* Name: hello.example.com (a pointer) */
4105 0x00, 0x01, /* Type: A */
4106 0x00, 0x01, /* Class: IN */
4107 0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */
4108 0x00, 0x04, /* Data length: 4 */
4109 0x01, 0x02, 0x03, 0x04 /* Address: 1.2.3.4 */
4110 };
4111
4112 // The response with compressed domain name by a sequence of labels ending with a pointer. See
4113 // RFC 1035 section 4.1.4.
4114 //
4115 // Ignoring the other fields of the message, the domain name of question section and answer
4116 // section are presented as:
4117 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4118 // 12 | 5 | h |
4119 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4120 // 14 | e | l |
4121 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4122 // 16 | l | o |
4123 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4124 // 18 | 7 | e |
4125 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4126 // 20 | x | a |
4127 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4128 // 22 | m | p |
4129 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4130 // 24 | l | e |
4131 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4132 // 26 | 3 | c |
4133 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4134 // 28 | o | m |
4135 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4136 // 30 | 0 | ... |
4137 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4138 //
4139 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4140 // 35 | 5 | h |
4141 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4142 // 37 | e | l |
4143 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4144 // 39 | l | o |
4145 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4146 // 41 | 1 1| 18 |
4147 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4148 const std::vector<uint8_t> kResponseLabelEndingWithAPointer = {
4149 /* Header */
4150 0x00, 0x00, /* Transaction ID: 0x0000 */
4151 0x81, 0x80, /* Flags: qr rd ra */
4152 0x00, 0x01, /* Questions: 1 */
4153 0x00, 0x01, /* Answer RRs: 1 */
4154 0x00, 0x00, /* Authority RRs: 0 */
4155 0x00, 0x00, /* Additional RRs: 0 */
4156 /* Queries */
4157 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
4158 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
4159 0x00, 0x01, /* Type: A */
4160 0x00, 0x01, /* Class: IN */
4161 /* Answers */
4162 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0xc0,
4163 0x12, /* Name: hello.example.com (a label ending with a pointer) */
4164 0x00, 0x01, /* Type: A */
4165 0x00, 0x01, /* Class: IN */
4166 0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */
4167 0x00, 0x04, /* Data length: 4 */
4168 0x01, 0x02, 0x03, 0x04 /* Address: 1.2.3.4 */
4169 };
4170
4171 for (const auto& response : {kResponseAPointer, kResponseLabelEndingWithAPointer}) {
4172 SCOPED_TRACE(StringPrintf("Hex dump: %s", toHex(makeSlice(response)).c_str()));
4173
4174 test::DNSResponder dns(test::DNSResponder::MappingType::BINARY_PACKET);
4175 dns.addMappingBinaryPacket(kHelloExampleComQueryV4, response);
4176 StartDns(dns, {});
4177 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
4178
4179 // Expect no cache because the TTL of testing responses are 0.
4180 VerifyQueryHelloExampleComV4(dns, calltype);
Hungming Chenbb90ab32019-10-28 18:20:31 +08004181 }
Mike Yu40e67072019-10-09 21:14:09 +08004182}
Hungming Chen22617fd2019-12-06 12:15:45 +08004183
4184TEST_P(ResolverParameterizedTest, TruncatedResponse) {
4185 const auto& calltype = GetParam();
4186
Hungming Chen22617fd2019-12-06 12:15:45 +08004187 test::DNSResponder dns;
Ken Chen99344882020-01-01 14:59:38 +08004188 StartDns(dns, kLargeCnameChainRecords);
Hungming Chen22617fd2019-12-06 12:15:45 +08004189 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
4190
4191 // Expect UDP response is truncated. The resolver retries over TCP. See RFC 1035 section 4.2.1.
4192 VerifyQueryHelloExampleComV4(dns, calltype, false);
4193 EXPECT_EQ(1U, GetNumQueriesForProtocol(dns, IPPROTO_UDP, kHelloExampleCom));
4194 EXPECT_EQ(1U, GetNumQueriesForProtocol(dns, IPPROTO_TCP, kHelloExampleCom));
4195}