blob: 02bb3f1271d0192e2ff3342175547ac033c20b7c [file] [log] [blame]
Ken Chenb9fa2062018-11-13 21:51:13 +08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
Lorenzo Colitti0a8b4aa2019-06-26 22:31:03 +090010 * Unless required by applicable law or agreed to in writing, software
Ken Chenb9fa2062018-11-13 21:51:13 +080011 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
Bernie Innocenti3952ccc2019-03-03 19:39:53 +090018#define LOG_TAG "resolv_integration_test"
Ken Chenb9fa2062018-11-13 21:51:13 +080019
Hungming Chen5bf09772019-04-25 11:16:13 +080020#include <android-base/logging.h>
Bernie Innocenti41b82c42019-06-05 22:38:25 +090021#include <android-base/parseint.h>
Mike Yu40e67072019-10-09 21:14:09 +080022#include <android-base/properties.h>
Bernie Innocenti41b82c42019-06-05 22:38:25 +090023#include <android-base/stringprintf.h>
24#include <android-base/unique_fd.h>
25#include <android/multinetwork.h> // ResNsendFlags
Ken Chenb9fa2062018-11-13 21:51:13 +080026#include <arpa/inet.h>
Luke Huang94b10b92018-11-21 20:13:38 +080027#include <arpa/nameser.h>
Hungming Chene8f970c2019-04-10 17:34:06 +080028#include <binder/ProcessState.h>
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +090029#include <bpf/BpfUtils.h>
Bernie Innocenti41b82c42019-06-05 22:38:25 +090030#include <cutils/sockets.h>
31#include <gmock/gmock-matchers.h>
32#include <gtest/gtest.h>
Ken Chenb9fa2062018-11-13 21:51:13 +080033#include <netdb.h>
Luke Huang9d2d25b2019-06-14 00:34:05 +080034#include <netdutils/InternetAddresses.h>
Luke Huang579ddc72019-06-14 00:59:39 +080035#include <netdutils/NetworkConstants.h> // SHA256_SIZE
Luke Huang9d2d25b2019-06-14 00:34:05 +080036#include <netdutils/ResponseCode.h>
Hungming Chen63779052019-10-30 15:06:13 +080037#include <netdutils/Slice.h>
Luke Huang9d2d25b2019-06-14 00:34:05 +080038#include <netdutils/SocketOption.h>
Mike Yu40e67072019-10-09 21:14:09 +080039#include <netdutils/Stopwatch.h>
Luke Huang94b10b92018-11-21 20:13:38 +080040#include <netinet/in.h>
Bernie Innocenti41b82c42019-06-05 22:38:25 +090041#include <openssl/base64.h>
Luke Huang94b10b92018-11-21 20:13:38 +080042#include <poll.h> /* poll */
Bernie Innocenti41b82c42019-06-05 22:38:25 +090043#include <private/android_filesystem_config.h>
Luke Huang94b10b92018-11-21 20:13:38 +080044#include <resolv.h>
Ken Chenb9fa2062018-11-13 21:51:13 +080045#include <stdarg.h>
Ken Chenb9fa2062018-11-13 21:51:13 +080046#include <stdlib.h>
Luke Huang94b10b92018-11-21 20:13:38 +080047#include <sys/socket.h>
48#include <sys/un.h>
Ken Chenb9fa2062018-11-13 21:51:13 +080049#include <unistd.h>
50
51#include <algorithm>
52#include <chrono>
53#include <iterator>
54#include <numeric>
55#include <thread>
56
Luke Huangf8215372019-11-22 11:53:41 +080057#include <aidl/android/net/IDnsResolver.h>
58#include <android/binder_manager.h>
59#include <android/binder_process.h>
Bernie Innocenti41b82c42019-06-05 22:38:25 +090060#include "NetdClient.h"
Bernie Innocenti41b82c42019-06-05 22:38:25 +090061#include "ResolverStats.h"
Luke Huangf8215372019-11-22 11:53:41 +080062#include "netid_client.h" // NETID_UNSET
63#include "params.h" // MAXNS
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +090064#include "test_utils.h"
Hungming Chene8f970c2019-04-10 17:34:06 +080065#include "tests/dns_metrics_listener/dns_metrics_listener.h"
chenbruceb43ec752019-07-24 20:19:41 +080066#include "tests/dns_responder/dns_responder.h"
Luke Huangf8215372019-11-22 11:53:41 +080067#include "tests/dns_responder/dns_responder_client_ndk.h"
chenbruceb43ec752019-07-24 20:19:41 +080068#include "tests/dns_responder/dns_tls_frontend.h"
Luke Huangfde82482019-06-04 01:04:53 +080069#include "tests/resolv_test_utils.h"
Ken Chenb9fa2062018-11-13 21:51:13 +080070
Luke Huang0d592bc2019-05-25 18:24:03 +080071// Valid VPN netId range is 100 ~ 65535
72constexpr int TEST_VPN_NETID = 65502;
Luke Huang94b10b92018-11-21 20:13:38 +080073constexpr int MAXPACKET = (8 * 1024);
Ken Chenb9fa2062018-11-13 21:51:13 +080074
Sehee Park2c118782019-05-07 13:02:45 +090075// Use maximum reserved appId for applications to avoid conflict with existing uids.
76static const int TEST_UID = 99999;
77
waynema0e73c2e2019-07-31 15:04:08 +080078// Currently the hostname of TLS server must match the CN filed on the server's certificate.
79// Inject a test CA whose hostname is "example.com" for DNS-OVER-TLS tests.
80static const std::string kDefaultPrivateDnsHostName = "example.com";
81static const std::string kDefaultIncorrectPrivateDnsHostName = "www.example.com";
82
Ken Chenb9fa2062018-11-13 21:51:13 +080083// Semi-public Bionic hook used by the NDK (frameworks/base/native/android/net.c)
84// Tested here for convenience.
85extern "C" int android_getaddrinfofornet(const char* hostname, const char* servname,
86 const addrinfo* hints, unsigned netid, unsigned mark,
87 struct addrinfo** result);
88
Luke Huang70070852019-11-25 18:25:50 +080089using aidl::android::net::IDnsResolver;
Luke Huangf8215372019-11-22 11:53:41 +080090using aidl::android::net::INetd;
Luke Huang9807e6b2019-05-20 16:17:12 +080091using android::base::ParseInt;
Ken Chenb9fa2062018-11-13 21:51:13 +080092using android::base::StringPrintf;
Luke Huang9807e6b2019-05-20 16:17:12 +080093using android::base::unique_fd;
Ken Chenb9fa2062018-11-13 21:51:13 +080094using android::net::ResolverStats;
Hungming Chene8f970c2019-04-10 17:34:06 +080095using android::net::metrics::DnsMetricsListener;
Ken Chenb9fa2062018-11-13 21:51:13 +080096using android::netdutils::enableSockopt;
Hungming Chen63779052019-10-30 15:06:13 +080097using android::netdutils::makeSlice;
Luke Huang9807e6b2019-05-20 16:17:12 +080098using android::netdutils::ResponseCode;
Luke Huang9d2d25b2019-06-14 00:34:05 +080099using android::netdutils::ScopedAddrinfo;
Mike Yu40e67072019-10-09 21:14:09 +0800100using android::netdutils::Stopwatch;
Hungming Chen63779052019-10-30 15:06:13 +0800101using android::netdutils::toHex;
Ken Chenb9fa2062018-11-13 21:51:13 +0800102
103// TODO: move into libnetdutils?
104namespace {
Luke Huangfde82482019-06-04 01:04:53 +0800105
Ken Chenb9fa2062018-11-13 21:51:13 +0800106ScopedAddrinfo safe_getaddrinfo(const char* node, const char* service,
107 const struct addrinfo* hints) {
108 addrinfo* result = nullptr;
109 if (getaddrinfo(node, service, hints, &result) != 0) {
110 result = nullptr; // Should already be the case, but...
111 }
112 return ScopedAddrinfo(result);
113}
Luke Huangfde82482019-06-04 01:04:53 +0800114
Mike Yu40e67072019-10-09 21:14:09 +0800115std::pair<ScopedAddrinfo, int> safe_getaddrinfo_time_taken(const char* node, const char* service,
116 const addrinfo& hints) {
117 Stopwatch s;
118 ScopedAddrinfo result = safe_getaddrinfo(node, service, &hints);
119 return {std::move(result), s.timeTakenUs() / 1000};
120}
121
Ken Chenb9fa2062018-11-13 21:51:13 +0800122} // namespace
123
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900124class ResolverTest : public ::testing::Test {
Hungming Chene8f970c2019-04-10 17:34:06 +0800125 public:
Hungming Chen5bf09772019-04-25 11:16:13 +0800126 static void SetUpTestCase() {
127 // Get binder service.
128 // Note that |mDnsClient| is not used for getting binder service in this static function.
129 // The reason is that wants to keep |mDnsClient| as a non-static data member. |mDnsClient|
130 // which sets up device network configuration could be independent from every test.
Luke Huangf8215372019-11-22 11:53:41 +0800131 // TODO: Perhaps add a static function in resolv_test_binder_utils.{cpp,h} to get binder
132 // service.
133
134 AIBinder* binder = AServiceManager_getService("dnsresolver");
135 ndk::SpAIBinder resolvBinder = ndk::SpAIBinder(binder);
136 auto resolvService = aidl::android::net::IDnsResolver::fromBinder(resolvBinder);
Hungming Chen5bf09772019-04-25 11:16:13 +0800137 ASSERT_NE(nullptr, resolvService.get());
138
139 // Subscribe the death recipient to the service IDnsResolver for detecting Netd death.
Luke Huang70070852019-11-25 18:25:50 +0800140 // GTEST assertion macros are not invoked for generating a test failure in the death
141 // recipient because the macros can't indicate failed test if Netd died between tests.
142 // Moreover, continuing testing may have no meaningful after Netd death. Therefore, the
143 // death recipient aborts process by GTEST_LOG_(FATAL) once Netd died.
Luke Huangf8215372019-11-22 11:53:41 +0800144 sResolvDeathRecipient = AIBinder_DeathRecipient_new([](void*) {
145 constexpr char errorMessage[] = "Netd died";
146 LOG(ERROR) << errorMessage;
147 GTEST_LOG_(FATAL) << errorMessage;
148 });
149 ASSERT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, sResolvDeathRecipient, nullptr));
Hungming Chen5bf09772019-04-25 11:16:13 +0800150
151 // Subscribe the DNS listener for verifying DNS metrics event contents.
Luke Huangf8215372019-11-22 11:53:41 +0800152 sDnsMetricsListener = ndk::SharedRefBase::make<DnsMetricsListener>(
153 TEST_NETID /*monitor specific network*/);
Hungming Chen5bf09772019-04-25 11:16:13 +0800154 ASSERT_TRUE(resolvService->registerEventListener(sDnsMetricsListener).isOk());
155
156 // Start the binder thread pool for listening DNS metrics events and receiving death
157 // recipient.
Luke Huangf8215372019-11-22 11:53:41 +0800158 ABinderProcess_startThreadPool();
Hungming Chene8f970c2019-04-10 17:34:06 +0800159 }
Luke Huangf8215372019-11-22 11:53:41 +0800160 static void TearDownTestCase() { AIBinder_DeathRecipient_delete(sResolvDeathRecipient); }
Hungming Chene8f970c2019-04-10 17:34:06 +0800161
Ken Chenb9fa2062018-11-13 21:51:13 +0800162 protected:
Xiao Ma09b71022018-12-11 17:56:32 +0900163 struct DnsRecord {
164 std::string host_name; // host name
165 ns_type type; // record type
166 std::string addr; // ipv4/v6 address
167 };
168
Hungming Chen5bf09772019-04-25 11:16:13 +0800169 void SetUp() { mDnsClient.SetUp(); }
Hungming Chene8f970c2019-04-10 17:34:06 +0800170 void TearDown() { mDnsClient.TearDown(); }
nuccachena26cc2a2018-07-17 18:07:23 +0800171
Xiao Ma09b71022018-12-11 17:56:32 +0900172 void StartDns(test::DNSResponder& dns, const std::vector<DnsRecord>& records) {
173 for (const auto& r : records) {
174 dns.addMapping(r.host_name, r.type, r.addr);
175 }
176
177 ASSERT_TRUE(dns.startServer());
178 dns.clearQueries();
179 }
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900180
Hungming Chene8f970c2019-04-10 17:34:06 +0800181 bool WaitForNat64Prefix(ExpectNat64PrefixStatus status,
182 std::chrono::milliseconds timeout = std::chrono::milliseconds(1000)) {
Hungming Chen5bf09772019-04-25 11:16:13 +0800183 return sDnsMetricsListener->waitForNat64Prefix(status, timeout);
Hungming Chene8f970c2019-04-10 17:34:06 +0800184 }
185
Mike Yu724f77d2019-08-16 11:14:50 +0800186 bool WaitForPrivateDnsValidation(std::string serverAddr, bool validated) {
187 return sDnsMetricsListener->waitForPrivateDnsValidation(serverAddr, validated);
188 }
189
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900190 DnsResponderClient mDnsClient;
Xiao Ma09b71022018-12-11 17:56:32 +0900191
Hungming Chen5bf09772019-04-25 11:16:13 +0800192 // Use a shared static DNS listener for all tests to avoid registering lots of listeners
193 // which may be released late until process terminated. Currently, registered DNS listener
194 // is removed by binder death notification which is fired when the process hosting an
195 // IBinder has gone away. If every test in ResolverTest registers its DNS listener, Netd
196 // may temporarily hold lots of dead listeners until the unit test process terminates.
197 // TODO: Perhaps add an unregistering listener binder call or fork a listener process which
198 // could be terminated earlier.
Luke Huangf8215372019-11-22 11:53:41 +0800199 static std::shared_ptr<DnsMetricsListener>
200 sDnsMetricsListener; // Initialized in SetUpTestCase.
Hungming Chen5bf09772019-04-25 11:16:13 +0800201
202 // Use a shared static death recipient to monitor the service death. The static death
203 // recipient could monitor the death not only during the test but also between tests.
Luke Huangf8215372019-11-22 11:53:41 +0800204 static AIBinder_DeathRecipient* sResolvDeathRecipient; // Initialized in SetUpTestCase.
Ken Chenb9fa2062018-11-13 21:51:13 +0800205};
206
Hungming Chen5bf09772019-04-25 11:16:13 +0800207// Initialize static member of class.
Luke Huangf8215372019-11-22 11:53:41 +0800208std::shared_ptr<DnsMetricsListener> ResolverTest::sDnsMetricsListener;
209AIBinder_DeathRecipient* ResolverTest::sResolvDeathRecipient;
Hungming Chen5bf09772019-04-25 11:16:13 +0800210
Ken Chenb9fa2062018-11-13 21:51:13 +0800211TEST_F(ResolverTest, GetHostByName) {
Xiao Ma09b71022018-12-11 17:56:32 +0900212 constexpr char nonexistent_host_name[] = "nonexistent.example.com.";
213
214 test::DNSResponder dns;
215 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.3"}});
216 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800217
218 const hostent* result;
Ken Chenb9fa2062018-11-13 21:51:13 +0800219 result = gethostbyname("nonexistent");
220 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, nonexistent_host_name));
221 ASSERT_TRUE(result == nullptr);
222 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
223
224 dns.clearQueries();
225 result = gethostbyname("hello");
Xiao Ma09b71022018-12-11 17:56:32 +0900226 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
Ken Chenb9fa2062018-11-13 21:51:13 +0800227 ASSERT_FALSE(result == nullptr);
228 ASSERT_EQ(4, result->h_length);
229 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
230 EXPECT_EQ("1.2.3.3", ToString(result));
231 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800232}
233
lifr4e4a2e02019-01-29 16:53:51 +0800234TEST_F(ResolverTest, GetHostByName_cnames) {
235 constexpr char host_name[] = "host.example.com.";
236 size_t cnamecount = 0;
237 test::DNSResponder dns;
238
239 const std::vector<DnsRecord> records = {
240 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
241 {"a.example.com.", ns_type::ns_t_cname, "b.example.com."},
242 {"b.example.com.", ns_type::ns_t_cname, "c.example.com."},
243 {"c.example.com.", ns_type::ns_t_cname, "d.example.com."},
244 {"d.example.com.", ns_type::ns_t_cname, "e.example.com."},
245 {"e.example.com.", ns_type::ns_t_cname, host_name},
246 {host_name, ns_type::ns_t_a, "1.2.3.3"},
247 {host_name, ns_type::ns_t_aaaa, "2001:db8::42"},
248 };
249 StartDns(dns, records);
250 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
251
252 // using gethostbyname2() to resolve ipv4 hello.example.com. to 1.2.3.3
253 // Ensure the v4 address and cnames are correct
254 const hostent* result;
255 result = gethostbyname2("hello", AF_INET);
256 ASSERT_FALSE(result == nullptr);
257
258 for (int i = 0; result != nullptr && result->h_aliases[i] != nullptr; i++) {
259 std::string domain_name = records[i].host_name.substr(0, records[i].host_name.size() - 1);
260 EXPECT_EQ(result->h_aliases[i], domain_name);
261 cnamecount++;
262 }
263 // The size of "Non-cname type" record in DNS records is 2
264 ASSERT_EQ(cnamecount, records.size() - 2);
265 ASSERT_EQ(4, result->h_length);
266 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
267 EXPECT_EQ("1.2.3.3", ToString(result));
268 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
269 EXPECT_EQ(1U, dns.queries().size()) << dns.dumpQueries();
270
271 // using gethostbyname2() to resolve ipv6 hello.example.com. to 2001:db8::42
272 // Ensure the v6 address and cnames are correct
273 cnamecount = 0;
274 dns.clearQueries();
275 result = gethostbyname2("hello", AF_INET6);
276 for (unsigned i = 0; result != nullptr && result->h_aliases[i] != nullptr; i++) {
277 std::string domain_name = records[i].host_name.substr(0, records[i].host_name.size() - 1);
278 EXPECT_EQ(result->h_aliases[i], domain_name);
279 cnamecount++;
280 }
281 // The size of "Non-cname type" DNS record in records is 2
282 ASSERT_EQ(cnamecount, records.size() - 2);
283 ASSERT_FALSE(result == nullptr);
284 ASSERT_EQ(16, result->h_length);
285 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
286 EXPECT_EQ("2001:db8::42", ToString(result));
287 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
288}
289
290TEST_F(ResolverTest, GetHostByName_cnamesInfiniteLoop) {
291 test::DNSResponder dns;
292 const std::vector<DnsRecord> records = {
293 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
294 {"a.example.com.", ns_type::ns_t_cname, kHelloExampleCom},
295 };
296 StartDns(dns, records);
297 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
298
299 const hostent* result;
300 result = gethostbyname2("hello", AF_INET);
301 ASSERT_TRUE(result == nullptr);
302
303 dns.clearQueries();
304 result = gethostbyname2("hello", AF_INET6);
305 ASSERT_TRUE(result == nullptr);
306}
307
Ken Chenb9fa2062018-11-13 21:51:13 +0800308TEST_F(ResolverTest, GetHostByName_localhost) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800309 constexpr char name_camelcase[] = "LocalHost";
Ken Chenb9fa2062018-11-13 21:51:13 +0800310 constexpr char name_ip6_dot[] = "ip6-localhost.";
311 constexpr char name_ip6_fqdn[] = "ip6-localhost.example.com.";
312
313 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma09b71022018-12-11 17:56:32 +0900314 test::DNSResponder dns;
315 StartDns(dns, {});
316 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800317
318 // Expect no DNS queries; localhost is resolved via /etc/hosts
Xiao Ma09b71022018-12-11 17:56:32 +0900319 const hostent* result = gethostbyname(kLocalHost);
Ken Chenb9fa2062018-11-13 21:51:13 +0800320 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
321 ASSERT_FALSE(result == nullptr);
322 ASSERT_EQ(4, result->h_length);
323 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900324 EXPECT_EQ(kLocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800325 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
326
327 // Ensure the hosts file resolver ignores case of hostnames
328 result = gethostbyname(name_camelcase);
329 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
330 ASSERT_FALSE(result == nullptr);
331 ASSERT_EQ(4, result->h_length);
332 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900333 EXPECT_EQ(kLocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800334 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
335
336 // The hosts file also contains ip6-localhost, but gethostbyname() won't
chenbruce018fdb22019-06-12 18:08:04 +0800337 // return it. This would be easy to
Ken Chenb9fa2062018-11-13 21:51:13 +0800338 // change, but there's no point in changing the legacy behavior; new code
339 // should be calling getaddrinfo() anyway.
340 // So we check the legacy behavior, which results in amusing A-record
341 // lookups for ip6-localhost, with and without search domains appended.
342 dns.clearQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900343 result = gethostbyname(kIp6LocalHost);
Sehee Parkbbca0202018-11-16 10:53:16 +0900344 EXPECT_EQ(2U, dns.queries().size()) << dns.dumpQueries();
345 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, name_ip6_dot)) << dns.dumpQueries();
346 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, name_ip6_fqdn)) << dns.dumpQueries();
Ken Chenb9fa2062018-11-13 21:51:13 +0800347 ASSERT_TRUE(result == nullptr);
348
349 // Finally, use gethostbyname2() to resolve ip6-localhost to ::1 from
350 // the hosts file.
351 dns.clearQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900352 result = gethostbyname2(kIp6LocalHost, AF_INET6);
Ken Chenb9fa2062018-11-13 21:51:13 +0800353 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
354 ASSERT_FALSE(result == nullptr);
355 ASSERT_EQ(16, result->h_length);
356 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900357 EXPECT_EQ(kIp6LocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800358 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800359}
360
361TEST_F(ResolverTest, GetHostByName_numeric) {
362 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma09b71022018-12-11 17:56:32 +0900363 test::DNSResponder dns;
364 StartDns(dns, {});
365 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800366
367 // Numeric v4 address: expect no DNS queries
368 constexpr char numeric_v4[] = "192.168.0.1";
Ken Chenb9fa2062018-11-13 21:51:13 +0800369 const hostent* result = gethostbyname(numeric_v4);
Sehee Parkbbca0202018-11-16 10:53:16 +0900370 EXPECT_EQ(0U, dns.queries().size());
Ken Chenb9fa2062018-11-13 21:51:13 +0800371 ASSERT_FALSE(result == nullptr);
372 ASSERT_EQ(4, result->h_length); // v4
373 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
374 EXPECT_EQ(numeric_v4, ToString(result));
375 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
376
377 // gethostbyname() recognizes a v6 address, and fails with no DNS queries
378 constexpr char numeric_v6[] = "2001:db8::42";
379 dns.clearQueries();
380 result = gethostbyname(numeric_v6);
Sehee Parkbbca0202018-11-16 10:53:16 +0900381 EXPECT_EQ(0U, dns.queries().size());
Ken Chenb9fa2062018-11-13 21:51:13 +0800382 EXPECT_TRUE(result == nullptr);
383
384 // Numeric v6 address with gethostbyname2(): succeeds with no DNS queries
385 dns.clearQueries();
386 result = gethostbyname2(numeric_v6, AF_INET6);
Sehee Parkbbca0202018-11-16 10:53:16 +0900387 EXPECT_EQ(0U, dns.queries().size());
Ken Chenb9fa2062018-11-13 21:51:13 +0800388 ASSERT_FALSE(result == nullptr);
389 ASSERT_EQ(16, result->h_length); // v6
390 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
391 EXPECT_EQ(numeric_v6, ToString(result));
392 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
393
394 // Numeric v6 address with scope work with getaddrinfo(),
395 // but gethostbyname2() does not understand them; it issues two dns
396 // queries, then fails. This hardly ever happens, there's no point
397 // in fixing this. This test simply verifies the current (bogus)
398 // behavior to avoid further regressions (like crashes, or leaks).
399 constexpr char numeric_v6_scope[] = "fe80::1%lo";
400 dns.clearQueries();
401 result = gethostbyname2(numeric_v6_scope, AF_INET6);
Sehee Parkbbca0202018-11-16 10:53:16 +0900402 EXPECT_EQ(2U, dns.queries().size()); // OUCH!
Ken Chenb9fa2062018-11-13 21:51:13 +0800403 ASSERT_TRUE(result == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800404}
405
406TEST_F(ResolverTest, BinderSerialization) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800407 std::vector<int> params_offsets = {
Luke Huang5bd827c2019-03-14 16:10:04 +0800408 IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY,
409 IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD,
410 IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES,
411 IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES,
412 IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC,
413 IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT,
Ken Chenb9fa2062018-11-13 21:51:13 +0800414 };
Bernie Innocentib102dd22018-12-04 14:57:48 +0900415 const int size = static_cast<int>(params_offsets.size());
Luke Huang5bd827c2019-03-14 16:10:04 +0800416 EXPECT_EQ(size, IDnsResolver::RESOLVER_PARAMS_COUNT);
Ken Chenb9fa2062018-11-13 21:51:13 +0800417 std::sort(params_offsets.begin(), params_offsets.end());
Bernie Innocentib102dd22018-12-04 14:57:48 +0900418 for (int i = 0; i < size; ++i) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800419 EXPECT_EQ(params_offsets[i], i);
420 }
421}
422
423TEST_F(ResolverTest, GetHostByName_Binder) {
Luke Huangf8215372019-11-22 11:53:41 +0800424 std::vector<std::string> domains = {"example.com"};
Ken Chenb9fa2062018-11-13 21:51:13 +0800425 std::vector<std::unique_ptr<test::DNSResponder>> dns;
426 std::vector<std::string> servers;
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900427 std::vector<DnsResponderClient::Mapping> mappings;
428 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupMappings(1, domains, &mappings));
429 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupDNSServers(4, mappings, &dns, &servers));
Ken Chenb9fa2062018-11-13 21:51:13 +0800430 ASSERT_EQ(1U, mappings.size());
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900431 const DnsResponderClient::Mapping& mapping = mappings[0];
Ken Chenb9fa2062018-11-13 21:51:13 +0800432
Xiao Ma09b71022018-12-11 17:56:32 +0900433 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains, kDefaultParams));
Ken Chenb9fa2062018-11-13 21:51:13 +0800434
435 const hostent* result = gethostbyname(mapping.host.c_str());
Bernie Innocentib102dd22018-12-04 14:57:48 +0900436 const size_t total_queries =
Luke Huangfde82482019-06-04 01:04:53 +0800437 std::accumulate(dns.begin(), dns.end(), 0, [&mapping](size_t total, auto& d) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800438 return total + GetNumQueriesForType(*d, ns_type::ns_t_a, mapping.entry.c_str());
439 });
440
441 EXPECT_LE(1U, total_queries);
442 ASSERT_FALSE(result == nullptr);
443 ASSERT_EQ(4, result->h_length);
444 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
445 EXPECT_EQ(mapping.ip4, ToString(result));
446 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
447
448 std::vector<std::string> res_servers;
449 std::vector<std::string> res_domains;
Mike Yu0a1c53d2018-11-26 13:26:21 +0900450 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900451 res_params res_params;
Ken Chenb9fa2062018-11-13 21:51:13 +0800452 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +0800453 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800454 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
455 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
456 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chenb9fa2062018-11-13 21:51:13 +0800457 EXPECT_EQ(servers.size(), res_servers.size());
458 EXPECT_EQ(domains.size(), res_domains.size());
Mike Yu0a1c53d2018-11-26 13:26:21 +0900459 EXPECT_EQ(0U, res_tls_servers.size());
Luke Huang5bd827c2019-03-14 16:10:04 +0800460 ASSERT_EQ(static_cast<size_t>(IDnsResolver::RESOLVER_PARAMS_COUNT), kDefaultParams.size());
461 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY],
462 res_params.sample_validity);
463 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD],
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900464 res_params.success_threshold);
Luke Huang5bd827c2019-03-14 16:10:04 +0800465 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
466 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
467 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
Ken Chenb9fa2062018-11-13 21:51:13 +0800468 res_params.base_timeout_msec);
469 EXPECT_EQ(servers.size(), res_stats.size());
470
Bernie Innocenti0c067e42019-04-01 15:33:16 +0900471 EXPECT_THAT(res_servers, testing::UnorderedElementsAreArray(servers));
472 EXPECT_THAT(res_domains, testing::UnorderedElementsAreArray(domains));
Ken Chenb9fa2062018-11-13 21:51:13 +0800473}
474
475TEST_F(ResolverTest, GetAddrInfo) {
Xiao Ma09b71022018-12-11 17:56:32 +0900476 constexpr char listen_addr[] = "127.0.0.4";
477 constexpr char listen_addr2[] = "127.0.0.5";
478 constexpr char host_name[] = "howdy.example.com.";
Ken Chenb9fa2062018-11-13 21:51:13 +0800479
Xiao Ma09b71022018-12-11 17:56:32 +0900480 const std::vector<DnsRecord> records = {
481 {host_name, ns_type::ns_t_a, "1.2.3.4"},
482 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
483 };
484 test::DNSResponder dns(listen_addr);
485 test::DNSResponder dns2(listen_addr2);
486 StartDns(dns, records);
487 StartDns(dns2, records);
Ken Chenb9fa2062018-11-13 21:51:13 +0800488
Xiao Ma09b71022018-12-11 17:56:32 +0900489 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr}));
Ken Chenb9fa2062018-11-13 21:51:13 +0800490 dns.clearQueries();
491 dns2.clearQueries();
492
493 ScopedAddrinfo result = safe_getaddrinfo("howdy", nullptr, nullptr);
494 EXPECT_TRUE(result != nullptr);
495 size_t found = GetNumQueries(dns, host_name);
496 EXPECT_LE(1U, found);
497 // Could be A or AAAA
498 std::string result_str = ToString(result);
499 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
Luke Huangf8215372019-11-22 11:53:41 +0800500 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +0800501
502 // Verify that the name is cached.
503 size_t old_found = found;
504 result = safe_getaddrinfo("howdy", nullptr, nullptr);
505 EXPECT_TRUE(result != nullptr);
506 found = GetNumQueries(dns, host_name);
507 EXPECT_LE(1U, found);
508 EXPECT_EQ(old_found, found);
509 result_str = ToString(result);
Luke Huangf8215372019-11-22 11:53:41 +0800510 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4") << result_str;
Ken Chenb9fa2062018-11-13 21:51:13 +0800511
512 // Change the DNS resolver, ensure that queries are still cached.
Xiao Ma09b71022018-12-11 17:56:32 +0900513 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr2}));
Ken Chenb9fa2062018-11-13 21:51:13 +0800514 dns.clearQueries();
515 dns2.clearQueries();
516
517 result = safe_getaddrinfo("howdy", nullptr, nullptr);
518 EXPECT_TRUE(result != nullptr);
519 found = GetNumQueries(dns, host_name);
520 size_t found2 = GetNumQueries(dns2, host_name);
521 EXPECT_EQ(0U, found);
522 EXPECT_LE(0U, found2);
523
524 // Could be A or AAAA
525 result_str = ToString(result);
526 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
Luke Huangf8215372019-11-22 11:53:41 +0800527 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +0800528}
529
530TEST_F(ResolverTest, GetAddrInfoV4) {
Xiao Ma09b71022018-12-11 17:56:32 +0900531 test::DNSResponder dns;
532 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.5"}});
533 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800534
Xiao Ma09b71022018-12-11 17:56:32 +0900535 const addrinfo hints = {.ai_family = AF_INET};
536 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
Ken Chenb9fa2062018-11-13 21:51:13 +0800537 EXPECT_TRUE(result != nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900538 EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
Ken Chenb9fa2062018-11-13 21:51:13 +0800539 EXPECT_EQ("1.2.3.5", ToString(result));
540}
541
542TEST_F(ResolverTest, GetAddrInfo_localhost) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800543 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma09b71022018-12-11 17:56:32 +0900544 test::DNSResponder dns;
545 StartDns(dns, {});
546 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800547
Xiao Ma09b71022018-12-11 17:56:32 +0900548 ScopedAddrinfo result = safe_getaddrinfo(kLocalHost, nullptr, nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800549 EXPECT_TRUE(result != nullptr);
550 // Expect no DNS queries; localhost is resolved via /etc/hosts
551 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900552 EXPECT_EQ(kLocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800553
Xiao Ma09b71022018-12-11 17:56:32 +0900554 result = safe_getaddrinfo(kIp6LocalHost, nullptr, nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800555 EXPECT_TRUE(result != nullptr);
556 // Expect no DNS queries; ip6-localhost is resolved via /etc/hosts
557 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900558 EXPECT_EQ(kIp6LocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800559}
560
Luke Huangd8ac4752019-06-18 17:05:47 +0800561TEST_F(ResolverTest, GetAddrInfo_InvalidSocketType) {
562 test::DNSResponder dns;
563 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.5"}});
564 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
565
566 // TODO: Test other invalid socket types.
567 const addrinfo hints = {
568 .ai_family = AF_UNSPEC,
Luke Huangd8ac4752019-06-18 17:05:47 +0800569 .ai_socktype = SOCK_PACKET,
Nick Desaulnierscd6395a2019-10-11 09:15:24 -0700570 .ai_protocol = ANY,
Luke Huangd8ac4752019-06-18 17:05:47 +0800571 };
572 addrinfo* result = nullptr;
573 // This is a valid hint, but the query won't be sent because the socket type is
574 // not supported.
575 EXPECT_EQ(EAI_NODATA, getaddrinfo("hello", nullptr, &hints, &result));
576 ScopedAddrinfo result_cleanup(result);
577 EXPECT_EQ(nullptr, result);
578}
579
Ken Chen92bed612018-12-22 21:46:55 +0800580// Verify if the resolver correctly handle multiple queries simultaneously
581// step 1: set dns server#1 into deferred responding mode.
582// step 2: thread#1 query "hello.example.com." --> resolver send query to server#1.
583// step 3: thread#2 query "hello.example.com." --> resolver hold the request and wait for
584// response of previous pending query sent by thread#1.
585// step 4: thread#3 query "konbanha.example.com." --> resolver send query to server#3. Server
586// respond to resolver immediately.
587// step 5: check if server#1 get 1 query by thread#1, server#2 get 0 query, server#3 get 1 query.
588// step 6: resume dns server#1 to respond dns query in step#2.
589// step 7: thread#1 and #2 should get returned from DNS query after step#6. Also, check the
590// number of queries in server#2 is 0 to ensure thread#2 does not wake up unexpectedly
591// before signaled by thread#1.
592TEST_F(ResolverTest, GetAddrInfoV4_deferred_resp) {
593 const char* listen_addr1 = "127.0.0.9";
594 const char* listen_addr2 = "127.0.0.10";
595 const char* listen_addr3 = "127.0.0.11";
596 const char* listen_srv = "53";
597 const char* host_name_deferred = "hello.example.com.";
598 const char* host_name_normal = "konbanha.example.com.";
Mike Yufc125e42019-05-15 20:41:28 +0800599 test::DNSResponder dns1(listen_addr1, listen_srv, ns_rcode::ns_r_servfail);
600 test::DNSResponder dns2(listen_addr2, listen_srv, ns_rcode::ns_r_servfail);
601 test::DNSResponder dns3(listen_addr3, listen_srv, ns_rcode::ns_r_servfail);
Ken Chen92bed612018-12-22 21:46:55 +0800602 dns1.addMapping(host_name_deferred, ns_type::ns_t_a, "1.2.3.4");
603 dns2.addMapping(host_name_deferred, ns_type::ns_t_a, "1.2.3.4");
604 dns3.addMapping(host_name_normal, ns_type::ns_t_a, "1.2.3.5");
605 ASSERT_TRUE(dns1.startServer());
606 ASSERT_TRUE(dns2.startServer());
607 ASSERT_TRUE(dns3.startServer());
608 const std::vector<std::string> servers_for_t1 = {listen_addr1};
609 const std::vector<std::string> servers_for_t2 = {listen_addr2};
610 const std::vector<std::string> servers_for_t3 = {listen_addr3};
611 addrinfo hints = {.ai_family = AF_INET};
612 const std::vector<int> params = {300, 25, 8, 8, 5000};
613 bool t3_task_done = false;
614
615 dns1.setDeferredResp(true);
616 std::thread t1([&, this]() {
617 ASSERT_TRUE(
618 mDnsClient.SetResolversForNetwork(servers_for_t1, kDefaultSearchDomains, params));
619 ScopedAddrinfo result = safe_getaddrinfo(host_name_deferred, nullptr, &hints);
620 // t3's dns query should got returned first
621 EXPECT_TRUE(t3_task_done);
622 EXPECT_EQ(1U, GetNumQueries(dns1, host_name_deferred));
623 EXPECT_TRUE(result != nullptr);
624 EXPECT_EQ("1.2.3.4", ToString(result));
625 });
626
627 // ensuring t1 and t2 handler functions are processed in order
628 usleep(100 * 1000);
629 std::thread t2([&, this]() {
630 ASSERT_TRUE(
631 mDnsClient.SetResolversForNetwork(servers_for_t2, kDefaultSearchDomains, params));
632 ScopedAddrinfo result = safe_getaddrinfo(host_name_deferred, nullptr, &hints);
633 EXPECT_TRUE(t3_task_done);
634 EXPECT_EQ(0U, GetNumQueries(dns2, host_name_deferred));
635 EXPECT_TRUE(result != nullptr);
636 EXPECT_EQ("1.2.3.4", ToString(result));
637
638 std::vector<std::string> res_servers;
639 std::vector<std::string> res_domains;
640 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900641 res_params res_params;
Ken Chen92bed612018-12-22 21:46:55 +0800642 std::vector<ResolverStats> res_stats;
643 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800644 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
645 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains,
646 &res_tls_servers, &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chen92bed612018-12-22 21:46:55 +0800647 EXPECT_EQ(0, wait_for_pending_req_timeout_count);
648 });
649
650 // ensuring t2 and t3 handler functions are processed in order
651 usleep(100 * 1000);
652 std::thread t3([&, this]() {
653 ASSERT_TRUE(
654 mDnsClient.SetResolversForNetwork(servers_for_t3, kDefaultSearchDomains, params));
655 ScopedAddrinfo result = safe_getaddrinfo(host_name_normal, nullptr, &hints);
656 EXPECT_EQ(1U, GetNumQueries(dns1, host_name_deferred));
657 EXPECT_EQ(0U, GetNumQueries(dns2, host_name_deferred));
658 EXPECT_EQ(1U, GetNumQueries(dns3, host_name_normal));
659 EXPECT_TRUE(result != nullptr);
660 EXPECT_EQ("1.2.3.5", ToString(result));
661
662 t3_task_done = true;
663 dns1.setDeferredResp(false);
664 });
665 t3.join();
666 t1.join();
667 t2.join();
668}
669
lifr4e4a2e02019-01-29 16:53:51 +0800670TEST_F(ResolverTest, GetAddrInfo_cnames) {
671 constexpr char host_name[] = "host.example.com.";
672 test::DNSResponder dns;
673 const std::vector<DnsRecord> records = {
674 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
675 {"a.example.com.", ns_type::ns_t_cname, "b.example.com."},
676 {"b.example.com.", ns_type::ns_t_cname, "c.example.com."},
677 {"c.example.com.", ns_type::ns_t_cname, "d.example.com."},
678 {"d.example.com.", ns_type::ns_t_cname, "e.example.com."},
679 {"e.example.com.", ns_type::ns_t_cname, host_name},
680 {host_name, ns_type::ns_t_a, "1.2.3.3"},
681 {host_name, ns_type::ns_t_aaaa, "2001:db8::42"},
682 };
683 StartDns(dns, records);
684 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
685
686 addrinfo hints = {.ai_family = AF_INET};
687 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
688 EXPECT_TRUE(result != nullptr);
689 EXPECT_EQ("1.2.3.3", ToString(result));
690
691 dns.clearQueries();
692 hints = {.ai_family = AF_INET6};
693 result = safe_getaddrinfo("hello", nullptr, &hints);
694 EXPECT_TRUE(result != nullptr);
695 EXPECT_EQ("2001:db8::42", ToString(result));
696}
697
698TEST_F(ResolverTest, GetAddrInfo_cnamesNoIpAddress) {
699 test::DNSResponder dns;
700 const std::vector<DnsRecord> records = {
701 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
702 };
703 StartDns(dns, records);
704 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
705
706 addrinfo hints = {.ai_family = AF_INET};
707 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
708 EXPECT_TRUE(result == nullptr);
709
710 dns.clearQueries();
711 hints = {.ai_family = AF_INET6};
712 result = safe_getaddrinfo("hello", nullptr, &hints);
713 EXPECT_TRUE(result == nullptr);
714}
715
716TEST_F(ResolverTest, GetAddrInfo_cnamesIllegalRdata) {
717 test::DNSResponder dns;
718 const std::vector<DnsRecord> records = {
719 {kHelloExampleCom, ns_type::ns_t_cname, ".!#?"},
720 };
721 StartDns(dns, records);
722 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
723
724 addrinfo hints = {.ai_family = AF_INET};
725 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
726 EXPECT_TRUE(result == nullptr);
727
728 dns.clearQueries();
729 hints = {.ai_family = AF_INET6};
730 result = safe_getaddrinfo("hello", nullptr, &hints);
731 EXPECT_TRUE(result == nullptr);
732}
733
Ken Chenb9fa2062018-11-13 21:51:13 +0800734TEST_F(ResolverTest, MultidomainResolution) {
Xiao Ma09b71022018-12-11 17:56:32 +0900735 constexpr char host_name[] = "nihao.example2.com.";
Luke Huangf8215372019-11-22 11:53:41 +0800736 std::vector<std::string> searchDomains = {"example1.com", "example2.com", "example3.com"};
Ken Chenb9fa2062018-11-13 21:51:13 +0800737
Xiao Ma09b71022018-12-11 17:56:32 +0900738 test::DNSResponder dns("127.0.0.6");
739 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.3"}});
740 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({"127.0.0.6"}, searchDomains));
741
Ken Chenb9fa2062018-11-13 21:51:13 +0800742 const hostent* result = gethostbyname("nihao");
Xiao Ma09b71022018-12-11 17:56:32 +0900743
Ken Chenb9fa2062018-11-13 21:51:13 +0800744 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
745 ASSERT_FALSE(result == nullptr);
746 ASSERT_EQ(4, result->h_length);
747 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
748 EXPECT_EQ("1.2.3.3", ToString(result));
749 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800750}
751
752TEST_F(ResolverTest, GetAddrInfoV6_numeric) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800753 constexpr char host_name[] = "ohayou.example.com.";
754 constexpr char numeric_addr[] = "fe80::1%lo";
755
Xiao Ma09b71022018-12-11 17:56:32 +0900756 test::DNSResponder dns;
Ken Chenb9fa2062018-11-13 21:51:13 +0800757 dns.setResponseProbability(0.0);
Xiao Ma09b71022018-12-11 17:56:32 +0900758 StartDns(dns, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
759 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800760
761 addrinfo hints = {.ai_family = AF_INET6};
762 ScopedAddrinfo result = safe_getaddrinfo(numeric_addr, nullptr, &hints);
763 EXPECT_TRUE(result != nullptr);
764 EXPECT_EQ(numeric_addr, ToString(result));
765 EXPECT_TRUE(dns.queries().empty()); // Ensure no DNS queries were sent out
766
767 // Now try a non-numeric hostname query with the AI_NUMERICHOST flag set.
768 // We should fail without sending out a DNS query.
769 hints.ai_flags |= AI_NUMERICHOST;
770 result = safe_getaddrinfo(host_name, nullptr, &hints);
771 EXPECT_TRUE(result == nullptr);
772 EXPECT_TRUE(dns.queries().empty()); // Ensure no DNS queries were sent out
773}
774
775TEST_F(ResolverTest, GetAddrInfoV6_failing) {
Xiao Ma09b71022018-12-11 17:56:32 +0900776 constexpr char listen_addr0[] = "127.0.0.7";
777 constexpr char listen_addr1[] = "127.0.0.8";
Ken Chenb9fa2062018-11-13 21:51:13 +0800778 const char* host_name = "ohayou.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +0900779
780 test::DNSResponder dns0(listen_addr0);
781 test::DNSResponder dns1(listen_addr1);
Ken Chenb9fa2062018-11-13 21:51:13 +0800782 dns0.setResponseProbability(0.0);
Xiao Ma09b71022018-12-11 17:56:32 +0900783 StartDns(dns0, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
784 StartDns(dns1, {{host_name, ns_type::ns_t_aaaa, "2001:db8::6"}});
785
Luke Huangf8215372019-11-22 11:53:41 +0800786 std::vector<std::string> servers = {listen_addr0, listen_addr1};
Ken Chenb9fa2062018-11-13 21:51:13 +0800787 // <sample validity in s> <success threshold in percent> <min samples> <max samples>
788 int sample_count = 8;
Luke Huangf8215372019-11-22 11:53:41 +0800789 const std::vector<int> params = {300, 25, sample_count, sample_count};
Xiao Ma09b71022018-12-11 17:56:32 +0900790 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, kDefaultSearchDomains, params));
Ken Chenb9fa2062018-11-13 21:51:13 +0800791
792 // Repeatedly perform resolutions for non-existing domains until MAXNSSAMPLES resolutions have
793 // reached the dns0, which is set to fail. No more requests should then arrive at that server
794 // for the next sample_lifetime seconds.
795 // TODO: This approach is implementation-dependent, change once metrics reporting is available.
Xiao Ma09b71022018-12-11 17:56:32 +0900796 const addrinfo hints = {.ai_family = AF_INET6};
Bernie Innocentib102dd22018-12-04 14:57:48 +0900797 for (int i = 0; i < sample_count; ++i) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800798 std::string domain = StringPrintf("nonexistent%d", i);
799 ScopedAddrinfo result = safe_getaddrinfo(domain.c_str(), nullptr, &hints);
800 }
801 // Due to 100% errors for all possible samples, the server should be ignored from now on and
802 // only the second one used for all following queries, until NSSAMPLE_VALIDITY is reached.
803 dns0.clearQueries();
804 dns1.clearQueries();
805 ScopedAddrinfo result = safe_getaddrinfo("ohayou", nullptr, &hints);
806 EXPECT_TRUE(result != nullptr);
807 EXPECT_EQ(0U, GetNumQueries(dns0, host_name));
808 EXPECT_EQ(1U, GetNumQueries(dns1, host_name));
809}
810
811TEST_F(ResolverTest, GetAddrInfoV6_nonresponsive) {
Xiao Ma09b71022018-12-11 17:56:32 +0900812 constexpr char listen_addr0[] = "127.0.0.7";
813 constexpr char listen_addr1[] = "127.0.0.8";
814 constexpr char listen_srv[] = "53";
815 constexpr char host_name1[] = "ohayou.example.com.";
816 constexpr char host_name2[] = "ciao.example.com.";
Luke Huang483cf332019-06-03 17:24:51 +0800817 const std::vector<std::string> defaultSearchDomain = {"example.com"};
818 // The minimal timeout is 1000ms, so we can't decrease timeout
819 // So reduce retry count.
820 const std::vector<int> reduceRetryParams = {
821 300, // sample validity in seconds
822 25, // success threshod in percent
823 8, 8, // {MIN,MAX}_SAMPLES
824 1000, // BASE_TIMEOUT_MSEC
825 1, // retry count
826 };
Xiao Ma09b71022018-12-11 17:56:32 +0900827 const std::vector<DnsRecord> records0 = {
828 {host_name1, ns_type::ns_t_aaaa, "2001:db8::5"},
829 {host_name2, ns_type::ns_t_aaaa, "2001:db8::5"},
830 };
831 const std::vector<DnsRecord> records1 = {
832 {host_name1, ns_type::ns_t_aaaa, "2001:db8::6"},
833 {host_name2, ns_type::ns_t_aaaa, "2001:db8::6"},
834 };
Ken Chenb9fa2062018-11-13 21:51:13 +0800835
836 // dns0 does not respond with 100% probability, while
837 // dns1 responds normally, at least initially.
Mike Yufc125e42019-05-15 20:41:28 +0800838 test::DNSResponder dns0(listen_addr0, listen_srv, static_cast<ns_rcode>(-1));
839 test::DNSResponder dns1(listen_addr1, listen_srv, static_cast<ns_rcode>(-1));
Ken Chenb9fa2062018-11-13 21:51:13 +0800840 dns0.setResponseProbability(0.0);
Xiao Ma09b71022018-12-11 17:56:32 +0900841 StartDns(dns0, records0);
842 StartDns(dns1, records1);
Luke Huang483cf332019-06-03 17:24:51 +0800843 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr0, listen_addr1}, defaultSearchDomain,
844 reduceRetryParams));
Ken Chenb9fa2062018-11-13 21:51:13 +0800845
Luke Huang483cf332019-06-03 17:24:51 +0800846 // Specify ai_socktype to make getaddrinfo will only query 1 time
847 const addrinfo hints = {.ai_family = AF_INET6, .ai_socktype = SOCK_STREAM};
Ken Chenb9fa2062018-11-13 21:51:13 +0800848
849 // dns0 will ignore the request, and we'll fallback to dns1 after the first
850 // retry.
851 ScopedAddrinfo result = safe_getaddrinfo(host_name1, nullptr, &hints);
852 EXPECT_TRUE(result != nullptr);
853 EXPECT_EQ(1U, GetNumQueries(dns0, host_name1));
854 EXPECT_EQ(1U, GetNumQueries(dns1, host_name1));
855
856 // Now make dns1 also ignore 100% requests... The resolve should alternate
Luke Huang483cf332019-06-03 17:24:51 +0800857 // queries between the nameservers and fail
Ken Chenb9fa2062018-11-13 21:51:13 +0800858 dns1.setResponseProbability(0.0);
859 addrinfo* result2 = nullptr;
860 EXPECT_EQ(EAI_NODATA, getaddrinfo(host_name2, nullptr, &hints, &result2));
861 EXPECT_EQ(nullptr, result2);
Luke Huang483cf332019-06-03 17:24:51 +0800862 EXPECT_EQ(1U, GetNumQueries(dns0, host_name2));
863 EXPECT_EQ(1U, GetNumQueries(dns1, host_name2));
Ken Chenb9fa2062018-11-13 21:51:13 +0800864}
865
866TEST_F(ResolverTest, GetAddrInfoV6_concurrent) {
Xiao Ma09b71022018-12-11 17:56:32 +0900867 constexpr char listen_addr0[] = "127.0.0.9";
868 constexpr char listen_addr1[] = "127.0.0.10";
869 constexpr char listen_addr2[] = "127.0.0.11";
870 constexpr char host_name[] = "konbanha.example.com.";
871
872 test::DNSResponder dns0(listen_addr0);
873 test::DNSResponder dns1(listen_addr1);
874 test::DNSResponder dns2(listen_addr2);
875 StartDns(dns0, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
876 StartDns(dns1, {{host_name, ns_type::ns_t_aaaa, "2001:db8::6"}});
877 StartDns(dns2, {{host_name, ns_type::ns_t_aaaa, "2001:db8::7"}});
878
Luke Huangf8215372019-11-22 11:53:41 +0800879 const std::vector<std::string> servers = {listen_addr0, listen_addr1, listen_addr2};
Ken Chenb9fa2062018-11-13 21:51:13 +0800880 std::vector<std::thread> threads(10);
881 for (std::thread& thread : threads) {
Luke Huangf8215372019-11-22 11:53:41 +0800882 thread = std::thread([this, &servers]() {
883 unsigned delay = arc4random_uniform(1 * 1000 * 1000); // <= 1s
Ken Chenb9fa2062018-11-13 21:51:13 +0800884 usleep(delay);
885 std::vector<std::string> serverSubset;
886 for (const auto& server : servers) {
887 if (arc4random_uniform(2)) {
888 serverSubset.push_back(server);
889 }
890 }
891 if (serverSubset.empty()) serverSubset = servers;
Xiao Ma09b71022018-12-11 17:56:32 +0900892 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(serverSubset));
893 const addrinfo hints = {.ai_family = AF_INET6};
Ken Chenb9fa2062018-11-13 21:51:13 +0800894 addrinfo* result = nullptr;
895 int rv = getaddrinfo("konbanha", nullptr, &hints, &result);
896 EXPECT_EQ(0, rv) << "error [" << rv << "] " << gai_strerror(rv);
897 if (result) {
898 freeaddrinfo(result);
899 result = nullptr;
900 }
901 });
902 }
903 for (std::thread& thread : threads) {
904 thread.join();
905 }
Ken Chen92bed612018-12-22 21:46:55 +0800906
907 std::vector<std::string> res_servers;
908 std::vector<std::string> res_domains;
909 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900910 res_params res_params;
Ken Chen92bed612018-12-22 21:46:55 +0800911 std::vector<ResolverStats> res_stats;
912 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800913 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
914 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
915 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chen92bed612018-12-22 21:46:55 +0800916 EXPECT_EQ(0, wait_for_pending_req_timeout_count);
Ken Chenb9fa2062018-11-13 21:51:13 +0800917}
918
Ken Chenb9fa2062018-11-13 21:51:13 +0800919TEST_F(ResolverTest, EmptySetup) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800920 std::vector<std::string> servers;
921 std::vector<std::string> domains;
Xiao Ma09b71022018-12-11 17:56:32 +0900922 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Ken Chenb9fa2062018-11-13 21:51:13 +0800923 std::vector<std::string> res_servers;
924 std::vector<std::string> res_domains;
Mike Yu0a1c53d2018-11-26 13:26:21 +0900925 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900926 res_params res_params;
Ken Chenb9fa2062018-11-13 21:51:13 +0800927 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +0800928 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800929 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
930 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
931 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chenb9fa2062018-11-13 21:51:13 +0800932 EXPECT_EQ(0U, res_servers.size());
933 EXPECT_EQ(0U, res_domains.size());
Mike Yu0a1c53d2018-11-26 13:26:21 +0900934 EXPECT_EQ(0U, res_tls_servers.size());
Luke Huang5bd827c2019-03-14 16:10:04 +0800935 ASSERT_EQ(static_cast<size_t>(IDnsResolver::RESOLVER_PARAMS_COUNT), kDefaultParams.size());
936 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY],
937 res_params.sample_validity);
938 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD],
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900939 res_params.success_threshold);
Luke Huang5bd827c2019-03-14 16:10:04 +0800940 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
941 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
942 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
Ken Chenb9fa2062018-11-13 21:51:13 +0800943 res_params.base_timeout_msec);
Luke Huang5bd827c2019-03-14 16:10:04 +0800944 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT], res_params.retry_count);
Ken Chenb9fa2062018-11-13 21:51:13 +0800945}
946
947TEST_F(ResolverTest, SearchPathChange) {
Xiao Ma09b71022018-12-11 17:56:32 +0900948 constexpr char listen_addr[] = "127.0.0.13";
949 constexpr char host_name1[] = "test13.domain1.org.";
950 constexpr char host_name2[] = "test13.domain2.org.";
Luke Huangf8215372019-11-22 11:53:41 +0800951 std::vector<std::string> servers = {listen_addr};
952 std::vector<std::string> domains = {"domain1.org"};
Xiao Ma09b71022018-12-11 17:56:32 +0900953
954 const std::vector<DnsRecord> records = {
955 {host_name1, ns_type::ns_t_aaaa, "2001:db8::13"},
956 {host_name2, ns_type::ns_t_aaaa, "2001:db8::1:13"},
957 };
958 test::DNSResponder dns(listen_addr);
959 StartDns(dns, records);
960 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Ken Chenb9fa2062018-11-13 21:51:13 +0800961
962 const addrinfo hints = {.ai_family = AF_INET6};
963 ScopedAddrinfo result = safe_getaddrinfo("test13", nullptr, &hints);
964 EXPECT_TRUE(result != nullptr);
965 EXPECT_EQ(1U, dns.queries().size());
966 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
967 EXPECT_EQ("2001:db8::13", ToString(result));
968
969 // Test that changing the domain search path on its own works.
Luke Huangf8215372019-11-22 11:53:41 +0800970 domains = {"domain2.org"};
Xiao Ma09b71022018-12-11 17:56:32 +0900971 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Ken Chenb9fa2062018-11-13 21:51:13 +0800972 dns.clearQueries();
973
974 result = safe_getaddrinfo("test13", nullptr, &hints);
975 EXPECT_TRUE(result != nullptr);
976 EXPECT_EQ(1U, dns.queries().size());
977 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
978 EXPECT_EQ("2001:db8::1:13", ToString(result));
979}
980
Luke Huang2dac4382019-06-24 13:28:44 +0800981namespace {
982
Luke Huangf8215372019-11-22 11:53:41 +0800983std::vector<std::string> getResolverDomains(aidl::android::net::IDnsResolver* dnsResolverService,
Luke Huang2dac4382019-06-24 13:28:44 +0800984 unsigned netId) {
985 std::vector<std::string> res_servers;
986 std::vector<std::string> res_domains;
987 std::vector<std::string> res_tls_servers;
988 res_params res_params;
989 std::vector<ResolverStats> res_stats;
990 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800991 DnsResponderClient::GetResolverInfo(dnsResolverService, netId, &res_servers, &res_domains,
992 &res_tls_servers, &res_params, &res_stats,
993 &wait_for_pending_req_timeout_count);
Luke Huang2dac4382019-06-24 13:28:44 +0800994 return res_domains;
995}
996
997} // namespace
998
999TEST_F(ResolverTest, SearchPathPrune) {
1000 constexpr size_t DUPLICATED_DOMAIN_NUM = 3;
1001 constexpr char listen_addr[] = "127.0.0.13";
1002 constexpr char domian_name1[] = "domain13.org.";
1003 constexpr char domian_name2[] = "domain14.org.";
1004 constexpr char host_name1[] = "test13.domain13.org.";
1005 constexpr char host_name2[] = "test14.domain14.org.";
1006 std::vector<std::string> servers = {listen_addr};
1007
1008 std::vector<std::string> testDomains1;
1009 std::vector<std::string> testDomains2;
1010 // Domain length should be <= 255
1011 // Max number of domains in search path is 6
1012 for (size_t i = 0; i < MAXDNSRCH + 1; i++) {
1013 // Fill up with invalid domain
1014 testDomains1.push_back(std::string(300, i + '0'));
1015 // Fill up with valid but duplicated domain
1016 testDomains2.push_back(StringPrintf("domain%zu.org", i % DUPLICATED_DOMAIN_NUM));
1017 }
1018
1019 // Add valid domain used for query.
1020 testDomains1.push_back(domian_name1);
1021
1022 // Add valid domain twice used for query.
1023 testDomains2.push_back(domian_name2);
1024 testDomains2.push_back(domian_name2);
1025
1026 const std::vector<DnsRecord> records = {
1027 {host_name1, ns_type::ns_t_aaaa, "2001:db8::13"},
1028 {host_name2, ns_type::ns_t_aaaa, "2001:db8::1:13"},
1029 };
1030 test::DNSResponder dns(listen_addr);
1031 StartDns(dns, records);
1032 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, testDomains1));
1033
1034 const addrinfo hints = {.ai_family = AF_INET6};
1035 ScopedAddrinfo result = safe_getaddrinfo("test13", nullptr, &hints);
1036
1037 EXPECT_TRUE(result != nullptr);
1038
1039 EXPECT_EQ(1U, dns.queries().size());
1040 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
1041 EXPECT_EQ("2001:db8::13", ToString(result));
1042
1043 const auto& res_domains1 = getResolverDomains(mDnsClient.resolvService(), TEST_NETID);
1044 // Expect 1 valid domain, invalid domains are removed.
1045 ASSERT_EQ(1U, res_domains1.size());
1046 EXPECT_EQ(domian_name1, res_domains1[0]);
1047
1048 dns.clearQueries();
1049
1050 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, testDomains2));
1051
1052 result = safe_getaddrinfo("test14", nullptr, &hints);
1053 EXPECT_TRUE(result != nullptr);
1054
1055 // (3 domains * 2 retries) + 1 success query = 7
1056 EXPECT_EQ(7U, dns.queries().size());
1057 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
1058 EXPECT_EQ("2001:db8::1:13", ToString(result));
1059
1060 const auto& res_domains2 = getResolverDomains(mDnsClient.resolvService(), TEST_NETID);
1061 // Expect 4 valid domain, duplicate domains are removed.
1062 EXPECT_EQ(DUPLICATED_DOMAIN_NUM + 1U, res_domains2.size());
1063 EXPECT_THAT(
1064 std::vector<std::string>({"domain0.org", "domain1.org", "domain2.org", domian_name2}),
1065 testing::ElementsAreArray(res_domains2));
1066}
1067
Mike Yu0a1c53d2018-11-26 13:26:21 +09001068// If we move this function to dns_responder_client, it will complicate the dependency need of
1069// dns_tls_frontend.h.
1070static void setupTlsServers(const std::vector<std::string>& servers,
waynema0e73c2e2019-07-31 15:04:08 +08001071 std::vector<std::unique_ptr<test::DnsTlsFrontend>>* tls) {
Xiao Ma09b71022018-12-11 17:56:32 +09001072 constexpr char listen_udp[] = "53";
1073 constexpr char listen_tls[] = "853";
Mike Yu0a1c53d2018-11-26 13:26:21 +09001074
1075 for (const auto& server : servers) {
1076 auto t = std::make_unique<test::DnsTlsFrontend>(server, listen_tls, server, listen_udp);
1077 t = std::make_unique<test::DnsTlsFrontend>(server, listen_tls, server, listen_udp);
1078 t->startServer();
Mike Yu0a1c53d2018-11-26 13:26:21 +09001079 tls->push_back(std::move(t));
1080 }
1081}
1082
Mike Yu0a1c53d2018-11-26 13:26:21 +09001083TEST_F(ResolverTest, MaxServerPrune_Binder) {
Mike Yu0a1c53d2018-11-26 13:26:21 +09001084 std::vector<std::string> domains;
1085 std::vector<std::unique_ptr<test::DNSResponder>> dns;
1086 std::vector<std::unique_ptr<test::DnsTlsFrontend>> tls;
1087 std::vector<std::string> servers;
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +09001088 std::vector<DnsResponderClient::Mapping> mappings;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001089
1090 for (unsigned i = 0; i < MAXDNSRCH + 1; i++) {
1091 domains.push_back(StringPrintf("example%u.com", i));
1092 }
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +09001093 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupMappings(1, domains, &mappings));
1094 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupDNSServers(MAXNS + 1, mappings, &dns, &servers));
waynema0e73c2e2019-07-31 15:04:08 +08001095 ASSERT_NO_FATAL_FAILURE(setupTlsServers(servers, &tls));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001096
waynema0e73c2e2019-07-31 15:04:08 +08001097 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, domains, kDefaultParams,
1098 kDefaultPrivateDnsHostName));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001099
Mike Yu383855b2019-01-15 17:53:27 +08001100 // If the private DNS validation hasn't completed yet before backend DNS servers stop,
1101 // TLS servers will get stuck in handleOneRequest(), which causes this test stuck in
1102 // ~DnsTlsFrontend() because the TLS server loop threads can't be terminated.
1103 // So, wait for private DNS validation done before stopping backend DNS servers.
1104 for (int i = 0; i < MAXNS; i++) {
chenbruceaff85842019-05-31 15:46:42 +08001105 LOG(INFO) << "Waiting for private DNS validation on " << tls[i]->listen_address() << ".";
Mike Yu724f77d2019-08-16 11:14:50 +08001106 EXPECT_TRUE(WaitForPrivateDnsValidation(tls[i]->listen_address(), true));
chenbruceaff85842019-05-31 15:46:42 +08001107 LOG(INFO) << "private DNS validation on " << tls[i]->listen_address() << " done.";
Mike Yu383855b2019-01-15 17:53:27 +08001108 }
1109
Mike Yu0a1c53d2018-11-26 13:26:21 +09001110 std::vector<std::string> res_servers;
1111 std::vector<std::string> res_domains;
1112 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +09001113 res_params res_params;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001114 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +08001115 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +08001116 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
1117 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
1118 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001119
1120 // Check the size of the stats and its contents.
1121 EXPECT_EQ(static_cast<size_t>(MAXNS), res_servers.size());
1122 EXPECT_EQ(static_cast<size_t>(MAXNS), res_tls_servers.size());
1123 EXPECT_EQ(static_cast<size_t>(MAXDNSRCH), res_domains.size());
1124 EXPECT_TRUE(std::equal(servers.begin(), servers.begin() + MAXNS, res_servers.begin()));
1125 EXPECT_TRUE(std::equal(servers.begin(), servers.begin() + MAXNS, res_tls_servers.begin()));
1126 EXPECT_TRUE(std::equal(domains.begin(), domains.begin() + MAXDNSRCH, res_domains.begin()));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001127}
1128
1129TEST_F(ResolverTest, ResolverStats) {
Xiao Ma09b71022018-12-11 17:56:32 +09001130 constexpr char listen_addr1[] = "127.0.0.4";
1131 constexpr char listen_addr2[] = "127.0.0.5";
1132 constexpr char listen_addr3[] = "127.0.0.6";
Mike Yu0a1c53d2018-11-26 13:26:21 +09001133
1134 // Set server 1 timeout.
Mike Yufc125e42019-05-15 20:41:28 +08001135 test::DNSResponder dns1(listen_addr1, "53", static_cast<ns_rcode>(-1));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001136 dns1.setResponseProbability(0.0);
1137 ASSERT_TRUE(dns1.startServer());
1138
1139 // Set server 2 responding server failure.
Xiao Ma09b71022018-12-11 17:56:32 +09001140 test::DNSResponder dns2(listen_addr2);
Mike Yu0a1c53d2018-11-26 13:26:21 +09001141 dns2.setResponseProbability(0.0);
1142 ASSERT_TRUE(dns2.startServer());
1143
1144 // Set server 3 workable.
Xiao Ma09b71022018-12-11 17:56:32 +09001145 test::DNSResponder dns3(listen_addr3);
1146 dns3.addMapping(kHelloExampleCom, ns_type::ns_t_a, "1.2.3.4");
Mike Yu0a1c53d2018-11-26 13:26:21 +09001147 ASSERT_TRUE(dns3.startServer());
1148
1149 std::vector<std::string> servers = {listen_addr1, listen_addr2, listen_addr3};
Xiao Ma09b71022018-12-11 17:56:32 +09001150 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001151
1152 dns3.clearQueries();
Xiao Ma09b71022018-12-11 17:56:32 +09001153 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
Mike Yu0a1c53d2018-11-26 13:26:21 +09001154 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
Xiao Ma09b71022018-12-11 17:56:32 +09001155 size_t found = GetNumQueries(dns3, kHelloExampleCom);
Mike Yu0a1c53d2018-11-26 13:26:21 +09001156 EXPECT_LE(1U, found);
1157 std::string result_str = ToString(result);
1158 EXPECT_TRUE(result_str == "1.2.3.4") << ", result_str='" << result_str << "'";
1159
1160 std::vector<std::string> res_servers;
1161 std::vector<std::string> res_domains;
1162 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +09001163 res_params res_params;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001164 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +08001165 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +08001166 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
1167 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
1168 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001169
1170 EXPECT_EQ(1, res_stats[0].timeouts);
1171 EXPECT_EQ(1, res_stats[1].errors);
1172 EXPECT_EQ(1, res_stats[2].successes);
Mike Yu0a1c53d2018-11-26 13:26:21 +09001173}
1174
Ken Chenb9fa2062018-11-13 21:51:13 +08001175// Test what happens if the specified TLS server is nonexistent.
1176TEST_F(ResolverTest, GetHostByName_TlsMissing) {
Xiao Ma09b71022018-12-11 17:56:32 +09001177 constexpr char listen_addr[] = "127.0.0.3";
1178 constexpr char host_name[] = "tlsmissing.example.com.";
1179
1180 test::DNSResponder dns;
1181 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.3"}});
Luke Huangf8215372019-11-22 11:53:41 +08001182 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001183
1184 // There's nothing listening on this address, so validation will either fail or
1185 /// hang. Either way, queries will continue to flow to the DNSResponder.
waynema0e73c2e2019-07-31 15:04:08 +08001186 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Ken Chenb9fa2062018-11-13 21:51:13 +08001187
1188 const hostent* result;
1189
1190 result = gethostbyname("tlsmissing");
1191 ASSERT_FALSE(result == nullptr);
1192 EXPECT_EQ("1.2.3.3", ToString(result));
1193
1194 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001195 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001196}
1197
1198// Test what happens if the specified TLS server replies with garbage.
1199TEST_F(ResolverTest, GetHostByName_TlsBroken) {
Xiao Ma09b71022018-12-11 17:56:32 +09001200 constexpr char listen_addr[] = "127.0.0.3";
1201 constexpr char host_name1[] = "tlsbroken1.example.com.";
1202 constexpr char host_name2[] = "tlsbroken2.example.com.";
1203 const std::vector<DnsRecord> records = {
1204 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1205 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1206 };
1207
1208 test::DNSResponder dns;
1209 StartDns(dns, records);
Luke Huangf8215372019-11-22 11:53:41 +08001210 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001211
1212 // Bind the specified private DNS socket but don't respond to any client sockets yet.
1213 int s = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
1214 ASSERT_TRUE(s >= 0);
1215 struct sockaddr_in tlsServer = {
Luke Huangf8215372019-11-22 11:53:41 +08001216 .sin_family = AF_INET,
1217 .sin_port = htons(853),
Ken Chenb9fa2062018-11-13 21:51:13 +08001218 };
1219 ASSERT_TRUE(inet_pton(AF_INET, listen_addr, &tlsServer.sin_addr));
1220 ASSERT_TRUE(enableSockopt(s, SOL_SOCKET, SO_REUSEPORT).ok());
1221 ASSERT_TRUE(enableSockopt(s, SOL_SOCKET, SO_REUSEADDR).ok());
1222 ASSERT_FALSE(bind(s, reinterpret_cast<struct sockaddr*>(&tlsServer), sizeof(tlsServer)));
1223 ASSERT_FALSE(listen(s, 1));
1224
1225 // Trigger TLS validation.
waynema0e73c2e2019-07-31 15:04:08 +08001226 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Ken Chenb9fa2062018-11-13 21:51:13 +08001227
1228 struct sockaddr_storage cliaddr;
1229 socklen_t sin_size = sizeof(cliaddr);
Luke Huangf8215372019-11-22 11:53:41 +08001230 int new_fd = accept4(s, reinterpret_cast<struct sockaddr*>(&cliaddr), &sin_size, SOCK_CLOEXEC);
Ken Chenb9fa2062018-11-13 21:51:13 +08001231 ASSERT_TRUE(new_fd > 0);
1232
1233 // We've received the new file descriptor but not written to it or closed, so the
1234 // validation is still pending. Queries should still flow correctly because the
1235 // server is not used until validation succeeds.
1236 const hostent* result;
1237 result = gethostbyname("tlsbroken1");
1238 ASSERT_FALSE(result == nullptr);
1239 EXPECT_EQ("1.2.3.1", ToString(result));
1240
1241 // Now we cause the validation to fail.
1242 std::string garbage = "definitely not a valid TLS ServerHello";
1243 write(new_fd, garbage.data(), garbage.size());
1244 close(new_fd);
1245
1246 // Validation failure shouldn't interfere with lookups, because lookups won't be sent
1247 // to the TLS server unless validation succeeds.
1248 result = gethostbyname("tlsbroken2");
1249 ASSERT_FALSE(result == nullptr);
1250 EXPECT_EQ("1.2.3.2", ToString(result));
1251
1252 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001253 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001254 close(s);
1255}
1256
1257TEST_F(ResolverTest, GetHostByName_Tls) {
Xiao Ma09b71022018-12-11 17:56:32 +09001258 constexpr char listen_addr[] = "127.0.0.3";
1259 constexpr char listen_udp[] = "53";
1260 constexpr char listen_tls[] = "853";
1261 constexpr char host_name1[] = "tls1.example.com.";
1262 constexpr char host_name2[] = "tls2.example.com.";
1263 constexpr char host_name3[] = "tls3.example.com.";
1264 const std::vector<DnsRecord> records = {
1265 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1266 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1267 {host_name3, ns_type::ns_t_a, "1.2.3.3"},
1268 };
1269
1270 test::DNSResponder dns;
1271 StartDns(dns, records);
Luke Huangf8215372019-11-22 11:53:41 +08001272 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001273
1274 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1275 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08001276 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08001277 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Ken Chenb9fa2062018-11-13 21:51:13 +08001278
Mike Yu724f77d2019-08-16 11:14:50 +08001279 const hostent* result = gethostbyname("tls1");
Ken Chenb9fa2062018-11-13 21:51:13 +08001280 ASSERT_FALSE(result == nullptr);
1281 EXPECT_EQ("1.2.3.1", ToString(result));
1282
1283 // Wait for query to get counted.
1284 EXPECT_TRUE(tls.waitForQueries(2, 5000));
1285
1286 // Stop the TLS server. Since we're in opportunistic mode, queries will
1287 // fall back to the locally-assigned (clear text) nameservers.
1288 tls.stopServer();
1289
1290 dns.clearQueries();
1291 result = gethostbyname("tls2");
1292 EXPECT_FALSE(result == nullptr);
1293 EXPECT_EQ("1.2.3.2", ToString(result));
1294 const auto queries = dns.queries();
1295 EXPECT_EQ(1U, queries.size());
1296 EXPECT_EQ("tls2.example.com.", queries[0].first);
1297 EXPECT_EQ(ns_t_a, queries[0].second);
1298
1299 // Reset the resolvers without enabling TLS. Queries should still be routed
1300 // to the UDP endpoint.
Xiao Ma09b71022018-12-11 17:56:32 +09001301 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001302
1303 result = gethostbyname("tls3");
1304 ASSERT_FALSE(result == nullptr);
1305 EXPECT_EQ("1.2.3.3", ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +08001306}
1307
Ken Chenb9fa2062018-11-13 21:51:13 +08001308TEST_F(ResolverTest, GetHostByName_TlsFailover) {
Xiao Ma09b71022018-12-11 17:56:32 +09001309 constexpr char listen_addr1[] = "127.0.0.3";
1310 constexpr char listen_addr2[] = "127.0.0.4";
1311 constexpr char listen_udp[] = "53";
1312 constexpr char listen_tls[] = "853";
1313 constexpr char host_name1[] = "tlsfailover1.example.com.";
1314 constexpr char host_name2[] = "tlsfailover2.example.com.";
1315 const std::vector<DnsRecord> records1 = {
1316 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1317 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1318 };
1319 const std::vector<DnsRecord> records2 = {
1320 {host_name1, ns_type::ns_t_a, "1.2.3.3"},
1321 {host_name2, ns_type::ns_t_a, "1.2.3.4"},
1322 };
1323
1324 test::DNSResponder dns1(listen_addr1);
1325 test::DNSResponder dns2(listen_addr2);
1326 StartDns(dns1, records1);
1327 StartDns(dns2, records2);
1328
Luke Huangf8215372019-11-22 11:53:41 +08001329 std::vector<std::string> servers = {listen_addr1, listen_addr2};
Ken Chenb9fa2062018-11-13 21:51:13 +08001330
1331 test::DnsTlsFrontend tls1(listen_addr1, listen_tls, listen_addr1, listen_udp);
1332 test::DnsTlsFrontend tls2(listen_addr2, listen_tls, listen_addr2, listen_udp);
1333 ASSERT_TRUE(tls1.startServer());
1334 ASSERT_TRUE(tls2.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08001335 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
1336 kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08001337 EXPECT_TRUE(WaitForPrivateDnsValidation(tls1.listen_address(), true));
1338 EXPECT_TRUE(WaitForPrivateDnsValidation(tls2.listen_address(), true));
Ken Chenb9fa2062018-11-13 21:51:13 +08001339
Mike Yu724f77d2019-08-16 11:14:50 +08001340 const hostent* result = gethostbyname("tlsfailover1");
Ken Chenb9fa2062018-11-13 21:51:13 +08001341 ASSERT_FALSE(result == nullptr);
1342 EXPECT_EQ("1.2.3.1", ToString(result));
1343
1344 // Wait for query to get counted.
1345 EXPECT_TRUE(tls1.waitForQueries(2, 5000));
1346 // No new queries should have reached tls2.
1347 EXPECT_EQ(1, tls2.queries());
1348
1349 // Stop tls1. Subsequent queries should attempt to reach tls1, fail, and retry to tls2.
1350 tls1.stopServer();
1351
1352 result = gethostbyname("tlsfailover2");
1353 EXPECT_EQ("1.2.3.4", ToString(result));
1354
1355 // Wait for query to get counted.
1356 EXPECT_TRUE(tls2.waitForQueries(2, 5000));
1357
1358 // No additional queries should have reached the insecure servers.
1359 EXPECT_EQ(2U, dns1.queries().size());
1360 EXPECT_EQ(2U, dns2.queries().size());
1361
1362 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001363 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Ken Chenb9fa2062018-11-13 21:51:13 +08001364}
1365
1366TEST_F(ResolverTest, GetHostByName_BadTlsName) {
Xiao Ma09b71022018-12-11 17:56:32 +09001367 constexpr char listen_addr[] = "127.0.0.3";
1368 constexpr char listen_udp[] = "53";
1369 constexpr char listen_tls[] = "853";
1370 constexpr char host_name[] = "badtlsname.example.com.";
1371
1372 test::DNSResponder dns;
1373 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.1"}});
Luke Huangf8215372019-11-22 11:53:41 +08001374 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001375
1376 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1377 ASSERT_TRUE(tls.startServer());
Xiao Ma09b71022018-12-11 17:56:32 +09001378 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
waynema0e73c2e2019-07-31 15:04:08 +08001379 kDefaultIncorrectPrivateDnsHostName));
Ken Chenb9fa2062018-11-13 21:51:13 +08001380
waynema0e73c2e2019-07-31 15:04:08 +08001381 // The TLS handshake would fail because the name of TLS server doesn't
1382 // match with TLS server's certificate.
Mike Yu724f77d2019-08-16 11:14:50 +08001383 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), false));
Ken Chenb9fa2062018-11-13 21:51:13 +08001384
1385 // The query should fail hard, because a name was specified.
1386 EXPECT_EQ(nullptr, gethostbyname("badtlsname"));
1387
1388 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001389 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001390}
1391
1392TEST_F(ResolverTest, GetAddrInfo_Tls) {
Xiao Ma09b71022018-12-11 17:56:32 +09001393 constexpr char listen_addr[] = "127.0.0.3";
1394 constexpr char listen_udp[] = "53";
1395 constexpr char listen_tls[] = "853";
1396 constexpr char host_name[] = "addrinfotls.example.com.";
1397 const std::vector<DnsRecord> records = {
1398 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1399 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1400 };
1401
1402 test::DNSResponder dns;
1403 StartDns(dns, records);
Luke Huangf8215372019-11-22 11:53:41 +08001404 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001405
1406 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1407 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08001408 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
1409 kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08001410 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Ken Chenb9fa2062018-11-13 21:51:13 +08001411
1412 dns.clearQueries();
1413 ScopedAddrinfo result = safe_getaddrinfo("addrinfotls", nullptr, nullptr);
1414 EXPECT_TRUE(result != nullptr);
1415 size_t found = GetNumQueries(dns, host_name);
1416 EXPECT_LE(1U, found);
1417 // Could be A or AAAA
1418 std::string result_str = ToString(result);
1419 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
Luke Huangf8215372019-11-22 11:53:41 +08001420 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +08001421 // Wait for both A and AAAA queries to get counted.
1422 EXPECT_TRUE(tls.waitForQueries(3, 5000));
1423
1424 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001425 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001426}
1427
1428TEST_F(ResolverTest, TlsBypass) {
1429 const char OFF[] = "off";
1430 const char OPPORTUNISTIC[] = "opportunistic";
1431 const char STRICT[] = "strict";
1432
1433 const char GETHOSTBYNAME[] = "gethostbyname";
1434 const char GETADDRINFO[] = "getaddrinfo";
1435 const char GETADDRINFOFORNET[] = "getaddrinfofornet";
1436
1437 const unsigned BYPASS_NETID = NETID_USE_LOCAL_NAMESERVERS | TEST_NETID;
1438
Ken Chenb9fa2062018-11-13 21:51:13 +08001439 const char ADDR4[] = "192.0.2.1";
1440 const char ADDR6[] = "2001:db8::1";
1441
1442 const char cleartext_addr[] = "127.0.0.53";
1443 const char cleartext_port[] = "53";
1444 const char tls_port[] = "853";
Luke Huangf8215372019-11-22 11:53:41 +08001445 const std::vector<std::string> servers = {cleartext_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001446
Xiao Ma09b71022018-12-11 17:56:32 +09001447 test::DNSResponder dns(cleartext_addr);
Ken Chenb9fa2062018-11-13 21:51:13 +08001448 ASSERT_TRUE(dns.startServer());
1449
1450 test::DnsTlsFrontend tls(cleartext_addr, tls_port, cleartext_addr, cleartext_port);
Mike Yudd4ac2d2019-05-31 16:52:11 +08001451 ASSERT_TRUE(tls.startServer());
Ken Chenb9fa2062018-11-13 21:51:13 +08001452
Luke Huangf8215372019-11-22 11:53:41 +08001453 // clang-format off
Ken Chenb9fa2062018-11-13 21:51:13 +08001454 struct TestConfig {
1455 const std::string mode;
1456 const bool withWorkingTLS;
1457 const std::string method;
1458
1459 std::string asHostName() const {
Luke Huangf8215372019-11-22 11:53:41 +08001460 return StringPrintf("%s.%s.%s.", mode.c_str(), withWorkingTLS ? "tlsOn" : "tlsOff",
Ken Chenb9fa2062018-11-13 21:51:13 +08001461 method.c_str());
1462 }
1463 } testConfigs[]{
Ken Chenb9fa2062018-11-13 21:51:13 +08001464 {OFF, true, GETHOSTBYNAME},
1465 {OPPORTUNISTIC, true, GETHOSTBYNAME},
1466 {STRICT, true, GETHOSTBYNAME},
Ken Chenb9fa2062018-11-13 21:51:13 +08001467 {OFF, true, GETADDRINFO},
1468 {OPPORTUNISTIC, true, GETADDRINFO},
1469 {STRICT, true, GETADDRINFO},
Ken Chenb9fa2062018-11-13 21:51:13 +08001470 {OFF, true, GETADDRINFOFORNET},
1471 {OPPORTUNISTIC, true, GETADDRINFOFORNET},
1472 {STRICT, true, GETADDRINFOFORNET},
Mike Yudd4ac2d2019-05-31 16:52:11 +08001473 {OFF, false, GETHOSTBYNAME},
1474 {OPPORTUNISTIC, false, GETHOSTBYNAME},
1475 {STRICT, false, GETHOSTBYNAME},
1476 {OFF, false, GETADDRINFO},
1477 {OPPORTUNISTIC, false, GETADDRINFO},
1478 {STRICT, false, GETADDRINFO},
1479 {OFF, false, GETADDRINFOFORNET},
1480 {OPPORTUNISTIC, false, GETADDRINFOFORNET},
1481 {STRICT, false, GETADDRINFOFORNET},
Ken Chenb9fa2062018-11-13 21:51:13 +08001482 };
Luke Huangf8215372019-11-22 11:53:41 +08001483 // clang-format on
Ken Chenb9fa2062018-11-13 21:51:13 +08001484
1485 for (const auto& config : testConfigs) {
1486 const std::string testHostName = config.asHostName();
1487 SCOPED_TRACE(testHostName);
1488
1489 // Don't tempt test bugs due to caching.
1490 const char* host_name = testHostName.c_str();
1491 dns.addMapping(host_name, ns_type::ns_t_a, ADDR4);
1492 dns.addMapping(host_name, ns_type::ns_t_aaaa, ADDR6);
1493
Mike Yudd4ac2d2019-05-31 16:52:11 +08001494 if (config.withWorkingTLS) {
1495 if (!tls.running()) {
1496 ASSERT_TRUE(tls.startServer());
1497 }
1498 } else {
1499 if (tls.running()) {
1500 ASSERT_TRUE(tls.stopServer());
1501 }
1502 }
Ken Chenb9fa2062018-11-13 21:51:13 +08001503
1504 if (config.mode == OFF) {
Xiao Ma09b71022018-12-11 17:56:32 +09001505 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, kDefaultSearchDomains,
1506 kDefaultParams));
Ken Chenb9fa2062018-11-13 21:51:13 +08001507 } else if (config.mode == OPPORTUNISTIC) {
Xiao Ma09b71022018-12-11 17:56:32 +09001508 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08001509 kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08001510
1511 // Wait for the validation event. If the server is running, the validation should
1512 // be successful; otherwise, the validation should be failed.
1513 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), config.withWorkingTLS));
Ken Chenb9fa2062018-11-13 21:51:13 +08001514 } else if (config.mode == STRICT) {
Xiao Ma09b71022018-12-11 17:56:32 +09001515 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08001516 kDefaultParams, kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08001517
1518 // Wait for the validation event.
1519 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), config.withWorkingTLS));
Ken Chenb9fa2062018-11-13 21:51:13 +08001520 }
Mike Yudd4ac2d2019-05-31 16:52:11 +08001521 tls.clearQueries();
Ken Chenb9fa2062018-11-13 21:51:13 +08001522
1523 const hostent* h_result = nullptr;
1524 ScopedAddrinfo ai_result;
1525
1526 if (config.method == GETHOSTBYNAME) {
1527 ASSERT_EQ(0, setNetworkForResolv(BYPASS_NETID));
1528 h_result = gethostbyname(host_name);
1529
1530 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
1531 ASSERT_FALSE(h_result == nullptr);
1532 ASSERT_EQ(4, h_result->h_length);
1533 ASSERT_FALSE(h_result->h_addr_list[0] == nullptr);
1534 EXPECT_EQ(ADDR4, ToString(h_result));
1535 EXPECT_TRUE(h_result->h_addr_list[1] == nullptr);
1536 } else if (config.method == GETADDRINFO) {
1537 ASSERT_EQ(0, setNetworkForResolv(BYPASS_NETID));
1538 ai_result = safe_getaddrinfo(host_name, nullptr, nullptr);
1539 EXPECT_TRUE(ai_result != nullptr);
1540
1541 EXPECT_LE(1U, GetNumQueries(dns, host_name));
1542 // Could be A or AAAA
1543 const std::string result_str = ToString(ai_result);
1544 EXPECT_TRUE(result_str == ADDR4 || result_str == ADDR6)
Luke Huangf8215372019-11-22 11:53:41 +08001545 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +08001546 } else if (config.method == GETADDRINFOFORNET) {
1547 addrinfo* raw_ai_result = nullptr;
1548 EXPECT_EQ(0, android_getaddrinfofornet(host_name, /*servname=*/nullptr,
1549 /*hints=*/nullptr, BYPASS_NETID, MARK_UNSET,
1550 &raw_ai_result));
1551 ai_result.reset(raw_ai_result);
1552
1553 EXPECT_LE(1U, GetNumQueries(dns, host_name));
1554 // Could be A or AAAA
1555 const std::string result_str = ToString(ai_result);
1556 EXPECT_TRUE(result_str == ADDR4 || result_str == ADDR6)
Luke Huangf8215372019-11-22 11:53:41 +08001557 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +08001558 }
1559
Mike Yudd4ac2d2019-05-31 16:52:11 +08001560 EXPECT_EQ(0, tls.queries());
Ken Chenb9fa2062018-11-13 21:51:13 +08001561
1562 // Clear per-process resolv netid.
1563 ASSERT_EQ(0, setNetworkForResolv(NETID_UNSET));
Ken Chenb9fa2062018-11-13 21:51:13 +08001564 dns.clearQueries();
1565 }
Ken Chenb9fa2062018-11-13 21:51:13 +08001566}
1567
1568TEST_F(ResolverTest, StrictMode_NoTlsServers) {
Xiao Ma09b71022018-12-11 17:56:32 +09001569 constexpr char cleartext_addr[] = "127.0.0.53";
Luke Huangf8215372019-11-22 11:53:41 +08001570 const std::vector<std::string> servers = {cleartext_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001571 constexpr char host_name[] = "strictmode.notlsips.example.com.";
1572 const std::vector<DnsRecord> records = {
1573 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1574 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1575 };
Ken Chenb9fa2062018-11-13 21:51:13 +08001576
Xiao Ma09b71022018-12-11 17:56:32 +09001577 test::DNSResponder dns(cleartext_addr);
1578 StartDns(dns, records);
Ken Chenb9fa2062018-11-13 21:51:13 +08001579
waynema0e73c2e2019-07-31 15:04:08 +08001580 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
1581 kDefaultIncorrectPrivateDnsHostName));
Ken Chenb9fa2062018-11-13 21:51:13 +08001582
1583 addrinfo* ai_result = nullptr;
1584 EXPECT_NE(0, getaddrinfo(host_name, nullptr, nullptr, &ai_result));
1585 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
1586}
Luke Huang94b10b92018-11-21 20:13:38 +08001587
1588namespace {
1589
Luke Huang70931aa2019-01-31 11:57:41 +08001590int getAsyncResponse(int fd, int* rcode, uint8_t* buf, int bufLen) {
Luke Huang94b10b92018-11-21 20:13:38 +08001591 struct pollfd wait_fd[1];
1592 wait_fd[0].fd = fd;
1593 wait_fd[0].events = POLLIN;
1594 short revents;
1595 int ret;
1596
1597 ret = poll(wait_fd, 1, -1);
1598 revents = wait_fd[0].revents;
1599 if (revents & POLLIN) {
1600 int n = resNetworkResult(fd, rcode, buf, bufLen);
Luke Huangba7bef92018-12-26 16:53:03 +08001601 // Verify that resNetworkResult() closed the fd
1602 char dummy;
1603 EXPECT_EQ(-1, read(fd, &dummy, sizeof dummy));
1604 EXPECT_EQ(EBADF, errno);
Luke Huang94b10b92018-11-21 20:13:38 +08001605 return n;
1606 }
1607 return -1;
1608}
1609
Luke Huang70931aa2019-01-31 11:57:41 +08001610std::string toString(uint8_t* buf, int bufLen, int ipType) {
Luke Huang94b10b92018-11-21 20:13:38 +08001611 ns_msg handle;
1612 int ancount, n = 0;
1613 ns_rr rr;
1614
Luke Huangf8215372019-11-22 11:53:41 +08001615 if (ns_initparse((const uint8_t*)buf, bufLen, &handle) >= 0) {
Luke Huang94b10b92018-11-21 20:13:38 +08001616 ancount = ns_msg_count(handle, ns_s_an);
1617 if (ns_parserr(&handle, ns_s_an, n, &rr) == 0) {
Luke Huang70931aa2019-01-31 11:57:41 +08001618 const uint8_t* rdata = ns_rr_rdata(rr);
Luke Huang94b10b92018-11-21 20:13:38 +08001619 char buffer[INET6_ADDRSTRLEN];
Luke Huangf8215372019-11-22 11:53:41 +08001620 if (inet_ntop(ipType, (const char*)rdata, buffer, sizeof(buffer))) {
Luke Huang94b10b92018-11-21 20:13:38 +08001621 return buffer;
1622 }
1623 }
1624 }
1625 return "";
1626}
1627
1628int dns_open_proxy() {
1629 int s = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
1630 if (s == -1) {
1631 return -1;
1632 }
1633 const int one = 1;
1634 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1635
1636 static const struct sockaddr_un proxy_addr = {
1637 .sun_family = AF_UNIX,
1638 .sun_path = "/dev/socket/dnsproxyd",
1639 };
1640
Luke Huangf8215372019-11-22 11:53:41 +08001641 if (TEMP_FAILURE_RETRY(connect(s, (const struct sockaddr*)&proxy_addr, sizeof(proxy_addr))) !=
Luke Huang94b10b92018-11-21 20:13:38 +08001642 0) {
1643 close(s);
1644 return -1;
1645 }
1646
1647 return s;
1648}
1649
Luke Huangba7bef92018-12-26 16:53:03 +08001650void expectAnswersValid(int fd, int ipType, const std::string& expectedAnswer) {
1651 int rcode = -1;
1652 uint8_t buf[MAXPACKET] = {};
1653
1654 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
1655 EXPECT_GT(res, 0);
1656 EXPECT_EQ(expectedAnswer, toString(buf, res, ipType));
1657}
1658
1659void expectAnswersNotValid(int fd, int expectedErrno) {
1660 int rcode = -1;
1661 uint8_t buf[MAXPACKET] = {};
1662
1663 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
1664 EXPECT_EQ(expectedErrno, res);
1665}
1666
Luke Huang94b10b92018-11-21 20:13:38 +08001667} // namespace
1668
1669TEST_F(ResolverTest, Async_NormalQueryV4V6) {
Xiao Ma09b71022018-12-11 17:56:32 +09001670 constexpr char listen_addr[] = "127.0.0.4";
1671 constexpr char host_name[] = "howdy.example.com.";
1672 const std::vector<DnsRecord> records = {
1673 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1674 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1675 };
1676
1677 test::DNSResponder dns(listen_addr);
1678 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001679 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001680 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001681
Luke Huangba7bef92018-12-26 16:53:03 +08001682 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
1683 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001684 EXPECT_TRUE(fd1 != -1);
1685 EXPECT_TRUE(fd2 != -1);
1686
Luke Huang70931aa2019-01-31 11:57:41 +08001687 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001688 int rcode;
1689 int res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
1690 EXPECT_GT(res, 0);
1691 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
1692
1693 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
1694 EXPECT_GT(res, 0);
1695 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
1696
1697 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
1698
1699 // Re-query verify cache works
Luke Huangba7bef92018-12-26 16:53:03 +08001700 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
1701 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001702
1703 EXPECT_TRUE(fd1 != -1);
1704 EXPECT_TRUE(fd2 != -1);
1705
1706 res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
1707 EXPECT_GT(res, 0);
1708 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
1709
1710 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
1711 EXPECT_GT(res, 0);
1712 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
1713
1714 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
1715}
1716
1717TEST_F(ResolverTest, Async_BadQuery) {
Xiao Ma09b71022018-12-11 17:56:32 +09001718 constexpr char listen_addr[] = "127.0.0.4";
1719 constexpr char host_name[] = "howdy.example.com.";
1720 const std::vector<DnsRecord> records = {
1721 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1722 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1723 };
1724
1725 test::DNSResponder dns(listen_addr);
1726 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001727 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001728 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001729
1730 static struct {
1731 int fd;
1732 const char* dname;
1733 const int queryType;
1734 const int expectRcode;
1735 } kTestData[] = {
Luke Huangba7bef92018-12-26 16:53:03 +08001736 {-1, "", ns_t_aaaa, 0},
1737 {-1, "as65ass46", ns_t_aaaa, 0},
1738 {-1, "454564564564", ns_t_aaaa, 0},
1739 {-1, "h645235", ns_t_a, 0},
1740 {-1, "www.google.com", ns_t_a, 0},
Luke Huang94b10b92018-11-21 20:13:38 +08001741 };
1742
1743 for (auto& td : kTestData) {
1744 SCOPED_TRACE(td.dname);
Luke Huangba7bef92018-12-26 16:53:03 +08001745 td.fd = resNetworkQuery(TEST_NETID, td.dname, ns_c_in, td.queryType, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001746 EXPECT_TRUE(td.fd != -1);
1747 }
1748
1749 // dns_responder return empty resp(packet only contains query part) with no error currently
1750 for (const auto& td : kTestData) {
Luke Huang70931aa2019-01-31 11:57:41 +08001751 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001752 int rcode;
1753 SCOPED_TRACE(td.dname);
1754 int res = getAsyncResponse(td.fd, &rcode, buf, MAXPACKET);
1755 EXPECT_GT(res, 0);
1756 EXPECT_EQ(rcode, td.expectRcode);
1757 }
1758}
1759
1760TEST_F(ResolverTest, Async_EmptyAnswer) {
Xiao Ma09b71022018-12-11 17:56:32 +09001761 constexpr char listen_addr[] = "127.0.0.4";
1762 constexpr char host_name[] = "howdy.example.com.";
1763 const std::vector<DnsRecord> records = {
1764 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1765 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1766 };
1767
1768 test::DNSResponder dns(listen_addr);
1769 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001770 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001771 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001772
Luke Huang9c264bb2018-12-18 16:44:41 +08001773 // TODO: Disable retry to make this test explicit.
1774 auto& cv = dns.getCv();
1775 auto& cvMutex = dns.getCvMutex();
1776 int fd1;
1777 // Wait on the condition variable to ensure that the DNS server has handled our first query.
1778 {
1779 std::unique_lock lk(cvMutex);
Luke Huangba7bef92018-12-26 16:53:03 +08001780 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huang9c264bb2018-12-18 16:44:41 +08001781 EXPECT_TRUE(fd1 != -1);
1782 EXPECT_EQ(std::cv_status::no_timeout, cv.wait_for(lk, std::chrono::seconds(1)));
1783 }
Luke Huang94b10b92018-11-21 20:13:38 +08001784
Luke Huang94b10b92018-11-21 20:13:38 +08001785 dns.setResponseProbability(0.0);
Luke Huang94b10b92018-11-21 20:13:38 +08001786
Luke Huangba7bef92018-12-26 16:53:03 +08001787 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001788 EXPECT_TRUE(fd2 != -1);
1789
Luke Huangba7bef92018-12-26 16:53:03 +08001790 int fd3 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001791 EXPECT_TRUE(fd3 != -1);
1792
Luke Huang9c264bb2018-12-18 16:44:41 +08001793 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001794 int rcode;
1795
Luke Huang9c264bb2018-12-18 16:44:41 +08001796 // expect no response
1797 int res = getAsyncResponse(fd3, &rcode, buf, MAXPACKET);
1798 EXPECT_EQ(-ETIMEDOUT, res);
Luke Huang94b10b92018-11-21 20:13:38 +08001799
Luke Huang9c264bb2018-12-18 16:44:41 +08001800 // expect no response
Luke Huang94b10b92018-11-21 20:13:38 +08001801 memset(buf, 0, MAXPACKET);
Luke Huang9c264bb2018-12-18 16:44:41 +08001802 res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
1803 EXPECT_EQ(-ETIMEDOUT, res);
Luke Huang94b10b92018-11-21 20:13:38 +08001804
Luke Huang94b10b92018-11-21 20:13:38 +08001805 dns.setResponseProbability(1.0);
Luke Huang94b10b92018-11-21 20:13:38 +08001806
Luke Huangba7bef92018-12-26 16:53:03 +08001807 int fd4 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001808 EXPECT_TRUE(fd4 != -1);
1809
1810 memset(buf, 0, MAXPACKET);
1811 res = getAsyncResponse(fd4, &rcode, buf, MAXPACKET);
1812 EXPECT_GT(res, 0);
1813 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
1814
1815 memset(buf, 0, MAXPACKET);
1816 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
1817 EXPECT_GT(res, 0);
1818 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
1819}
1820
1821TEST_F(ResolverTest, Async_MalformedQuery) {
Xiao Ma09b71022018-12-11 17:56:32 +09001822 constexpr char listen_addr[] = "127.0.0.4";
1823 constexpr char host_name[] = "howdy.example.com.";
1824 const std::vector<DnsRecord> records = {
1825 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1826 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1827 };
1828
1829 test::DNSResponder dns(listen_addr);
1830 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001831 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001832 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001833
1834 int fd = dns_open_proxy();
1835 EXPECT_TRUE(fd > 0);
1836
1837 const std::string badMsg = "16-52512#";
Xiao Ma09b71022018-12-11 17:56:32 +09001838 static const struct {
Luke Huang94b10b92018-11-21 20:13:38 +08001839 const std::string cmd;
1840 const int expectErr;
1841 } kTestData[] = {
Luke Huangba7bef92018-12-26 16:53:03 +08001842 // Too few arguments
Luke Huang94b10b92018-11-21 20:13:38 +08001843 {"resnsend " + badMsg + '\0', -EINVAL},
1844 // Bad netId
Luke Huangba7bef92018-12-26 16:53:03 +08001845 {"resnsend badnetId 0 " + badMsg + '\0', -EINVAL},
Luke Huang94b10b92018-11-21 20:13:38 +08001846 // Bad raw data
Luke Huangba7bef92018-12-26 16:53:03 +08001847 {"resnsend " + std::to_string(TEST_NETID) + " 0 " + badMsg + '\0', -EILSEQ},
Luke Huang94b10b92018-11-21 20:13:38 +08001848 };
1849
1850 for (unsigned int i = 0; i < std::size(kTestData); i++) {
1851 auto& td = kTestData[i];
1852 SCOPED_TRACE(td.cmd);
1853 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, td.cmd.c_str(), td.cmd.size()));
1854 EXPECT_EQ(rc, static_cast<ssize_t>(td.cmd.size()));
1855
1856 int32_t tmp;
1857 rc = TEMP_FAILURE_RETRY(read(fd, &tmp, sizeof(tmp)));
1858 EXPECT_TRUE(rc > 0);
1859 EXPECT_EQ(static_cast<int>(ntohl(tmp)), td.expectErr);
1860 }
1861 // Normal query with answer buffer
1862 // This is raw data of query "howdy.example.com" type 1 class 1
1863 std::string query = "81sBAAABAAAAAAAABWhvd2R5B2V4YW1wbGUDY29tAAABAAE=";
Luke Huangba7bef92018-12-26 16:53:03 +08001864 std::string cmd = "resnsend " + std::to_string(TEST_NETID) + " 0 " + query + '\0';
Luke Huang94b10b92018-11-21 20:13:38 +08001865 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size()));
1866 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size()));
1867
Luke Huang70931aa2019-01-31 11:57:41 +08001868 uint8_t smallBuf[1] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001869 int rcode;
1870 rc = getAsyncResponse(fd, &rcode, smallBuf, 1);
Luke Huangba7bef92018-12-26 16:53:03 +08001871 EXPECT_EQ(-EMSGSIZE, rc);
Luke Huang94b10b92018-11-21 20:13:38 +08001872
1873 // Do the normal test with large buffer again
1874 fd = dns_open_proxy();
1875 EXPECT_TRUE(fd > 0);
1876 rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size()));
1877 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size()));
Luke Huang70931aa2019-01-31 11:57:41 +08001878 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001879 rc = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
1880 EXPECT_EQ("1.2.3.4", toString(buf, rc, AF_INET));
Mike Yu4f3747b2018-12-02 17:54:29 +09001881}
1882
Luke Huangba7bef92018-12-26 16:53:03 +08001883TEST_F(ResolverTest, Async_CacheFlags) {
Xiao Ma09b71022018-12-11 17:56:32 +09001884 constexpr char listen_addr[] = "127.0.0.4";
1885 constexpr char host_name[] = "howdy.example.com.";
Luke Huang40f5f492019-05-09 19:37:35 +08001886 constexpr char another_host_name[] = "howdy.example2.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09001887 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"},
Luke Huang40f5f492019-05-09 19:37:35 +08001890 {another_host_name, ns_type::ns_t_a, "1.2.3.5"},
1891 {another_host_name, ns_type::ns_t_aaaa, "::1.2.3.5"},
Xiao Ma09b71022018-12-11 17:56:32 +09001892 };
1893
1894 test::DNSResponder dns(listen_addr);
1895 StartDns(dns, records);
Luke Huangba7bef92018-12-26 16:53:03 +08001896 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001897 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huangba7bef92018-12-26 16:53:03 +08001898
1899 // ANDROID_RESOLV_NO_CACHE_STORE
1900 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1901 ANDROID_RESOLV_NO_CACHE_STORE);
1902 EXPECT_TRUE(fd1 != -1);
1903 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1904 ANDROID_RESOLV_NO_CACHE_STORE);
1905 EXPECT_TRUE(fd2 != -1);
1906 int fd3 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1907 ANDROID_RESOLV_NO_CACHE_STORE);
1908 EXPECT_TRUE(fd3 != -1);
1909
1910 expectAnswersValid(fd3, AF_INET, "1.2.3.4");
1911 expectAnswersValid(fd2, AF_INET, "1.2.3.4");
1912 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
1913
1914 // No cache exists, expect 3 queries
1915 EXPECT_EQ(3U, GetNumQueries(dns, host_name));
1916
1917 // Re-query and cache
1918 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
1919
1920 EXPECT_TRUE(fd1 != -1);
1921
1922 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
1923
1924 // Now we have cache, expect 4 queries
1925 EXPECT_EQ(4U, GetNumQueries(dns, host_name));
1926
1927 // ANDROID_RESOLV_NO_CACHE_LOOKUP
1928 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1929 ANDROID_RESOLV_NO_CACHE_LOOKUP);
1930 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1931 ANDROID_RESOLV_NO_CACHE_LOOKUP);
1932
1933 EXPECT_TRUE(fd1 != -1);
1934 EXPECT_TRUE(fd2 != -1);
1935
1936 expectAnswersValid(fd2, AF_INET, "1.2.3.4");
1937 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
1938
1939 // Skip cache, expect 6 queries
1940 EXPECT_EQ(6U, GetNumQueries(dns, host_name));
1941
1942 // Re-query verify cache works
1943 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1944 ANDROID_RESOLV_NO_CACHE_STORE);
1945 EXPECT_TRUE(fd1 != -1);
1946 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
1947
1948 // Cache hits, expect still 6 queries
1949 EXPECT_EQ(6U, GetNumQueries(dns, host_name));
Luke Huanga1d74182019-03-19 17:30:36 +08001950
1951 // Start to verify if ANDROID_RESOLV_NO_CACHE_LOOKUP does write response into cache
1952 dns.clearQueries();
1953
1954 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
1955 ANDROID_RESOLV_NO_CACHE_LOOKUP);
1956 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
1957 ANDROID_RESOLV_NO_CACHE_LOOKUP);
1958
1959 EXPECT_TRUE(fd1 != -1);
1960 EXPECT_TRUE(fd2 != -1);
1961
1962 expectAnswersValid(fd2, AF_INET6, "::1.2.3.4");
1963 expectAnswersValid(fd1, AF_INET6, "::1.2.3.4");
1964
1965 // Skip cache, expect 2 queries
1966 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
1967
1968 // Re-query without flags
1969 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
1970 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
1971
1972 EXPECT_TRUE(fd1 != -1);
1973 EXPECT_TRUE(fd2 != -1);
1974
1975 expectAnswersValid(fd2, AF_INET6, "::1.2.3.4");
1976 expectAnswersValid(fd1, AF_INET6, "::1.2.3.4");
1977
1978 // Cache hits, expect still 2 queries
1979 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
Luke Huang40f5f492019-05-09 19:37:35 +08001980
1981 // Test both ANDROID_RESOLV_NO_CACHE_STORE and ANDROID_RESOLV_NO_CACHE_LOOKUP are set
1982 dns.clearQueries();
1983
1984 // Make sure that the cache of "howdy.example2.com" exists.
1985 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_aaaa, 0);
1986 EXPECT_TRUE(fd1 != -1);
1987 expectAnswersValid(fd1, AF_INET6, "::1.2.3.5");
1988 EXPECT_EQ(1U, GetNumQueries(dns, another_host_name));
1989
1990 // Re-query with testFlags
1991 const int testFlag = ANDROID_RESOLV_NO_CACHE_STORE | ANDROID_RESOLV_NO_CACHE_LOOKUP;
1992 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_aaaa, testFlag);
1993 EXPECT_TRUE(fd1 != -1);
1994 expectAnswersValid(fd1, AF_INET6, "::1.2.3.5");
1995 // Expect cache lookup is skipped.
1996 EXPECT_EQ(2U, GetNumQueries(dns, another_host_name));
1997
1998 // Do another query with testFlags
1999 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_a, testFlag);
2000 EXPECT_TRUE(fd1 != -1);
2001 expectAnswersValid(fd1, AF_INET, "1.2.3.5");
2002 // Expect cache lookup is skipped.
2003 EXPECT_EQ(3U, GetNumQueries(dns, another_host_name));
2004
2005 // Re-query with no flags
2006 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_a, 0);
2007 EXPECT_TRUE(fd1 != -1);
2008 expectAnswersValid(fd1, AF_INET, "1.2.3.5");
2009 // Expect no cache hit because cache storing is also skipped in previous query.
2010 EXPECT_EQ(4U, GetNumQueries(dns, another_host_name));
Luke Huangba7bef92018-12-26 16:53:03 +08002011}
2012
2013TEST_F(ResolverTest, Async_NoRetryFlag) {
Luke Huang70931aa2019-01-31 11:57:41 +08002014 constexpr char listen_addr0[] = "127.0.0.4";
2015 constexpr char listen_addr1[] = "127.0.0.6";
Xiao Ma09b71022018-12-11 17:56:32 +09002016 constexpr char host_name[] = "howdy.example.com.";
2017 const std::vector<DnsRecord> records = {
2018 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2019 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
2020 };
2021
Luke Huang70931aa2019-01-31 11:57:41 +08002022 test::DNSResponder dns0(listen_addr0);
2023 test::DNSResponder dns1(listen_addr1);
2024 StartDns(dns0, records);
2025 StartDns(dns1, records);
2026 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr0, listen_addr1}));
Luke Huangba7bef92018-12-26 16:53:03 +08002027
Luke Huang70931aa2019-01-31 11:57:41 +08002028 dns0.clearQueries();
2029 dns1.clearQueries();
2030
2031 dns0.setResponseProbability(0.0);
2032 dns1.setResponseProbability(0.0);
Luke Huangba7bef92018-12-26 16:53:03 +08002033
2034 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2035 ANDROID_RESOLV_NO_RETRY);
2036 EXPECT_TRUE(fd1 != -1);
2037
2038 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
2039 ANDROID_RESOLV_NO_RETRY);
2040 EXPECT_TRUE(fd2 != -1);
2041
2042 // expect no response
2043 expectAnswersNotValid(fd1, -ETIMEDOUT);
2044 expectAnswersNotValid(fd2, -ETIMEDOUT);
2045
Luke Huang70931aa2019-01-31 11:57:41 +08002046 // No retry case, expect total 2 queries. The server is selected randomly.
2047 EXPECT_EQ(2U, GetNumQueries(dns0, host_name) + GetNumQueries(dns1, host_name));
Luke Huangba7bef92018-12-26 16:53:03 +08002048
Luke Huang70931aa2019-01-31 11:57:41 +08002049 dns0.clearQueries();
2050 dns1.clearQueries();
Luke Huangba7bef92018-12-26 16:53:03 +08002051
2052 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
2053 EXPECT_TRUE(fd1 != -1);
2054
2055 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
2056 EXPECT_TRUE(fd2 != -1);
2057
2058 // expect no response
2059 expectAnswersNotValid(fd1, -ETIMEDOUT);
2060 expectAnswersNotValid(fd2, -ETIMEDOUT);
2061
2062 // Retry case, expect 4 queries
Luke Huang70931aa2019-01-31 11:57:41 +08002063 EXPECT_EQ(4U, GetNumQueries(dns0, host_name));
2064 EXPECT_EQ(4U, GetNumQueries(dns1, host_name));
2065}
2066
2067TEST_F(ResolverTest, Async_VerifyQueryID) {
2068 constexpr char listen_addr[] = "127.0.0.4";
2069 constexpr char host_name[] = "howdy.example.com.";
2070 const std::vector<DnsRecord> records = {
2071 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2072 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
2073 };
2074
2075 test::DNSResponder dns(listen_addr);
2076 StartDns(dns, records);
2077 std::vector<std::string> servers = {listen_addr};
2078 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
2079
2080 const uint8_t queryBuf1[] = {
2081 /* Header */
2082 0x55, 0x66, /* Transaction ID */
2083 0x01, 0x00, /* Flags */
2084 0x00, 0x01, /* Questions */
2085 0x00, 0x00, /* Answer RRs */
2086 0x00, 0x00, /* Authority RRs */
2087 0x00, 0x00, /* Additional RRs */
2088 /* Queries */
2089 0x05, 0x68, 0x6f, 0x77, 0x64, 0x79, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
2090 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
2091 0x00, 0x01, /* Type */
2092 0x00, 0x01 /* Class */
2093 };
2094
2095 int fd = resNetworkSend(TEST_NETID, queryBuf1, sizeof(queryBuf1), 0);
2096 EXPECT_TRUE(fd != -1);
2097
2098 uint8_t buf[MAXPACKET] = {};
2099 int rcode;
2100
2101 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
2102 EXPECT_GT(res, 0);
2103 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
2104
2105 auto hp = reinterpret_cast<HEADER*>(buf);
2106 EXPECT_EQ(21862U, htons(hp->id));
2107
2108 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
2109
2110 const uint8_t queryBuf2[] = {
2111 /* Header */
2112 0x00, 0x53, /* Transaction ID */
2113 0x01, 0x00, /* Flags */
2114 0x00, 0x01, /* Questions */
2115 0x00, 0x00, /* Answer RRs */
2116 0x00, 0x00, /* Authority RRs */
2117 0x00, 0x00, /* Additional RRs */
2118 /* Queries */
2119 0x05, 0x68, 0x6f, 0x77, 0x64, 0x79, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
2120 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
2121 0x00, 0x01, /* Type */
2122 0x00, 0x01 /* Class */
2123 };
2124
2125 // Re-query verify cache works and query id is correct
2126 fd = resNetworkSend(TEST_NETID, queryBuf2, sizeof(queryBuf2), 0);
2127
2128 EXPECT_TRUE(fd != -1);
2129
2130 res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
2131 EXPECT_GT(res, 0);
2132 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
2133
2134 EXPECT_EQ(0x0053U, htons(hp->id));
2135
2136 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
Luke Huangba7bef92018-12-26 16:53:03 +08002137}
2138
Mike Yu4f3747b2018-12-02 17:54:29 +09002139// This test checks that the resolver should not generate the request containing OPT RR when using
Ken Chen0a015532019-01-02 14:59:38 +08002140// cleartext DNS. If we query the DNS server not supporting EDNS0 and it reponds with
2141// FORMERR_ON_EDNS, we will fallback to no EDNS0 and try again. If the server does no response, we
2142// won't retry so that we get no answer.
Mike Yu4f3747b2018-12-02 17:54:29 +09002143TEST_F(ResolverTest, BrokenEdns) {
2144 typedef test::DNSResponder::Edns Edns;
2145 enum ExpectResult { EXPECT_FAILURE, EXPECT_SUCCESS };
2146
2147 const char OFF[] = "off";
2148 const char OPPORTUNISTIC_UDP[] = "opportunistic_udp";
2149 const char OPPORTUNISTIC_TLS[] = "opportunistic_tls";
2150 const char STRICT[] = "strict";
2151 const char GETHOSTBYNAME[] = "gethostbyname";
2152 const char GETADDRINFO[] = "getaddrinfo";
Mike Yu4f3747b2018-12-02 17:54:29 +09002153 const char ADDR4[] = "192.0.2.1";
2154 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2155 const char CLEARTEXT_PORT[] = "53";
2156 const char TLS_PORT[] = "853";
Luke Huangf8215372019-11-22 11:53:41 +08002157 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
Mike Yu4f3747b2018-12-02 17:54:29 +09002158
Mike Yufc125e42019-05-15 20:41:28 +08002159 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, ns_rcode::ns_r_servfail);
Mike Yu4f3747b2018-12-02 17:54:29 +09002160 ASSERT_TRUE(dns.startServer());
2161
2162 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2163
Luke Huangf8215372019-11-22 11:53:41 +08002164 // clang-format off
Mike Yu4f3747b2018-12-02 17:54:29 +09002165 static const struct TestConfig {
2166 std::string mode;
2167 std::string method;
2168 Edns edns;
2169 ExpectResult expectResult;
2170
2171 std::string asHostName() const {
2172 const char* ednsString;
2173 switch (edns) {
2174 case Edns::ON:
2175 ednsString = "ednsOn";
2176 break;
Ken Chen0a015532019-01-02 14:59:38 +08002177 case Edns::FORMERR_ON_EDNS:
Mike Yu4f3747b2018-12-02 17:54:29 +09002178 ednsString = "ednsFormerr";
2179 break;
2180 case Edns::DROP:
2181 ednsString = "ednsDrop";
2182 break;
2183 default:
2184 ednsString = "";
2185 break;
2186 }
2187 return StringPrintf("%s.%s.%s.", mode.c_str(), method.c_str(), ednsString);
2188 }
2189 } testConfigs[] = {
2190 // In OPPORTUNISTIC_TLS, we get no answer if the DNS server supports TLS but not EDNS0.
2191 // Could such server exist? if so, we might need to fallback to query cleartext DNS.
2192 // Another thing is that {OPPORTUNISTIC_TLS, Edns::DROP} and {STRICT, Edns::DROP} are
2193 // commented out since TLS timeout is not configurable.
2194 // TODO: Uncomment them after TLS timeout is configurable.
2195 {OFF, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2196 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2197 {OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2198 {STRICT, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
Ken Chen0a015532019-01-02 14:59:38 +08002199 {OFF, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2200 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2201 {OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
2202 {STRICT, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
Mike Yu4f3747b2018-12-02 17:54:29 +09002203 {OFF, GETHOSTBYNAME, Edns::DROP, EXPECT_SUCCESS},
2204 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::DROP, EXPECT_SUCCESS},
2205 //{OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::DROP, EXPECT_FAILURE},
2206 //{STRICT, GETHOSTBYNAME, Edns::DROP, EXPECT_FAILURE},
2207 {OFF, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2208 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2209 {OPPORTUNISTIC_TLS, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2210 {STRICT, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
Ken Chen0a015532019-01-02 14:59:38 +08002211 {OFF, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2212 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2213 {OPPORTUNISTIC_TLS, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
2214 {STRICT, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
Mike Yu4f3747b2018-12-02 17:54:29 +09002215 {OFF, GETADDRINFO, Edns::DROP, EXPECT_SUCCESS},
2216 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::DROP, EXPECT_SUCCESS},
2217 //{OPPORTUNISTIC_TLS, GETADDRINFO, Edns::DROP, EXPECT_FAILURE},
2218 //{STRICT, GETADDRINFO, Edns::DROP, EXPECT_FAILURE},
2219 };
Luke Huangf8215372019-11-22 11:53:41 +08002220 // clang-format on
Mike Yu4f3747b2018-12-02 17:54:29 +09002221
2222 for (const auto& config : testConfigs) {
2223 const std::string testHostName = config.asHostName();
2224 SCOPED_TRACE(testHostName);
2225
2226 const char* host_name = testHostName.c_str();
2227 dns.addMapping(host_name, ns_type::ns_t_a, ADDR4);
2228 dns.setEdns(config.edns);
2229
2230 if (config.mode == OFF) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002231 if (tls.running()) {
2232 ASSERT_TRUE(tls.stopServer());
2233 }
Xiao Ma09b71022018-12-11 17:56:32 +09002234 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Mike Yu4f3747b2018-12-02 17:54:29 +09002235 } else if (config.mode == OPPORTUNISTIC_UDP) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002236 if (tls.running()) {
2237 ASSERT_TRUE(tls.stopServer());
2238 }
Xiao Ma09b71022018-12-11 17:56:32 +09002239 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08002240 kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002241 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), false));
Mike Yu4f3747b2018-12-02 17:54:29 +09002242 } else if (config.mode == OPPORTUNISTIC_TLS) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002243 if (!tls.running()) {
2244 ASSERT_TRUE(tls.startServer());
2245 }
Xiao Ma09b71022018-12-11 17:56:32 +09002246 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08002247 kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002248 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yu4f3747b2018-12-02 17:54:29 +09002249 } else if (config.mode == STRICT) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002250 if (!tls.running()) {
2251 ASSERT_TRUE(tls.startServer());
2252 }
Xiao Ma09b71022018-12-11 17:56:32 +09002253 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08002254 kDefaultParams, kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08002255 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yu4f3747b2018-12-02 17:54:29 +09002256 }
2257
2258 if (config.method == GETHOSTBYNAME) {
2259 const hostent* h_result = gethostbyname(host_name);
2260 if (config.expectResult == EXPECT_SUCCESS) {
2261 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2262 ASSERT_TRUE(h_result != nullptr);
2263 ASSERT_EQ(4, h_result->h_length);
2264 ASSERT_FALSE(h_result->h_addr_list[0] == nullptr);
2265 EXPECT_EQ(ADDR4, ToString(h_result));
2266 EXPECT_TRUE(h_result->h_addr_list[1] == nullptr);
2267 } else {
2268 EXPECT_EQ(0U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
2269 ASSERT_TRUE(h_result == nullptr);
2270 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2271 }
2272 } else if (config.method == GETADDRINFO) {
2273 ScopedAddrinfo ai_result;
2274 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2275 ai_result = safe_getaddrinfo(host_name, nullptr, &hints);
2276 if (config.expectResult == EXPECT_SUCCESS) {
2277 EXPECT_TRUE(ai_result != nullptr);
2278 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
2279 const std::string result_str = ToString(ai_result);
2280 EXPECT_EQ(ADDR4, result_str);
2281 } else {
2282 EXPECT_TRUE(ai_result == nullptr);
2283 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
2284 }
2285 } else {
2286 FAIL() << "Unsupported query method: " << config.method;
2287 }
2288
Mike Yudd4ac2d2019-05-31 16:52:11 +08002289 tls.clearQueries();
Mike Yu4f3747b2018-12-02 17:54:29 +09002290 dns.clearQueries();
2291 }
Mike Yu4f3747b2018-12-02 17:54:29 +09002292}
nuccachena26cc2a2018-07-17 18:07:23 +08002293
Ken Chen0a015532019-01-02 14:59:38 +08002294// DNS-over-TLS validation success, but server does not respond to TLS query after a while.
2295// Resolver should have a reasonable number of retries instead of spinning forever. We don't have
2296// an efficient way to know if resolver is stuck in an infinite loop. However, test case will be
2297// failed due to timeout.
2298TEST_F(ResolverTest, UnstableTls) {
2299 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2300 const char CLEARTEXT_PORT[] = "53";
2301 const char TLS_PORT[] = "853";
2302 const char* host_name1 = "nonexistent1.example.com.";
2303 const char* host_name2 = "nonexistent2.example.com.";
2304 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
2305
Mike Yufc125e42019-05-15 20:41:28 +08002306 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, ns_rcode::ns_r_servfail);
Ken Chen0a015532019-01-02 14:59:38 +08002307 ASSERT_TRUE(dns.startServer());
2308 dns.setEdns(test::DNSResponder::Edns::FORMERR_ON_EDNS);
2309 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2310 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08002311 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002312 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
2313
Ken Chen0a015532019-01-02 14:59:38 +08002314 // Shutdown TLS server to get an error. It's similar to no response case but without waiting.
2315 tls.stopServer();
2316
2317 const hostent* h_result = gethostbyname(host_name1);
2318 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
2319 ASSERT_TRUE(h_result == nullptr);
2320 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2321
2322 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2323 ScopedAddrinfo ai_result = safe_getaddrinfo(host_name2, nullptr, &hints);
2324 EXPECT_TRUE(ai_result == nullptr);
2325 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
2326}
2327
2328// DNS-over-TLS validation success, but server does not respond to TLS query after a while.
2329// Moreover, server responds RCODE=FORMERR even on non-EDNS query.
2330TEST_F(ResolverTest, BogusDnsServer) {
2331 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2332 const char CLEARTEXT_PORT[] = "53";
2333 const char TLS_PORT[] = "853";
2334 const char* host_name1 = "nonexistent1.example.com.";
2335 const char* host_name2 = "nonexistent2.example.com.";
2336 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
2337
Mike Yufc125e42019-05-15 20:41:28 +08002338 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, ns_rcode::ns_r_servfail);
Ken Chen0a015532019-01-02 14:59:38 +08002339 ASSERT_TRUE(dns.startServer());
2340 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2341 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08002342 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002343 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
2344
Ken Chen0a015532019-01-02 14:59:38 +08002345 // Shutdown TLS server to get an error. It's similar to no response case but without waiting.
2346 tls.stopServer();
2347 dns.setEdns(test::DNSResponder::Edns::FORMERR_UNCOND);
2348
2349 const hostent* h_result = gethostbyname(host_name1);
2350 EXPECT_EQ(0U, GetNumQueries(dns, host_name1));
2351 ASSERT_TRUE(h_result == nullptr);
2352 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2353
2354 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2355 ScopedAddrinfo ai_result = safe_getaddrinfo(host_name2, nullptr, &hints);
2356 EXPECT_TRUE(ai_result == nullptr);
2357 EXPECT_EQ(0U, GetNumQueries(dns, host_name2));
2358}
2359
nuccachena26cc2a2018-07-17 18:07:23 +08002360TEST_F(ResolverTest, GetAddrInfo_Dns64Synthesize) {
2361 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002362 constexpr char dns64_name[] = "ipv4only.arpa.";
2363 constexpr char host_name[] = "v4only.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002364 const std::vector<DnsRecord> records = {
2365 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2366 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2367 };
nuccachena26cc2a2018-07-17 18:07:23 +08002368
Xiao Ma09b71022018-12-11 17:56:32 +09002369 test::DNSResponder dns(listen_addr);
Xiao Ma09b71022018-12-11 17:56:32 +09002370 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002371
2372 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002373 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002374
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002375 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002376 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002377 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002378
2379 // hints are necessary in order to let netd know which type of addresses the caller is
2380 // interested in.
Xiao Ma09b71022018-12-11 17:56:32 +09002381 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachena26cc2a2018-07-17 18:07:23 +08002382 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, &hints);
2383 EXPECT_TRUE(result != nullptr);
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002384 // TODO: BUG: there should only be two queries, one AAAA (which returns no records) and one A
2385 // (which returns 1.2.3.4). But there is an extra AAAA.
2386 EXPECT_EQ(3U, GetNumQueries(dns, host_name));
nuccachena26cc2a2018-07-17 18:07:23 +08002387
2388 std::string result_str = ToString(result);
2389 EXPECT_EQ(result_str, "64:ff9b::102:304");
2390
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002391 // Stopping NAT64 prefix discovery disables synthesis.
Luke Huang5bd827c2019-03-14 16:10:04 +08002392 EXPECT_TRUE(mDnsClient.resolvService()->stopPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002393 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_NOT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002394
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002395 dns.clearQueries();
nuccachena26cc2a2018-07-17 18:07:23 +08002396
2397 result = safe_getaddrinfo("v4only", nullptr, &hints);
2398 EXPECT_TRUE(result != nullptr);
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002399 // TODO: BUG: there should only be one query, an AAAA (which returns no records), because the
2400 // A is already cached. But there is an extra AAAA.
2401 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
nuccachena26cc2a2018-07-17 18:07:23 +08002402
2403 result_str = ToString(result);
2404 EXPECT_EQ(result_str, "1.2.3.4");
2405}
2406
nuccachena26cc2a2018-07-17 18:07:23 +08002407TEST_F(ResolverTest, GetAddrInfo_Dns64QuerySpecified) {
2408 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002409 constexpr char dns64_name[] = "ipv4only.arpa.";
2410 constexpr char host_name[] = "v4only.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002411 const std::vector<DnsRecord> records = {
2412 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2413 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2414 };
nuccachena26cc2a2018-07-17 18:07:23 +08002415
Xiao Ma09b71022018-12-11 17:56:32 +09002416 test::DNSResponder dns(listen_addr);
2417 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002418 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002419 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002420
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002421 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002422 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002423 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002424
2425 // Ensure to synthesize AAAA if AF_INET6 is specified, and not to synthesize AAAA
2426 // in AF_INET case.
2427 addrinfo hints;
2428 memset(&hints, 0, sizeof(hints));
2429 hints.ai_family = AF_INET6;
2430 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, &hints);
2431 EXPECT_TRUE(result != nullptr);
2432 std::string result_str = ToString(result);
2433 EXPECT_EQ(result_str, "64:ff9b::102:304");
2434
2435 hints.ai_family = AF_INET;
2436 result = safe_getaddrinfo("v4only", nullptr, &hints);
2437 EXPECT_TRUE(result != nullptr);
2438 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2439 result_str = ToString(result);
2440 EXPECT_EQ(result_str, "1.2.3.4");
2441}
nuccachena26cc2a2018-07-17 18:07:23 +08002442
2443TEST_F(ResolverTest, GetAddrInfo_Dns64QueryUnspecifiedV6) {
2444 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002445 constexpr char dns64_name[] = "ipv4only.arpa.";
2446 constexpr char host_name[] = "v4v6.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002447 const std::vector<DnsRecord> records = {
2448 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2449 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2450 {host_name, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
2451 };
nuccachena26cc2a2018-07-17 18:07:23 +08002452
Xiao Ma09b71022018-12-11 17:56:32 +09002453 test::DNSResponder dns(listen_addr);
2454 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002455 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002456 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002457
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002458 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002459 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002460 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002461
Xiao Ma09b71022018-12-11 17:56:32 +09002462 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachena26cc2a2018-07-17 18:07:23 +08002463 ScopedAddrinfo result = safe_getaddrinfo("v4v6", nullptr, &hints);
2464 EXPECT_TRUE(result != nullptr);
2465 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2466
2467 // In AF_UNSPEC case, do not synthesize AAAA if there's at least one AAAA answer.
Xiao Ma09b71022018-12-11 17:56:32 +09002468 const std::vector<std::string> result_strs = ToStrings(result);
nuccachena26cc2a2018-07-17 18:07:23 +08002469 for (const auto& str : result_strs) {
2470 EXPECT_TRUE(str == "1.2.3.4" || str == "2001:db8::102:304")
2471 << ", result_str='" << str << "'";
2472 }
2473}
2474
2475TEST_F(ResolverTest, GetAddrInfo_Dns64QueryUnspecifiedNoV6) {
2476 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002477 constexpr char dns64_name[] = "ipv4only.arpa.";
2478 constexpr char host_name[] = "v4v6.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002479 const std::vector<DnsRecord> records = {
2480 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2481 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2482 };
nuccachena26cc2a2018-07-17 18:07:23 +08002483
Xiao Ma09b71022018-12-11 17:56:32 +09002484 test::DNSResponder dns(listen_addr);
2485 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002486 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002487 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002488
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002489 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002490 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002491 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002492
Xiao Ma09b71022018-12-11 17:56:32 +09002493 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachena26cc2a2018-07-17 18:07:23 +08002494 ScopedAddrinfo result = safe_getaddrinfo("v4v6", nullptr, &hints);
2495 EXPECT_TRUE(result != nullptr);
2496 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2497
2498 // In AF_UNSPEC case, synthesize AAAA if there's no AAAA answer.
2499 std::string result_str = ToString(result);
2500 EXPECT_EQ(result_str, "64:ff9b::102:304");
2501}
2502
2503TEST_F(ResolverTest, GetAddrInfo_Dns64QuerySpecialUseIPv4Addresses) {
2504 constexpr char THIS_NETWORK[] = "this_network";
2505 constexpr char LOOPBACK[] = "loopback";
2506 constexpr char LINK_LOCAL[] = "link_local";
2507 constexpr char MULTICAST[] = "multicast";
2508 constexpr char LIMITED_BROADCAST[] = "limited_broadcast";
2509
2510 constexpr char ADDR_THIS_NETWORK[] = "0.0.0.1";
2511 constexpr char ADDR_LOOPBACK[] = "127.0.0.1";
2512 constexpr char ADDR_LINK_LOCAL[] = "169.254.0.1";
2513 constexpr char ADDR_MULTICAST[] = "224.0.0.1";
2514 constexpr char ADDR_LIMITED_BROADCAST[] = "255.255.255.255";
2515
2516 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002517 constexpr char dns64_name[] = "ipv4only.arpa.";
2518
Xiao Ma09b71022018-12-11 17:56:32 +09002519 test::DNSResponder dns(listen_addr);
2520 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachena26cc2a2018-07-17 18:07:23 +08002521 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002522 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002523
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002524 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002525 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002526 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002527
Luke Huangf8215372019-11-22 11:53:41 +08002528 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08002529 static const struct TestConfig {
2530 std::string name;
2531 std::string addr;
2532
2533 std::string asHostName() const { return StringPrintf("%s.example.com.", name.c_str()); }
2534 } testConfigs[]{
2535 {THIS_NETWORK, ADDR_THIS_NETWORK},
2536 {LOOPBACK, ADDR_LOOPBACK},
2537 {LINK_LOCAL, ADDR_LINK_LOCAL},
2538 {MULTICAST, ADDR_MULTICAST},
2539 {LIMITED_BROADCAST, ADDR_LIMITED_BROADCAST}
2540 };
Luke Huangf8215372019-11-22 11:53:41 +08002541 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08002542
2543 for (const auto& config : testConfigs) {
2544 const std::string testHostName = config.asHostName();
2545 SCOPED_TRACE(testHostName);
2546
2547 const char* host_name = testHostName.c_str();
2548 dns.addMapping(host_name, ns_type::ns_t_a, config.addr.c_str());
2549
2550 addrinfo hints;
2551 memset(&hints, 0, sizeof(hints));
2552 hints.ai_family = AF_INET6;
2553 ScopedAddrinfo result = safe_getaddrinfo(config.name.c_str(), nullptr, &hints);
2554 // In AF_INET6 case, don't return IPv4 answers
2555 EXPECT_TRUE(result == nullptr);
2556 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2557 dns.clearQueries();
2558
2559 memset(&hints, 0, sizeof(hints));
2560 hints.ai_family = AF_UNSPEC;
2561 result = safe_getaddrinfo(config.name.c_str(), nullptr, &hints);
2562 EXPECT_TRUE(result != nullptr);
2563 // Expect IPv6 query only. IPv4 answer has been cached in previous query.
2564 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2565 // In AF_UNSPEC case, don't synthesize special use IPv4 address.
2566 std::string result_str = ToString(result);
2567 EXPECT_EQ(result_str, config.addr.c_str());
2568 dns.clearQueries();
2569 }
2570}
2571
2572TEST_F(ResolverTest, GetAddrInfo_Dns64QueryWithNullArgumentHints) {
2573 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002574 constexpr char dns64_name[] = "ipv4only.arpa.";
2575 constexpr char host_name[] = "v4only.example.com.";
2576 constexpr char host_name2[] = "v4v6.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002577 const std::vector<DnsRecord> records = {
2578 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2579 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2580 {host_name2, ns_type::ns_t_a, "1.2.3.4"},
2581 {host_name2, ns_type::ns_t_aaaa, "2001:db8::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);
2585 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002586 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002587 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002588
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002589 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002590 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002591 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002592
2593 // Assign argument hints of getaddrinfo() as null is equivalent to set ai_family AF_UNSPEC.
2594 // In AF_UNSPEC case, synthesize AAAA if there has A answer only.
2595 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, nullptr);
2596 EXPECT_TRUE(result != nullptr);
2597 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2598 std::string result_str = ToString(result);
2599 EXPECT_EQ(result_str, "64:ff9b::102:304");
2600 dns.clearQueries();
2601
2602 // In AF_UNSPEC case, do not synthesize AAAA if there's at least one AAAA answer.
2603 result = safe_getaddrinfo("v4v6", nullptr, nullptr);
2604 EXPECT_TRUE(result != nullptr);
2605 EXPECT_LE(2U, GetNumQueries(dns, host_name2));
2606 std::vector<std::string> result_strs = ToStrings(result);
2607 for (const auto& str : result_strs) {
2608 EXPECT_TRUE(str == "1.2.3.4" || str == "2001:db8::102:304")
2609 << ", result_str='" << str << "'";
2610 }
2611}
2612
2613TEST_F(ResolverTest, GetAddrInfo_Dns64QueryNullArgumentNode) {
2614 constexpr char ADDR_ANYADDR_V4[] = "0.0.0.0";
2615 constexpr char ADDR_ANYADDR_V6[] = "::";
2616 constexpr char ADDR_LOCALHOST_V4[] = "127.0.0.1";
2617 constexpr char ADDR_LOCALHOST_V6[] = "::1";
2618
2619 constexpr char PORT_NAME_HTTP[] = "http";
2620 constexpr char PORT_NUMBER_HTTP[] = "80";
2621
2622 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002623 constexpr char dns64_name[] = "ipv4only.arpa.";
2624
Xiao Ma09b71022018-12-11 17:56:32 +09002625 test::DNSResponder dns(listen_addr);
2626 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachena26cc2a2018-07-17 18:07:23 +08002627 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002628 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002629
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002630 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002631 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002632 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002633
Luke Huangf8215372019-11-22 11:53:41 +08002634 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08002635 // If node is null, return address is listed by libc/getaddrinfo.c as follows.
2636 // - passive socket -> anyaddr (0.0.0.0 or ::)
2637 // - non-passive socket -> localhost (127.0.0.1 or ::1)
2638 static const struct TestConfig {
2639 int flag;
2640 std::string addr_v4;
2641 std::string addr_v6;
2642
2643 std::string asParameters() const {
2644 return StringPrintf("flag=%d, addr_v4=%s, addr_v6=%s", flag, addr_v4.c_str(),
2645 addr_v6.c_str());
2646 }
2647 } testConfigs[]{
2648 {0 /* non-passive */, ADDR_LOCALHOST_V4, ADDR_LOCALHOST_V6},
2649 {AI_PASSIVE, ADDR_ANYADDR_V4, ADDR_ANYADDR_V6}
2650 };
Luke Huangf8215372019-11-22 11:53:41 +08002651 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08002652
2653 for (const auto& config : testConfigs) {
2654 SCOPED_TRACE(config.asParameters());
2655
Xiao Ma09b71022018-12-11 17:56:32 +09002656 addrinfo hints = {
Nick Desaulnierscd6395a2019-10-11 09:15:24 -07002657 .ai_flags = config.flag,
Xiao Ma09b71022018-12-11 17:56:32 +09002658 .ai_family = AF_UNSPEC, // any address family
2659 .ai_socktype = 0, // any type
2660 .ai_protocol = 0, // any protocol
Xiao Ma09b71022018-12-11 17:56:32 +09002661 };
nuccachena26cc2a2018-07-17 18:07:23 +08002662
2663 // Assign hostname as null and service as port name.
2664 ScopedAddrinfo result = safe_getaddrinfo(nullptr, PORT_NAME_HTTP, &hints);
2665 ASSERT_TRUE(result != nullptr);
2666
2667 // Can't be synthesized because it should not get into Netd.
2668 std::vector<std::string> result_strs = ToStrings(result);
2669 for (const auto& str : result_strs) {
2670 EXPECT_TRUE(str == config.addr_v4 || str == config.addr_v6)
2671 << ", result_str='" << str << "'";
2672 }
2673
2674 // Assign hostname as null and service as numeric port number.
2675 hints.ai_flags = config.flag | AI_NUMERICSERV;
2676 result = safe_getaddrinfo(nullptr, PORT_NUMBER_HTTP, &hints);
2677 ASSERT_TRUE(result != nullptr);
2678
2679 // Can't be synthesized because it should not get into Netd.
2680 result_strs = ToStrings(result);
2681 for (const auto& str : result_strs) {
2682 EXPECT_TRUE(str == config.addr_v4 || str == config.addr_v6)
2683 << ", result_str='" << str << "'";
2684 }
2685 }
2686}
2687
2688TEST_F(ResolverTest, GetHostByAddr_ReverseDnsQueryWithHavingNat64Prefix) {
2689 struct hostent* result = nullptr;
2690 struct in_addr v4addr;
2691 struct in6_addr v6addr;
2692
2693 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002694 constexpr char dns64_name[] = "ipv4only.arpa.";
2695 constexpr char ptr_name[] = "v4v6.example.com.";
2696 // PTR record for IPv4 address 1.2.3.4
2697 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2698 // PTR record for IPv6 address 2001:db8::102:304
2699 constexpr char ptr_addr_v6[] =
2700 "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 +09002701 const std::vector<DnsRecord> records = {
2702 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2703 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2704 {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name},
2705 };
nuccachena26cc2a2018-07-17 18:07:23 +08002706
Xiao Ma09b71022018-12-11 17:56:32 +09002707 test::DNSResponder dns(listen_addr);
2708 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002709 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002710 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002711
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002712 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002713 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002714 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002715
2716 // Reverse IPv4 DNS query. Prefix should have no effect on it.
2717 inet_pton(AF_INET, "1.2.3.4", &v4addr);
2718 result = gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET);
2719 ASSERT_TRUE(result != nullptr);
2720 std::string result_str = result->h_name ? result->h_name : "null";
2721 EXPECT_EQ(result_str, "v4v6.example.com");
2722
2723 // Reverse IPv6 DNS query. Prefix should have no effect on it.
2724 inet_pton(AF_INET6, "2001:db8::102:304", &v6addr);
2725 result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2726 ASSERT_TRUE(result != nullptr);
2727 result_str = result->h_name ? result->h_name : "null";
2728 EXPECT_EQ(result_str, "v4v6.example.com");
2729}
2730
2731TEST_F(ResolverTest, GetHostByAddr_ReverseDns64Query) {
2732 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002733 constexpr char dns64_name[] = "ipv4only.arpa.";
2734 constexpr char ptr_name[] = "v4only.example.com.";
2735 // PTR record for IPv4 address 1.2.3.4
2736 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2737 // PTR record for IPv6 address 64:ff9b::1.2.3.4
2738 constexpr char ptr_addr_v6_nomapping[] =
2739 "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.";
2740 constexpr char ptr_name_v6_synthesis[] = "v6synthesis.example.com.";
2741 // PTR record for IPv6 address 64:ff9b::5.6.7.8
2742 constexpr char ptr_addr_v6_synthesis[] =
2743 "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 +09002744 const std::vector<DnsRecord> records = {
2745 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2746 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2747 {ptr_addr_v6_synthesis, ns_type::ns_t_ptr, ptr_name_v6_synthesis},
2748 };
nuccachena26cc2a2018-07-17 18:07:23 +08002749
Xiao Ma09b71022018-12-11 17:56:32 +09002750 test::DNSResponder dns(listen_addr);
2751 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002752 // "ptr_addr_v6_nomapping" is not mapped in DNS server
nuccachena26cc2a2018-07-17 18:07:23 +08002753 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002754 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002755
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002756 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002757 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002758 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002759
2760 // Synthesized PTR record doesn't exist on DNS server
2761 // Reverse IPv6 DNS64 query while DNS server doesn't have an answer for synthesized address.
2762 // After querying synthesized address failed, expect that prefix is removed from IPv6
2763 // synthesized address and do reverse IPv4 query instead.
2764 struct in6_addr v6addr;
2765 inet_pton(AF_INET6, "64:ff9b::1.2.3.4", &v6addr);
2766 struct hostent* result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2767 ASSERT_TRUE(result != nullptr);
2768 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_nomapping)); // PTR record not exist
2769 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4)); // PTR record exist
2770 std::string result_str = result->h_name ? result->h_name : "null";
2771 EXPECT_EQ(result_str, "v4only.example.com");
2772 // Check that return address has been mapped from IPv4 to IPv6 address because Netd
2773 // removes NAT64 prefix and does IPv4 DNS reverse lookup in this case. Then, Netd
2774 // fakes the return IPv4 address as original queried IPv6 address.
2775 result_str = ToString(result);
2776 EXPECT_EQ(result_str, "64:ff9b::102:304");
2777 dns.clearQueries();
2778
2779 // Synthesized PTR record exists on DNS server
2780 // Reverse IPv6 DNS64 query while DNS server has an answer for synthesized address.
2781 // Expect to Netd pass through synthesized address for DNS queries.
2782 inet_pton(AF_INET6, "64:ff9b::5.6.7.8", &v6addr);
2783 result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2784 ASSERT_TRUE(result != nullptr);
2785 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_synthesis));
2786 result_str = result->h_name ? result->h_name : "null";
2787 EXPECT_EQ(result_str, "v6synthesis.example.com");
2788}
2789
2790TEST_F(ResolverTest, GetHostByAddr_ReverseDns64QueryFromHostFile) {
2791 constexpr char dns64_name[] = "ipv4only.arpa.";
2792 constexpr char host_name[] = "localhost";
2793 // The address is synthesized by prefix64:localhost.
2794 constexpr char host_addr[] = "64:ff9b::7f00:1";
nuccachena26cc2a2018-07-17 18:07:23 +08002795 constexpr char listen_addr[] = "::1";
Xiao Ma09b71022018-12-11 17:56:32 +09002796
2797 test::DNSResponder dns(listen_addr);
2798 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
nuccachena26cc2a2018-07-17 18:07:23 +08002799 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002800 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002801
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002802 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002803 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002804 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002805
2806 // Using synthesized "localhost" address to be a trick for resolving host name
2807 // from host file /etc/hosts and "localhost" is the only name in /etc/hosts. Note that this is
2808 // not realistic: the code never synthesizes AAAA records for addresses in 127.0.0.0/8.
2809 struct in6_addr v6addr;
2810 inet_pton(AF_INET6, host_addr, &v6addr);
2811 struct hostent* result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2812 ASSERT_TRUE(result != nullptr);
2813 // Expect no DNS queries; localhost is resolved via /etc/hosts.
2814 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
2815
Luke Huangf8215372019-11-22 11:53:41 +08002816 ASSERT_EQ(sizeof(in6_addr), (unsigned)result->h_length);
nuccachena26cc2a2018-07-17 18:07:23 +08002817 ASSERT_EQ(AF_INET6, result->h_addrtype);
2818 std::string result_str = ToString(result);
2819 EXPECT_EQ(result_str, host_addr);
2820 result_str = result->h_name ? result->h_name : "null";
2821 EXPECT_EQ(result_str, host_name);
2822}
2823
Hungming Chen9e6185a2019-06-04 16:09:19 +08002824TEST_F(ResolverTest, GetHostByAddr_cnamesClasslessReverseDelegation) {
2825 // IPv4 addresses in the subnet with notation '/' or '-'.
2826 constexpr char addr_slash[] = "192.0.2.1";
2827 constexpr char addr_hyphen[] = "192.0.3.1";
2828
2829 // Used to verify DNS reverse query for classless reverse lookup zone. See detail in RFC 2317
2830 // section 4.
2831 const static std::vector<DnsRecord> records = {
2832 // The records for reverse querying "192.0.2.1" in the subnet with notation '/'.
2833 {"1.2.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0/25.2.0.192.in-addr.arpa."},
2834 {"1.0/25.2.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
2835
2836 // The records for reverse querying "192.0.3.1" in the subnet with notation '-'.
2837 {"1.3.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0-127.3.0.192.in-addr.arpa."},
2838 {"1.0-127.3.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
2839 };
2840
2841 test::DNSResponder dns;
2842 StartDns(dns, records);
2843 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
2844
2845 for (const auto& address : {addr_slash, addr_hyphen}) {
2846 SCOPED_TRACE(address);
2847
2848 in_addr v4addr;
2849 ASSERT_TRUE(inet_pton(AF_INET, address, &v4addr));
2850 hostent* result = gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET);
2851 ASSERT_TRUE(result != nullptr);
2852 EXPECT_STREQ("hello.example.com", result->h_name);
2853 }
2854}
2855
nuccachena26cc2a2018-07-17 18:07:23 +08002856TEST_F(ResolverTest, GetNameInfo_ReverseDnsQueryWithHavingNat64Prefix) {
2857 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002858 constexpr char dns64_name[] = "ipv4only.arpa.";
2859 constexpr char ptr_name[] = "v4v6.example.com.";
2860 // PTR record for IPv4 address 1.2.3.4
2861 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2862 // PTR record for IPv6 address 2001:db8::102:304
2863 constexpr char ptr_addr_v6[] =
2864 "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 +09002865 const std::vector<DnsRecord> records = {
2866 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2867 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2868 {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name},
2869 };
nuccachena26cc2a2018-07-17 18:07:23 +08002870
Xiao Ma09b71022018-12-11 17:56:32 +09002871 test::DNSResponder dns(listen_addr);
2872 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002873 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002874 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002875
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002876 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002877 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002878 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002879
Luke Huangf8215372019-11-22 11:53:41 +08002880 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08002881 static const struct TestConfig {
2882 int flag;
2883 int family;
2884 std::string addr;
2885 std::string host;
2886
2887 std::string asParameters() const {
2888 return StringPrintf("flag=%d, family=%d, addr=%s, host=%s", flag, family, addr.c_str(),
2889 host.c_str());
2890 }
2891 } testConfigs[]{
2892 {NI_NAMEREQD, AF_INET, "1.2.3.4", "v4v6.example.com"},
2893 {NI_NUMERICHOST, AF_INET, "1.2.3.4", "1.2.3.4"},
2894 {0, AF_INET, "1.2.3.4", "v4v6.example.com"},
2895 {0, AF_INET, "5.6.7.8", "5.6.7.8"}, // unmapped
2896 {NI_NAMEREQD, AF_INET6, "2001:db8::102:304", "v4v6.example.com"},
2897 {NI_NUMERICHOST, AF_INET6, "2001:db8::102:304", "2001:db8::102:304"},
2898 {0, AF_INET6, "2001:db8::102:304", "v4v6.example.com"},
2899 {0, AF_INET6, "2001:db8::506:708", "2001:db8::506:708"}, // unmapped
2900 };
Luke Huangf8215372019-11-22 11:53:41 +08002901 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08002902
2903 // Reverse IPv4/IPv6 DNS query. Prefix should have no effect on it.
2904 for (const auto& config : testConfigs) {
2905 SCOPED_TRACE(config.asParameters());
2906
2907 int rv;
2908 char host[NI_MAXHOST];
2909 struct sockaddr_in sin;
2910 struct sockaddr_in6 sin6;
2911 if (config.family == AF_INET) {
2912 memset(&sin, 0, sizeof(sin));
2913 sin.sin_family = AF_INET;
2914 inet_pton(AF_INET, config.addr.c_str(), &sin.sin_addr);
Luke Huangf8215372019-11-22 11:53:41 +08002915 rv = getnameinfo((const struct sockaddr*)&sin, sizeof(sin), host, sizeof(host), nullptr,
2916 0, config.flag);
nuccachena26cc2a2018-07-17 18:07:23 +08002917 if (config.flag == NI_NAMEREQD) EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4));
2918 } else if (config.family == AF_INET6) {
2919 memset(&sin6, 0, sizeof(sin6));
2920 sin6.sin6_family = AF_INET6;
2921 inet_pton(AF_INET6, config.addr.c_str(), &sin6.sin6_addr);
Luke Huangf8215372019-11-22 11:53:41 +08002922 rv = getnameinfo((const struct sockaddr*)&sin6, sizeof(sin6), host, sizeof(host),
nuccachena26cc2a2018-07-17 18:07:23 +08002923 nullptr, 0, config.flag);
2924 if (config.flag == NI_NAMEREQD) EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6));
2925 }
2926 ASSERT_EQ(0, rv);
2927 std::string result_str = host;
2928 EXPECT_EQ(result_str, config.host);
2929 dns.clearQueries();
2930 }
2931}
2932
2933TEST_F(ResolverTest, GetNameInfo_ReverseDns64Query) {
2934 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002935 constexpr char dns64_name[] = "ipv4only.arpa.";
2936 constexpr char ptr_name[] = "v4only.example.com.";
2937 // PTR record for IPv4 address 1.2.3.4
2938 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2939 // PTR record for IPv6 address 64:ff9b::1.2.3.4
2940 constexpr char ptr_addr_v6_nomapping[] =
2941 "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.";
2942 constexpr char ptr_name_v6_synthesis[] = "v6synthesis.example.com.";
2943 // PTR record for IPv6 address 64:ff9b::5.6.7.8
2944 constexpr char ptr_addr_v6_synthesis[] =
2945 "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 +09002946 const std::vector<DnsRecord> records = {
2947 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2948 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2949 {ptr_addr_v6_synthesis, ns_type::ns_t_ptr, ptr_name_v6_synthesis},
2950 };
nuccachena26cc2a2018-07-17 18:07:23 +08002951
Xiao Ma09b71022018-12-11 17:56:32 +09002952 test::DNSResponder dns(listen_addr);
2953 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002954 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002955 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002956
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002957 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002958 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002959 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002960
Luke Huangf8215372019-11-22 11:53:41 +08002961 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08002962 static const struct TestConfig {
2963 bool hasSynthesizedPtrRecord;
2964 int flag;
2965 std::string addr;
2966 std::string host;
2967
2968 std::string asParameters() const {
2969 return StringPrintf("hasSynthesizedPtrRecord=%d, flag=%d, addr=%s, host=%s",
2970 hasSynthesizedPtrRecord, flag, addr.c_str(), host.c_str());
2971 }
2972 } testConfigs[]{
2973 {false, NI_NAMEREQD, "64:ff9b::102:304", "v4only.example.com"},
2974 {false, NI_NUMERICHOST, "64:ff9b::102:304", "64:ff9b::102:304"},
2975 {false, 0, "64:ff9b::102:304", "v4only.example.com"},
2976 {true, NI_NAMEREQD, "64:ff9b::506:708", "v6synthesis.example.com"},
2977 {true, NI_NUMERICHOST, "64:ff9b::506:708", "64:ff9b::506:708"},
2978 {true, 0, "64:ff9b::506:708", "v6synthesis.example.com"}
2979 };
Luke Huangf8215372019-11-22 11:53:41 +08002980 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08002981
2982 // hasSynthesizedPtrRecord = false
2983 // Synthesized PTR record doesn't exist on DNS server
2984 // Reverse IPv6 DNS64 query while DNS server doesn't have an answer for synthesized address.
2985 // After querying synthesized address failed, expect that prefix is removed from IPv6
2986 // synthesized address and do reverse IPv4 query instead.
2987 //
2988 // hasSynthesizedPtrRecord = true
2989 // Synthesized PTR record exists on DNS server
2990 // Reverse IPv6 DNS64 query while DNS server has an answer for synthesized address.
2991 // Expect to just pass through synthesized address for DNS queries.
2992 for (const auto& config : testConfigs) {
2993 SCOPED_TRACE(config.asParameters());
2994
2995 char host[NI_MAXHOST];
2996 struct sockaddr_in6 sin6;
2997 memset(&sin6, 0, sizeof(sin6));
2998 sin6.sin6_family = AF_INET6;
2999 inet_pton(AF_INET6, config.addr.c_str(), &sin6.sin6_addr);
Luke Huangf8215372019-11-22 11:53:41 +08003000 int rv = getnameinfo((const struct sockaddr*)&sin6, sizeof(sin6), host, sizeof(host),
nuccachena26cc2a2018-07-17 18:07:23 +08003001 nullptr, 0, config.flag);
3002 ASSERT_EQ(0, rv);
3003 if (config.flag == NI_NAMEREQD) {
3004 if (config.hasSynthesizedPtrRecord) {
3005 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_synthesis));
3006 } else {
3007 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_nomapping)); // PTR record not exist.
3008 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4)); // PTR record exist.
3009 }
3010 }
3011 std::string result_str = host;
3012 EXPECT_EQ(result_str, config.host);
3013 dns.clearQueries();
3014 }
3015}
3016
3017TEST_F(ResolverTest, GetNameInfo_ReverseDns64QueryFromHostFile) {
3018 constexpr char dns64_name[] = "ipv4only.arpa.";
3019 constexpr char host_name[] = "localhost";
3020 // The address is synthesized by prefix64:localhost.
3021 constexpr char host_addr[] = "64:ff9b::7f00:1";
nuccachena26cc2a2018-07-17 18:07:23 +08003022 constexpr char listen_addr[] = "::1";
Xiao Ma09b71022018-12-11 17:56:32 +09003023
3024 test::DNSResponder dns(listen_addr);
3025 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
nuccachena26cc2a2018-07-17 18:07:23 +08003026 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003027 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003028
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003029 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003030 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003031 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003032
3033 // Using synthesized "localhost" address to be a trick for resolving host name
3034 // from host file /etc/hosts and "localhost" is the only name in /etc/hosts. Note that this is
3035 // not realistic: the code never synthesizes AAAA records for addresses in 127.0.0.0/8.
3036 char host[NI_MAXHOST];
Xiao Ma09b71022018-12-11 17:56:32 +09003037 struct sockaddr_in6 sin6 = {.sin6_family = AF_INET6};
nuccachena26cc2a2018-07-17 18:07:23 +08003038 inet_pton(AF_INET6, host_addr, &sin6.sin6_addr);
Luke Huangf8215372019-11-22 11:53:41 +08003039 int rv = getnameinfo((const struct sockaddr*)&sin6, sizeof(sin6), host, sizeof(host), nullptr,
nuccachena26cc2a2018-07-17 18:07:23 +08003040 0, NI_NAMEREQD);
3041 ASSERT_EQ(0, rv);
3042 // Expect no DNS queries; localhost is resolved via /etc/hosts.
3043 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
3044
3045 std::string result_str = host;
3046 EXPECT_EQ(result_str, host_name);
3047}
3048
Hungming Chen9e6185a2019-06-04 16:09:19 +08003049TEST_F(ResolverTest, GetNameInfo_cnamesClasslessReverseDelegation) {
3050 // IPv4 addresses in the subnet with notation '/' or '-'.
3051 constexpr char addr_slash[] = "192.0.2.1";
3052 constexpr char addr_hyphen[] = "192.0.3.1";
3053
3054 // Used to verify DNS reverse query for classless reverse lookup zone. See detail in RFC 2317
3055 // section 4.
3056 const static std::vector<DnsRecord> records = {
3057 // The records for reverse querying "192.0.2.1" in the subnet with notation '/'.
3058 {"1.2.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0/25.2.0.192.in-addr.arpa."},
3059 {"1.0/25.2.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
3060
3061 // The records for reverse querying "192.0.3.1" in the subnet with notation '-'.
3062 {"1.3.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0-127.3.0.192.in-addr.arpa."},
3063 {"1.0-127.3.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
3064 };
3065
3066 test::DNSResponder dns;
3067 StartDns(dns, records);
3068 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3069
3070 for (const auto& address : {addr_slash, addr_hyphen}) {
3071 SCOPED_TRACE(address);
3072
3073 char host[NI_MAXHOST];
3074 sockaddr_in sin = {.sin_family = AF_INET};
3075 ASSERT_TRUE(inet_pton(AF_INET, address, &sin.sin_addr));
3076 int rv = getnameinfo((const sockaddr*)&sin, sizeof(sin), host, sizeof(host), nullptr, 0,
3077 NI_NAMEREQD);
3078 ASSERT_EQ(0, rv);
3079 EXPECT_STREQ("hello.example.com", host);
3080 }
3081}
3082
nuccachena26cc2a2018-07-17 18:07:23 +08003083TEST_F(ResolverTest, GetHostByName2_Dns64Synthesize) {
Xiao Ma09b71022018-12-11 17:56:32 +09003084 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08003085 constexpr char dns64_name[] = "ipv4only.arpa.";
3086 constexpr char host_name[] = "ipv4only.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09003087 const std::vector<DnsRecord> records = {
3088 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
3089 {host_name, ns_type::ns_t_a, "1.2.3.4"},
3090 };
nuccachena26cc2a2018-07-17 18:07:23 +08003091
Xiao Ma09b71022018-12-11 17:56:32 +09003092 test::DNSResponder dns(listen_addr);
3093 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08003094 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003095 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003096
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003097 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003098 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003099 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003100
3101 // Query an IPv4-only hostname. Expect that gets a synthesized address.
3102 struct hostent* result = gethostbyname2("ipv4only", AF_INET6);
3103 ASSERT_TRUE(result != nullptr);
3104 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3105 std::string result_str = ToString(result);
3106 EXPECT_EQ(result_str, "64:ff9b::102:304");
3107}
nuccachena26cc2a2018-07-17 18:07:23 +08003108
3109TEST_F(ResolverTest, GetHostByName2_DnsQueryWithHavingNat64Prefix) {
3110 constexpr char dns64_name[] = "ipv4only.arpa.";
3111 constexpr char host_name[] = "v4v6.example.com.";
nuccachena26cc2a2018-07-17 18:07:23 +08003112 constexpr char listen_addr[] = "::1";
Xiao Ma09b71022018-12-11 17:56:32 +09003113 const std::vector<DnsRecord> records = {
3114 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
3115 {host_name, ns_type::ns_t_a, "1.2.3.4"},
3116 {host_name, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
3117 };
3118
3119 test::DNSResponder dns(listen_addr);
3120 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08003121 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003122 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003123
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003124 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003125 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003126 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003127
3128 // IPv4 DNS query. Prefix should have no effect on it.
3129 struct hostent* result = gethostbyname2("v4v6", AF_INET);
3130 ASSERT_TRUE(result != nullptr);
3131 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3132 std::string result_str = ToString(result);
3133 EXPECT_EQ(result_str, "1.2.3.4");
3134 dns.clearQueries();
3135
3136 // IPv6 DNS query. Prefix should have no effect on it.
3137 result = gethostbyname2("v4v6", AF_INET6);
3138 ASSERT_TRUE(result != nullptr);
3139 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3140 result_str = ToString(result);
3141 EXPECT_EQ(result_str, "2001:db8::102:304");
3142}
3143
3144TEST_F(ResolverTest, GetHostByName2_Dns64QuerySpecialUseIPv4Addresses) {
3145 constexpr char THIS_NETWORK[] = "this_network";
3146 constexpr char LOOPBACK[] = "loopback";
3147 constexpr char LINK_LOCAL[] = "link_local";
3148 constexpr char MULTICAST[] = "multicast";
3149 constexpr char LIMITED_BROADCAST[] = "limited_broadcast";
3150
3151 constexpr char ADDR_THIS_NETWORK[] = "0.0.0.1";
3152 constexpr char ADDR_LOOPBACK[] = "127.0.0.1";
3153 constexpr char ADDR_LINK_LOCAL[] = "169.254.0.1";
3154 constexpr char ADDR_MULTICAST[] = "224.0.0.1";
3155 constexpr char ADDR_LIMITED_BROADCAST[] = "255.255.255.255";
3156
3157 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08003158 constexpr char dns64_name[] = "ipv4only.arpa.";
3159
Xiao Ma09b71022018-12-11 17:56:32 +09003160 test::DNSResponder dns(listen_addr);
3161 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachena26cc2a2018-07-17 18:07:23 +08003162 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003163 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003164
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003165 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003166 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003167 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003168
Luke Huangf8215372019-11-22 11:53:41 +08003169 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08003170 static const struct TestConfig {
3171 std::string name;
3172 std::string addr;
3173
3174 std::string asHostName() const {
Luke Huangf8215372019-11-22 11:53:41 +08003175 return StringPrintf("%s.example.com.", name.c_str());
nuccachena26cc2a2018-07-17 18:07:23 +08003176 }
3177 } testConfigs[]{
3178 {THIS_NETWORK, ADDR_THIS_NETWORK},
3179 {LOOPBACK, ADDR_LOOPBACK},
3180 {LINK_LOCAL, ADDR_LINK_LOCAL},
3181 {MULTICAST, ADDR_MULTICAST},
3182 {LIMITED_BROADCAST, ADDR_LIMITED_BROADCAST}
3183 };
Luke Huangf8215372019-11-22 11:53:41 +08003184 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08003185
3186 for (const auto& config : testConfigs) {
3187 const std::string testHostName = config.asHostName();
3188 SCOPED_TRACE(testHostName);
3189
3190 const char* host_name = testHostName.c_str();
3191 dns.addMapping(host_name, ns_type::ns_t_a, config.addr.c_str());
3192
3193 struct hostent* result = gethostbyname2(config.name.c_str(), AF_INET6);
3194 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3195
3196 // In AF_INET6 case, don't synthesize special use IPv4 address.
3197 // Expect to have no answer
3198 EXPECT_EQ(nullptr, result);
3199
3200 dns.clearQueries();
3201 }
Bernie Innocenti2fef2b82018-12-20 15:56:40 +09003202}
Mike Yuf14e1a92019-05-10 13:54:58 +08003203
3204TEST_F(ResolverTest, PrefixDiscoveryBypassTls) {
3205 constexpr char listen_addr[] = "::1";
3206 constexpr char cleartext_port[] = "53";
3207 constexpr char tls_port[] = "853";
3208 constexpr char dns64_name[] = "ipv4only.arpa.";
3209 const std::vector<std::string> servers = {listen_addr};
3210
3211 test::DNSResponder dns(listen_addr);
3212 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
3213 test::DnsTlsFrontend tls(listen_addr, tls_port, listen_addr, cleartext_port);
3214 ASSERT_TRUE(tls.startServer());
3215
3216 // Setup OPPORTUNISTIC mode and wait for the validation complete.
waynema0e73c2e2019-07-31 15:04:08 +08003217 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08003218 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yuf14e1a92019-05-10 13:54:58 +08003219 tls.clearQueries();
3220
3221 // Start NAT64 prefix discovery and wait for it complete.
3222 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003223 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
Mike Yuf14e1a92019-05-10 13:54:58 +08003224
3225 // Verify it bypassed TLS even though there's a TLS server available.
3226 EXPECT_EQ(0, tls.queries());
3227 EXPECT_EQ(1U, GetNumQueries(dns, dns64_name));
3228
3229 // Restart the testing network to reset the cache.
3230 mDnsClient.TearDown();
3231 mDnsClient.SetUp();
3232 dns.clearQueries();
3233
3234 // Setup STRICT mode and wait for the validation complete.
waynema0e73c2e2019-07-31 15:04:08 +08003235 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
3236 kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08003237 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yuf14e1a92019-05-10 13:54:58 +08003238 tls.clearQueries();
3239
3240 // Start NAT64 prefix discovery and wait for it to complete.
3241 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003242 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
Mike Yuf14e1a92019-05-10 13:54:58 +08003243
3244 // Verify it bypassed TLS despite STRICT mode.
3245 EXPECT_EQ(0, tls.queries());
3246 EXPECT_EQ(1U, GetNumQueries(dns, dns64_name));
3247}
Luke Huang9807e6b2019-05-20 16:17:12 +08003248
3249namespace {
3250
Luke Huang0d592bc2019-05-25 18:24:03 +08003251class ScopedSetNetworkForProcess {
3252 public:
3253 explicit ScopedSetNetworkForProcess(unsigned netId) {
3254 mStoredNetId = getNetworkForProcess();
3255 if (netId == mStoredNetId) return;
3256 EXPECT_EQ(0, setNetworkForProcess(netId));
3257 }
3258 ~ScopedSetNetworkForProcess() { EXPECT_EQ(0, setNetworkForProcess(mStoredNetId)); }
3259
3260 private:
3261 unsigned mStoredNetId;
3262};
3263
3264class ScopedSetNetworkForResolv {
3265 public:
3266 explicit ScopedSetNetworkForResolv(unsigned netId) { EXPECT_EQ(0, setNetworkForResolv(netId)); }
3267 ~ScopedSetNetworkForResolv() { EXPECT_EQ(0, setNetworkForResolv(NETID_UNSET)); }
3268};
3269
Luke Huang9807e6b2019-05-20 16:17:12 +08003270void sendCommand(int fd, const std::string& cmd) {
3271 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size() + 1));
3272 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size() + 1));
3273}
3274
3275int32_t readBE32(int fd) {
3276 int32_t tmp;
3277 int n = TEMP_FAILURE_RETRY(read(fd, &tmp, sizeof(tmp)));
3278 EXPECT_TRUE(n > 0);
3279 return ntohl(tmp);
3280}
3281
Luke Huang0d592bc2019-05-25 18:24:03 +08003282int readResponseCode(int fd) {
Luke Huang9807e6b2019-05-20 16:17:12 +08003283 char buf[4];
3284 int n = TEMP_FAILURE_RETRY(read(fd, &buf, sizeof(buf)));
3285 EXPECT_TRUE(n > 0);
3286 // The format of response code is that 4 bytes for the code & null.
3287 buf[3] = '\0';
3288 int result;
3289 EXPECT_TRUE(ParseInt(buf, &result));
3290 return result;
3291}
3292
Luke Huang0d592bc2019-05-25 18:24:03 +08003293bool checkAndClearUseLocalNameserversFlag(unsigned* netid) {
3294 if (netid == nullptr || ((*netid) & NETID_USE_LOCAL_NAMESERVERS) == 0) {
3295 return false;
3296 }
3297 *netid = (*netid) & ~NETID_USE_LOCAL_NAMESERVERS;
3298 return true;
3299}
3300
Luke Huangf8215372019-11-22 11:53:41 +08003301aidl::android::net::UidRangeParcel makeUidRangeParcel(int start, int stop) {
3302 aidl::android::net::UidRangeParcel res;
Luke Huang0d592bc2019-05-25 18:24:03 +08003303 res.start = start;
3304 res.stop = stop;
3305
3306 return res;
3307}
3308
3309void expectNetIdWithLocalNameserversFlag(unsigned netId) {
3310 unsigned dnsNetId = 0;
3311 EXPECT_EQ(0, getNetworkForDns(&dnsNetId));
3312 EXPECT_TRUE(checkAndClearUseLocalNameserversFlag(&dnsNetId));
3313 EXPECT_EQ(netId, static_cast<unsigned>(dnsNetId));
3314}
3315
3316void expectDnsNetIdEquals(unsigned netId) {
3317 unsigned dnsNetId = 0;
3318 EXPECT_EQ(0, getNetworkForDns(&dnsNetId));
3319 EXPECT_EQ(netId, static_cast<unsigned>(dnsNetId));
3320}
3321
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003322void expectDnsNetIdIsDefaultNetwork(INetd* netdService) {
Luke Huang0d592bc2019-05-25 18:24:03 +08003323 int currentNetid;
3324 EXPECT_TRUE(netdService->networkGetDefault(&currentNetid).isOk());
3325 expectDnsNetIdEquals(currentNetid);
3326}
3327
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003328void expectDnsNetIdWithVpn(INetd* netdService, unsigned vpnNetId, unsigned expectedNetId) {
Luke Huang0d592bc2019-05-25 18:24:03 +08003329 EXPECT_TRUE(netdService->networkCreateVpn(vpnNetId, false /* secure */).isOk());
3330 uid_t uid = getuid();
3331 // Add uid to VPN
3332 EXPECT_TRUE(netdService->networkAddUidRanges(vpnNetId, {makeUidRangeParcel(uid, uid)}).isOk());
3333 expectDnsNetIdEquals(expectedNetId);
3334 EXPECT_TRUE(netdService->networkDestroy(vpnNetId).isOk());
3335}
3336
Luke Huang9807e6b2019-05-20 16:17:12 +08003337} // namespace
3338
3339TEST_F(ResolverTest, getDnsNetId) {
3340 // We've called setNetworkForProcess in SetupOemNetwork, so reset to default first.
3341 setNetworkForProcess(NETID_UNSET);
Luke Huang0d592bc2019-05-25 18:24:03 +08003342
3343 expectDnsNetIdIsDefaultNetwork(mDnsClient.netdService());
3344 expectDnsNetIdWithVpn(mDnsClient.netdService(), TEST_VPN_NETID, TEST_VPN_NETID);
Luke Huang9807e6b2019-05-20 16:17:12 +08003345
3346 // Test with setNetworkForProcess
Luke Huang0d592bc2019-05-25 18:24:03 +08003347 {
3348 ScopedSetNetworkForProcess scopedSetNetworkForProcess(TEST_NETID);
3349 expectDnsNetIdEquals(TEST_NETID);
3350 }
3351
3352 // Test with setNetworkForProcess with NETID_USE_LOCAL_NAMESERVERS
3353 {
3354 ScopedSetNetworkForProcess scopedSetNetworkForProcess(TEST_NETID |
3355 NETID_USE_LOCAL_NAMESERVERS);
3356 expectNetIdWithLocalNameserversFlag(TEST_NETID);
3357 }
Luke Huang9807e6b2019-05-20 16:17:12 +08003358
3359 // Test with setNetworkForResolv
Luke Huang0d592bc2019-05-25 18:24:03 +08003360 {
3361 ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID);
3362 expectDnsNetIdEquals(TEST_NETID);
3363 }
3364
3365 // Test with setNetworkForResolv with NETID_USE_LOCAL_NAMESERVERS
3366 {
3367 ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID |
3368 NETID_USE_LOCAL_NAMESERVERS);
3369 expectNetIdWithLocalNameserversFlag(TEST_NETID);
3370 }
3371
3372 // Test with setNetworkForResolv under bypassable vpn
3373 {
3374 ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID);
3375 expectDnsNetIdWithVpn(mDnsClient.netdService(), TEST_VPN_NETID, TEST_NETID);
3376 }
Luke Huang9807e6b2019-05-20 16:17:12 +08003377
3378 // Create socket connected to DnsProxyListener
3379 int fd = dns_open_proxy();
3380 EXPECT_TRUE(fd > 0);
3381 unique_fd ufd(fd);
3382
3383 // Test command with wrong netId
3384 sendCommand(fd, "getdnsnetid abc");
Luke Huang0d592bc2019-05-25 18:24:03 +08003385 EXPECT_EQ(ResponseCode::DnsProxyQueryResult, readResponseCode(fd));
Luke Huang9807e6b2019-05-20 16:17:12 +08003386 EXPECT_EQ(-EINVAL, readBE32(fd));
3387
3388 // Test unsupported command
3389 sendCommand(fd, "getdnsnetidNotSupported");
3390 // Keep in sync with FrameworkListener.cpp (500, "Command not recognized")
Luke Huang0d592bc2019-05-25 18:24:03 +08003391 EXPECT_EQ(500, readResponseCode(fd));
Luke Huang9807e6b2019-05-20 16:17:12 +08003392}
Sehee Park2c118782019-05-07 13:02:45 +09003393
3394TEST_F(ResolverTest, BlockDnsQueryWithUidRule) {
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003395 // This test relies on blocking traffic on loopback, which xt_qtaguid does not do.
3396 // See aosp/358413 and b/34444781 for why.
3397 SKIP_IF_BPF_NOT_SUPPORTED;
3398
Sehee Park2c118782019-05-07 13:02:45 +09003399 constexpr char listen_addr1[] = "127.0.0.4";
3400 constexpr char listen_addr2[] = "::1";
3401 constexpr char host_name[] = "howdy.example.com.";
3402 const std::vector<DnsRecord> records = {
3403 {host_name, ns_type::ns_t_a, "1.2.3.4"},
3404 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
3405 };
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003406 INetd* netdService = mDnsClient.netdService();
Sehee Park2c118782019-05-07 13:02:45 +09003407
3408 test::DNSResponder dns1(listen_addr1);
3409 test::DNSResponder dns2(listen_addr2);
3410 StartDns(dns1, records);
3411 StartDns(dns2, records);
3412
3413 std::vector<std::string> servers = {listen_addr1, listen_addr2};
3414 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
3415 dns1.clearQueries();
3416 dns2.clearQueries();
3417
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003418 // Add drop rule for TEST_UID. Also enable the standby chain because it might not be enabled.
3419 // Unfortunately we cannot use FIREWALL_CHAIN_NONE, or custom iptables rules, for this purpose
3420 // because netd calls fchown() on the DNS query sockets, and "iptables -m owner" matches the
3421 // UID of the socket creator, not the UID set by fchown().
3422 //
3423 // TODO: migrate FIREWALL_CHAIN_NONE to eBPF as well.
3424 EXPECT_TRUE(netdService->firewallEnableChildChain(INetd::FIREWALL_CHAIN_STANDBY, true).isOk());
3425 EXPECT_TRUE(netdService
Sehee Park2c118782019-05-07 13:02:45 +09003426 ->firewallSetUidRule(INetd::FIREWALL_CHAIN_STANDBY, TEST_UID,
3427 INetd::FIREWALL_RULE_DENY)
3428 .isOk());
3429
3430 // Save uid
3431 int suid = getuid();
3432
3433 // Switch to TEST_UID
3434 EXPECT_TRUE(seteuid(TEST_UID) == 0);
3435
3436 // Dns Query
3437 int fd1 = resNetworkQuery(TEST_NETID, host_name, ns_c_in, ns_t_a, 0);
3438 int fd2 = resNetworkQuery(TEST_NETID, host_name, ns_c_in, ns_t_aaaa, 0);
3439 EXPECT_TRUE(fd1 != -1);
3440 EXPECT_TRUE(fd2 != -1);
3441
3442 uint8_t buf[MAXPACKET] = {};
3443 int rcode;
3444 int res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
3445 EXPECT_EQ(-ECONNREFUSED, res);
3446
3447 memset(buf, 0, MAXPACKET);
3448 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
3449 EXPECT_EQ(-ECONNREFUSED, res);
3450
3451 // Restore uid
3452 EXPECT_TRUE(seteuid(suid) == 0);
3453
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003454 // Remove drop rule for TEST_UID, and disable the standby chain.
3455 EXPECT_TRUE(netdService
Sehee Park2c118782019-05-07 13:02:45 +09003456 ->firewallSetUidRule(INetd::FIREWALL_CHAIN_STANDBY, TEST_UID,
3457 INetd::FIREWALL_RULE_ALLOW)
3458 .isOk());
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003459 EXPECT_TRUE(netdService->firewallEnableChildChain(INetd::FIREWALL_CHAIN_STANDBY, false).isOk());
Sehee Park2c118782019-05-07 13:02:45 +09003460}
Mike Yua772c202019-09-23 17:47:21 +08003461
Mike Yu40e67072019-10-09 21:14:09 +08003462namespace {
3463
3464const std::string kDotConnectTimeoutMsFlag(
3465 "persist.device_config.netd_native.dot_connect_timeout_ms");
3466
3467class ScopedSystemProperties {
3468 public:
3469 explicit ScopedSystemProperties(const std::string& key, const std::string& value)
3470 : mStoredKey(key) {
3471 mStoredValue = android::base::GetProperty(key, "");
3472 android::base::SetProperty(key, value);
3473 }
3474 ~ScopedSystemProperties() { android::base::SetProperty(mStoredKey, mStoredValue); }
3475
3476 private:
3477 std::string mStoredKey;
3478 std::string mStoredValue;
3479};
3480
3481} // namespace
3482
Mike Yua772c202019-09-23 17:47:21 +08003483TEST_F(ResolverTest, ConnectTlsServerTimeout) {
Mike Yu40e67072019-10-09 21:14:09 +08003484 constexpr int expectedTimeout = 1000;
3485 constexpr char hostname1[] = "query1.example.com.";
3486 constexpr char hostname2[] = "query2.example.com.";
Mike Yua772c202019-09-23 17:47:21 +08003487 const std::vector<DnsRecord> records = {
Mike Yu40e67072019-10-09 21:14:09 +08003488 {hostname1, ns_type::ns_t_a, "1.2.3.4"},
3489 {hostname2, ns_type::ns_t_a, "1.2.3.5"},
Mike Yua772c202019-09-23 17:47:21 +08003490 };
3491
3492 test::DNSResponder dns;
3493 StartDns(dns, records);
Mike Yu40e67072019-10-09 21:14:09 +08003494 test::DnsTlsFrontend tls;
Mike Yua772c202019-09-23 17:47:21 +08003495 ASSERT_TRUE(tls.startServer());
3496
Mike Yu40e67072019-10-09 21:14:09 +08003497 // The resolver will adjust the timeout value to 1000ms since the value is too small.
3498 ScopedSystemProperties scopedSystemProperties(kDotConnectTimeoutMsFlag, "100");
Mike Yua772c202019-09-23 17:47:21 +08003499
Mike Yu40e67072019-10-09 21:14:09 +08003500 // Set up resolver to opportunistic mode with the default configuration.
Luke Huangf8215372019-11-22 11:53:41 +08003501 const aidl::android::net::ResolverParamsParcel parcel =
3502 DnsResponderClient::GetDefaultResolverParamsParcel();
Mike Yu40e67072019-10-09 21:14:09 +08003503 ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
Mike Yua772c202019-09-23 17:47:21 +08003504 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
3505 dns.clearQueries();
3506 tls.clearQueries();
3507
3508 // The server becomes unresponsive to the handshake request.
3509 tls.setHangOnHandshakeForTesting(true);
3510
3511 // Expect the things happening in getaddrinfo():
3512 // 1. Connect to the private DNS server.
3513 // 2. SSL handshake times out.
3514 // 3. Fallback to UDP transport, and then get the answer.
Mike Yu40e67072019-10-09 21:14:09 +08003515 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
3516 auto [result, timeTakenMs] = safe_getaddrinfo_time_taken(hostname1, nullptr, hints);
Mike Yua772c202019-09-23 17:47:21 +08003517
Mike Yu40e67072019-10-09 21:14:09 +08003518 EXPECT_NE(nullptr, result);
Mike Yua772c202019-09-23 17:47:21 +08003519 EXPECT_EQ(0, tls.queries());
Mike Yu40e67072019-10-09 21:14:09 +08003520 EXPECT_EQ(1U, GetNumQueries(dns, hostname1));
3521 EXPECT_EQ(records.at(0).addr, ToString(result));
Mike Yua772c202019-09-23 17:47:21 +08003522
Mike Yu40e67072019-10-09 21:14:09 +08003523 // A loose upper bound is set by adding 2000ms buffer time. Theoretically, getaddrinfo()
3524 // should just take a bit more than expetTimeout milliseconds.
3525 EXPECT_GE(timeTakenMs, expectedTimeout);
3526 EXPECT_LE(timeTakenMs, expectedTimeout + 2000);
3527
3528 // Set the server to be responsive. Verify that the resolver will attempt to reconnect
3529 // to the server and then get the result within the timeout.
3530 tls.setHangOnHandshakeForTesting(false);
3531 std::tie(result, timeTakenMs) = safe_getaddrinfo_time_taken(hostname2, nullptr, hints);
3532
3533 EXPECT_NE(nullptr, result);
3534 EXPECT_EQ(1, tls.queries());
3535 EXPECT_EQ(1U, GetNumQueries(dns, hostname2));
3536 EXPECT_EQ(records.at(1).addr, ToString(result));
3537
3538 EXPECT_LE(timeTakenMs, expectedTimeout);
Mike Yua772c202019-09-23 17:47:21 +08003539}
Hungming Chenbb90ab32019-10-28 18:20:31 +08003540
Ken Chen766feae2019-10-30 15:13:44 +08003541TEST_F(ResolverTest, FlushNetworkCache) {
Luke Huang0b5a76c2019-11-23 03:00:00 +08003542 SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsClient.resolvService(), 4);
Ken Chen766feae2019-10-30 15:13:44 +08003543 test::DNSResponder dns;
3544 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3545 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3546
3547 const hostent* result = gethostbyname("hello");
3548 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
3549
3550 // get result from cache
3551 result = gethostbyname("hello");
3552 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
3553
3554 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
3555
3556 result = gethostbyname("hello");
3557 EXPECT_EQ(2U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
3558}
3559
3560TEST_F(ResolverTest, FlushNetworkCache_random) {
Luke Huang0b5a76c2019-11-23 03:00:00 +08003561 SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsClient.resolvService(), 4);
Ken Chen766feae2019-10-30 15:13:44 +08003562 constexpr int num_flush = 10;
3563 constexpr int num_queries = 20;
3564 test::DNSResponder dns;
3565 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3566 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3567 const addrinfo hints = {.ai_family = AF_INET};
3568
3569 std::thread t([this]() {
3570 for (int i = 0; i < num_flush; ++i) {
3571 unsigned delay = arc4random_uniform(10 * 1000); // 10ms
3572 usleep(delay);
3573 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
3574 }
3575 });
3576
3577 for (int i = 0; i < num_queries; ++i) {
3578 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3579 EXPECT_TRUE(result != nullptr);
3580 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3581 }
3582 t.join();
3583}
3584
3585// flush cache while one query is wait-for-response, another is pending.
3586TEST_F(ResolverTest, FlushNetworkCache_concurrent) {
Luke Huang0b5a76c2019-11-23 03:00:00 +08003587 SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsClient.resolvService(), 4);
Ken Chen766feae2019-10-30 15:13:44 +08003588 const char* listen_addr1 = "127.0.0.9";
3589 const char* listen_addr2 = "127.0.0.10";
3590 test::DNSResponder dns1(listen_addr1);
3591 test::DNSResponder dns2(listen_addr2);
3592 StartDns(dns1, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3593 StartDns(dns2, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3594 addrinfo hints = {.ai_family = AF_INET};
3595
3596 // step 1: set server#1 into deferred responding mode
3597 dns1.setDeferredResp(true);
3598 std::thread t1([&listen_addr1, &hints, this]() {
3599 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr1}));
3600 // step 3: query
3601 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3602 // step 9: check result
3603 EXPECT_TRUE(result != nullptr);
3604 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3605 });
3606
3607 // step 2: wait for the query to reach the server
3608 while (GetNumQueries(dns1, kHelloExampleCom) == 0) {
3609 usleep(1000); // 1ms
3610 }
3611
3612 std::thread t2([&listen_addr2, &hints, &dns2, this]() {
3613 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr2}));
3614 // step 5: query (should be blocked in resolver)
3615 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3616 // step 7: check result
3617 EXPECT_TRUE(result != nullptr);
3618 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3619 EXPECT_EQ(1U, GetNumQueriesForType(dns2, ns_type::ns_t_a, kHelloExampleCom));
3620 });
3621
3622 // step 4: wait a bit for the 2nd query to enter pending state
3623 usleep(100 * 1000); // 100ms
3624 // step 6: flush cache (will unblock pending queries)
3625 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
3626 t2.join();
3627
3628 // step 8: resume server#1
3629 dns1.setDeferredResp(false);
3630 t1.join();
3631
3632 // step 10: verify if result is correctly cached
3633 dns2.clearQueries();
3634 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3635 EXPECT_EQ(0U, GetNumQueries(dns2, kHelloExampleCom));
3636 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3637}
3638
Hungming Chenbb90ab32019-10-28 18:20:31 +08003639// Parameterized tests.
3640// TODO: Merge the existing tests as parameterized test if possible.
3641// TODO: Perhaps move parameterized tests to an independent file.
3642enum class CallType { GETADDRINFO, GETHOSTBYNAME };
3643class ResolverParameterizedTest : public ResolverTest,
Hungming Chen63779052019-10-30 15:06:13 +08003644 public testing::WithParamInterface<CallType> {
3645 protected:
3646 void VerifyQueryHelloExampleComV4(const test::DNSResponder& dns, const CallType calltype) {
3647 if (calltype == CallType::GETADDRINFO) {
3648 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
3649 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3650 ASSERT_TRUE(result != nullptr);
3651 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3652 } else if (calltype == CallType::GETHOSTBYNAME) {
3653 const hostent* result = gethostbyname("hello");
3654 ASSERT_TRUE(result != nullptr);
3655 ASSERT_EQ(4, result->h_length);
3656 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
3657 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3658 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
3659 } else {
3660 FAIL() << "Unsupported call type: " << static_cast<uint32_t>(calltype);
3661 }
3662 EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
3663 }
3664};
Hungming Chenbb90ab32019-10-28 18:20:31 +08003665
Hungming Chen63779052019-10-30 15:06:13 +08003666INSTANTIATE_TEST_SUITE_P(QueryCallTest, ResolverParameterizedTest,
Hungming Chenbb90ab32019-10-28 18:20:31 +08003667 testing::Values(CallType::GETADDRINFO, CallType::GETHOSTBYNAME),
3668 [](const testing::TestParamInfo<CallType>& info) {
Hungming Chenbb90ab32019-10-28 18:20:31 +08003669 switch (info.param) {
3670 case CallType::GETADDRINFO:
Hungming Chen63779052019-10-30 15:06:13 +08003671 return "GetAddrInfo";
Hungming Chenbb90ab32019-10-28 18:20:31 +08003672 case CallType::GETHOSTBYNAME:
Hungming Chen63779052019-10-30 15:06:13 +08003673 return "GetHostByName";
Hungming Chenbb90ab32019-10-28 18:20:31 +08003674 default:
Hungming Chen63779052019-10-30 15:06:13 +08003675 return "InvalidParameter"; // Should not happen.
Hungming Chenbb90ab32019-10-28 18:20:31 +08003676 }
Hungming Chenbb90ab32019-10-28 18:20:31 +08003677 });
3678
3679TEST_P(ResolverParameterizedTest, AuthoritySectionAndAdditionalSection) {
3680 // DNS response may have more information in authority section and additional section.
3681 // Currently, getanswer() of packages/modules/DnsResolver/getaddrinfo.cpp doesn't parse the
3682 // content of authority section and additional section. Test these sections if they crash
3683 // the resolver, just in case. See also RFC 1035 section 4.1.
3684 const auto& calltype = GetParam();
3685 test::DNSHeader header(kDefaultDnsHeader);
3686
3687 // Create a DNS response which has a authoritative nameserver record in authority
3688 // section and its relevant address record in additional section.
3689 //
3690 // Question
3691 // hello.example.com. IN A
3692 // Answer
3693 // hello.example.com. IN A 1.2.3.4
3694 // Authority:
3695 // hello.example.com. IN NS ns1.example.com.
3696 // Additional:
3697 // ns1.example.com. IN A 5.6.7.8
3698 //
3699 // A response may have only question, answer, and authority section. Current testing response
3700 // should be able to cover this condition.
3701
3702 // Question section.
3703 test::DNSQuestion question{
3704 .qname = {.name = kHelloExampleCom},
3705 .qtype = ns_type::ns_t_a,
3706 .qclass = ns_c_in,
3707 };
3708 header.questions.push_back(std::move(question));
3709
3710 // Answer section.
3711 test::DNSRecord recordAnswer{
3712 .name = {.name = kHelloExampleCom},
3713 .rtype = ns_type::ns_t_a,
3714 .rclass = ns_c_in,
3715 .ttl = 0, // no cache
3716 };
Hungming Chen63779052019-10-30 15:06:13 +08003717 EXPECT_TRUE(test::DNSResponder::fillRdata(kHelloExampleComAddrV4, recordAnswer));
Hungming Chenbb90ab32019-10-28 18:20:31 +08003718 header.answers.push_back(std::move(recordAnswer));
3719
3720 // Authority section.
3721 test::DNSRecord recordAuthority{
3722 .name = {.name = kHelloExampleCom},
3723 .rtype = ns_type::ns_t_ns,
3724 .rclass = ns_c_in,
3725 .ttl = 0, // no cache
3726 };
3727 EXPECT_TRUE(test::DNSResponder::fillRdata("ns1.example.com.", recordAuthority));
3728 header.authorities.push_back(std::move(recordAuthority));
3729
3730 // Additional section.
3731 test::DNSRecord recordAdditional{
3732 .name = {.name = "ns1.example.com."},
3733 .rtype = ns_type::ns_t_a,
3734 .rclass = ns_c_in,
3735 .ttl = 0, // no cache
3736 };
3737 EXPECT_TRUE(test::DNSResponder::fillRdata("5.6.7.8", recordAdditional));
3738 header.additionals.push_back(std::move(recordAdditional));
3739
3740 // Start DNS server.
3741 test::DNSResponder dns(test::DNSResponder::MappingType::DNS_HEADER);
3742 dns.addMappingDnsHeader(kHelloExampleCom, ns_type::ns_t_a, header);
3743 ASSERT_TRUE(dns.startServer());
3744 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3745 dns.clearQueries();
3746
3747 // Expect that get the address and the resolver doesn't crash.
Hungming Chen63779052019-10-30 15:06:13 +08003748 VerifyQueryHelloExampleComV4(dns, calltype);
3749}
3750
3751TEST_P(ResolverParameterizedTest, MessageCompression) {
3752 const auto& calltype = GetParam();
3753
3754 // The response with compressed domain name by a pointer. See RFC 1035 section 4.1.4.
3755 //
3756 // Ignoring the other fields of the message, the domain name of question section and answer
3757 // section are presented as:
3758 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3759 // 12 | 5 | h |
3760 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3761 // 14 | e | l |
3762 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3763 // 16 | l | o |
3764 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3765 // 18 | 7 | e |
3766 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3767 // 20 | x | a |
3768 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3769 // 22 | m | p |
3770 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3771 // 24 | l | e |
3772 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3773 // 26 | 3 | c |
3774 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3775 // 28 | o | m |
3776 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3777 // 30 | 0 | ... |
3778 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3779 //
3780 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3781 // 35 | 1 1| 12 |
3782 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3783 const std::vector<uint8_t> kResponseAPointer = {
3784 /* Header */
3785 0x00, 0x00, /* Transaction ID: 0x0000 */
3786 0x81, 0x80, /* Flags: qr rd ra */
3787 0x00, 0x01, /* Questions: 1 */
3788 0x00, 0x01, /* Answer RRs: 1 */
3789 0x00, 0x00, /* Authority RRs: 0 */
3790 0x00, 0x00, /* Additional RRs: 0 */
3791 /* Queries */
3792 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
3793 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
3794 0x00, 0x01, /* Type: A */
3795 0x00, 0x01, /* Class: IN */
3796 /* Answers */
3797 0xc0, 0x0c, /* Name: hello.example.com (a pointer) */
3798 0x00, 0x01, /* Type: A */
3799 0x00, 0x01, /* Class: IN */
3800 0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */
3801 0x00, 0x04, /* Data length: 4 */
3802 0x01, 0x02, 0x03, 0x04 /* Address: 1.2.3.4 */
3803 };
3804
3805 // The response with compressed domain name by a sequence of labels ending with a pointer. See
3806 // RFC 1035 section 4.1.4.
3807 //
3808 // Ignoring the other fields of the message, the domain name of question section and answer
3809 // section are presented as:
3810 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3811 // 12 | 5 | h |
3812 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3813 // 14 | e | l |
3814 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3815 // 16 | l | o |
3816 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3817 // 18 | 7 | e |
3818 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3819 // 20 | x | a |
3820 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3821 // 22 | m | p |
3822 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3823 // 24 | l | e |
3824 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3825 // 26 | 3 | c |
3826 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3827 // 28 | o | m |
3828 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3829 // 30 | 0 | ... |
3830 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3831 //
3832 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3833 // 35 | 5 | h |
3834 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3835 // 37 | e | l |
3836 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3837 // 39 | l | o |
3838 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3839 // 41 | 1 1| 18 |
3840 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3841 const std::vector<uint8_t> kResponseLabelEndingWithAPointer = {
3842 /* Header */
3843 0x00, 0x00, /* Transaction ID: 0x0000 */
3844 0x81, 0x80, /* Flags: qr rd ra */
3845 0x00, 0x01, /* Questions: 1 */
3846 0x00, 0x01, /* Answer RRs: 1 */
3847 0x00, 0x00, /* Authority RRs: 0 */
3848 0x00, 0x00, /* Additional RRs: 0 */
3849 /* Queries */
3850 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
3851 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
3852 0x00, 0x01, /* Type: A */
3853 0x00, 0x01, /* Class: IN */
3854 /* Answers */
3855 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0xc0,
3856 0x12, /* Name: hello.example.com (a label ending with a pointer) */
3857 0x00, 0x01, /* Type: A */
3858 0x00, 0x01, /* Class: IN */
3859 0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */
3860 0x00, 0x04, /* Data length: 4 */
3861 0x01, 0x02, 0x03, 0x04 /* Address: 1.2.3.4 */
3862 };
3863
3864 for (const auto& response : {kResponseAPointer, kResponseLabelEndingWithAPointer}) {
3865 SCOPED_TRACE(StringPrintf("Hex dump: %s", toHex(makeSlice(response)).c_str()));
3866
3867 test::DNSResponder dns(test::DNSResponder::MappingType::BINARY_PACKET);
3868 dns.addMappingBinaryPacket(kHelloExampleComQueryV4, response);
3869 StartDns(dns, {});
3870 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3871
3872 // Expect no cache because the TTL of testing responses are 0.
3873 VerifyQueryHelloExampleComV4(dns, calltype);
Hungming Chenbb90ab32019-10-28 18:20:31 +08003874 }
Mike Yu40e67072019-10-09 21:14:09 +08003875}